Subversion Repositories DIN Is Noise

Rev

Rev 2302 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* options_list.h
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/


#ifndef __options_list
#define __options_list

#include "arrow_button.h"
#include "font.h"
#include <string>

struct option_listener : voiddata {
  virtual void picked (label& lbl, int dir) = 0;
};

#define MAKE_OPTION_LISTENER(name,var)\
struct name : option_listener {\
  void picked (label& l, int dir);\
};\
name var;\


#define PICKED_OPTION(scope,name) void scope::name::picked (label& l, int dir)

struct options_list : widget, click_listener {

  arrow_button left;
  arrow_button right;
  button option;
  button apply;

  option_listener* olis;

  options_list (int show_apply = 0) {

#ifdef __WIDGET_MOVE__
    widget* w[] = {&option, this, &left, &right, &apply, 0};
    makefam (w);
#endif

    left.set_dir (arrow_button::left);
    right.set_dir (arrow_button::right);
    left.set_listener (this);
    right.set_listener (this);

    apply.set_text ("Apply");
    if (show_apply) apply.show (); else apply.hide ();

    olis = 0;
  }

  void set_text (const std::string& t) {
    option.set_text (t);
    set_name (t);
    set_pos (posx, posy);
  }

  static const int spacing = 4;

  void set_pos (int x, int y) {

    widget::set_pos (x, y);

    left.set_pos (x, y + fnt.lift);
    advance_right (x, left, spacing);

    right.set_pos (x, y + fnt.lift);
    advance_right (x, right, spacing + 1);

    option.set_pos (x, y);

    widget* rw = 0;
    if (apply.visible) {
      rw = &apply;
      set_apply_pos ();
    } else rw = &option;

    set_extents (left.extents.left, option.extents.bottom, rw->extents.right, rw->extents.top);

  }

  void set_apply_pos () {
    int x = option.extents.left;
    advance_right (x, option, 6 * spacing);
    apply.set_pos (x, option.extents.bottom);
  }

  int handle_input () {
    int r = option.handle_input();
    if (left.handle_input());
    else if (right.handle_input()) ;
    else if (apply.visible && apply.handle_input()) ;
    return r;
  }

  void draw () {
    widget::draw ();
    option.draw ();
    left.draw ();
    right.draw ();
    if (apply.visible) apply.draw ();
  }

  void clicked (button& b) {
    if (olis) {
      if (&b == &left)
        olis->picked (option, -1);
      else
        olis->picked (option, 1);
    }
  }

  void set_click_repeat (int click_repeat) {
    left.click_repeat = click_repeat;
    right.click_repeat = click_repeat;
  }

  void set_moveable (int m, int mc, int* pmb) {
    option.set_moveable (m, mc, pmb);
    widget::set_moveable (m, mc, pmb);
  }

  void set_listener (option_listener* _olis) {
    olis = _olis;
  }

};

#endif