Subversion Repositories DIN Is Noise

Rev

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

/*
* widget.h
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/



#ifndef __widget
#define __widget

#include "box.h"
#include "color.h"
#include "point.h"
#include "viewwin.h"

#include <vector>
#include <list>
#include <map>
#include <string>
#include <fstream>

#define LISTEN(w,v) w.set_listener(v);
#define MOVE(w) w.set_moveable(1);
#define HANDLEINPUT(h) if (h.handle_input()) return 1;

#define MILLION 1000000
#define MILLIONF float(MILLION)

extern int lmb;
extern int mousex, mouseyy;

struct ui;
struct widget;

struct voiddata {
  void* data;
  voiddata () : data (0) {}
};

struct move_listener : voiddata {
  virtual void moved () = 0;
  virtual void movestart () {}
  virtual void endmove () {}
};

struct nullt {
  int null;
  nullt () : null(0) {}
};

#define MAKE_MOVE_LISTENER(name,var) struct name : move_listener { void movestart (); void moved (); void endmove (); } ; name var;
#define MOVED(scope,name) void scope::name::moved ()
#define MOVESTART(scope,name) void scope::name::movestart ()
#define MOVEEND(scope,name) void scope::name::endmove ()

struct mover {
  widget* w; // widget moved
  int* pmb; // mouse button that moves widget
  int mb_clicked; // is that mouse button clicked
  int move; // 1 - widget is moving, 0 - not
  int prevx, prevy; // previous mouse position
  mover (widget* ww, int* pb = &lmb);
  int handle_input ();
};

typedef std::vector<widget *>::size_type size_vw;

struct widget { // ui widget

  int id;

  std::string name;
  void set_name (const std::string& _name);
  void nametothis ();
  virtual void set_text (const std::string& txt) {set_name (txt);}

  // bounding box
  //
  box<int> extents; // extents of bounding box around this widget
  void set_extents (int l, int b, int r, int t);
  void set_extents (const box<int>& ext) { extents = ext;}
  int size; // for making square widgets
  void set_size (int _sz) {
    size = _sz;
    set_extents (posx, posy, posx + size, posy + size);
  }
  void set_width_height (int w, int h) {
    set_extents (posx, posy, posx + w, posy + h);
  }

  static int bb[]; // bounding box data for OpenGL drawing
  void draw_bbox ();
  void fill_bbox (float a = 0.1f, int g = 1);
  void draw_and_fill_bbox ();

  // color of all widgets (except checkbuttons)
  static float R, G, B;
  color clr;
  virtual void set_color (unsigned char ur, unsigned char ug, unsigned char ub);
  virtual void set_color (float r, float g, float b);
  void set_color (const color& c) {set_color (c.r, c.g, c.b);}

  int posx, posy; // position in screen space
  virtual void set_pos (int x, int y);

  // helper to handle move with mouse
  int moveable; // moveable?
  mover movr; // handles move
  move_listener* movlis;
  virtual void set_moveable (int m, int mc = 0, int* pmb = &lmb);
  void move (int dx, int dy, int mc = 1);
  void setpos2 (widget& w);

  int visible; // visible?

  int enabled; // enabled?
  void enable ();
  void disable ();

  static int HOVER; // hover over any widget in DIN?

  int hover; // hovering?

  // children
  //
  std::vector<widget*> children;
  int numchil;
  void add_child (widget *w);
  void remove_child (widget* w);
  void swapchild (widget* w1, widget* w2);

#ifdef __WIDGET_MOVE__
  int dg;
  void draw_guides ();
#endif

  static widget *focus, *next_focus;

  enum {all, only_children};
  virtual void show ();
  void hide (int what = all);

  widget (int l = 0, int b = 0, int r = 0, int t = 0);
  virtual ~widget ();

  virtual int handle_input ();
  virtual void draw ();

  virtual void update () {}

  static void advance_right (int& x, widget& w, int spc = 10) {
    const box<int>& e = w.extents;
    x += (e.width + spc);
  }

  virtual void load (std::ifstream& file);
  virtual void save (std::ofstream& file);

};

// globals
//

void widget_load (const std::string& name, widget** pw, int n);
void widget_load (const std::string& fname, std::vector<widget*>& vec);
void widget_save (const std::string& name, widget** pw, int n);
void widget_save (const std::string& fname, std::vector<widget*>& vec);

// listeners for widgets
template <typename W> struct change_listener {
  virtual void changed (W& w) = 0;
};

// for tying lmb to a widget
struct is_lmb_t {
  widget* tie;
  is_lmb_t ();
  int operator() (widget* w = 0);
  void clear (widget* _tie = 0);
};

extern is_lmb_t is_lmb;

void set_focus (widget* w);
void defocus ();
void defocus (widget* w);

void makehier (widget** wa);
void makehier (widget** wa, int n);
void makefam (widget** wa);
void makefam (widget* parent, widget** children, int n);
void makefam (widget** mem, int n);

#endif