FLTK sandbox

Check-in [5b4d03fe0b]
Login

Check-in [5b4d03fe0b]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:started adding of styles to fltk
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | styles
Files: files | file ages | folders
SHA1: 5b4d03fe0b323f914569a41d40ffc3128c0fe54d
User & Date: Nikita 2016-01-30 20:44:33.416
Context
2016-01-31
21:34
added new method Style::replace() to change default value for given property name added an initialization of some classes via the replace() fixed calls to realloc() every time on change class_name_ changed type of property name to const char* (it keeps only pointer to outer string) Leaf check-in: 94d917ba9c user: Nikita tags: styles
2016-01-30
20:44
started adding of styles to fltk check-in: 5b4d03fe0b user: Nikita tags: styles
2016-01-29
13:09
[CMake] Work around CMake bug in CMake versions 3.4.x. CMake versions 3.4.x crash when using fltk_wrap_ui, a built-in CMake command. According to the CMake devs this will be fixed in CMake 3.5. However, since fltk_wrap_ui is no longer necessary (it can replaced by custom build commands) and some Linux distributions deploy CMake 3.4.x we decided to use an own replacement function. This makes sure that FLTK can be built with CMake 3.4.x, but FLTK users may still have to rewrite their own CMake files to not use fltk_wrap_ui. git-svn-id: http://seriss.com/public/fltk/fltk/branches/branch-1.3@11081 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 Leaf check-in: 0957b8a5d6 user: AlbrechtS@ea41ed52-d2ee-0310-a9c1-e6b18d33e121 tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to FL/Fl_Button.H.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
*/

class FL_EXPORT Fl_Button : public Fl_Widget {

  int shortcut_;
  char value_;
  char oldval;
  uchar down_box_;

protected:

  static Fl_Widget_Tracker *key_release_tracker;
  static void key_release_timeout(void*);
  void simulate_key_action();








|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
*/

class FL_EXPORT Fl_Button : public Fl_Widget {

  int shortcut_;
  char value_;
  char oldval;
  int down_box_id_;

protected:

  static Fl_Widget_Tracker *key_release_tracker;
  static void key_release_timeout(void*);
  void simulate_key_action();

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
   */
  void shortcut(int s) {shortcut_ = s;}

  /**
    Returns the current down box type, which is drawn when value() is non-zero.
    \retval Fl_Boxtype
   */
  Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;}

  /**
    Sets the down box type. The default value of 0 causes FLTK to figure out
    the correct matching down version of box().

    Some derived classes (e.g. Fl_Round_Button and Fl_Light_Button use
    down_box() for special purposes. See docs of these classes.

    \param[in] b down box type
   */
  void down_box(Fl_Boxtype b) {down_box_ = b;}

  /// (for backwards compatibility)
  void shortcut(const char *s) {shortcut(fl_old_shortcut(s));}

  /// (for backwards compatibility)
  Fl_Color down_color() const {return selection_color();}








|










|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
   */
  void shortcut(int s) {shortcut_ = s;}

  /**
    Returns the current down box type, which is drawn when value() is non-zero.
    \retval Fl_Boxtype
   */
  Fl_Boxtype down_box() const {return (Fl_Boxtype)style()->get(down_box_id_);}

  /**
    Sets the down box type. The default value of 0 causes FLTK to figure out
    the correct matching down version of box().

    Some derived classes (e.g. Fl_Round_Button and Fl_Light_Button use
    down_box() for special purposes. See docs of these classes.

    \param[in] b down box type
   */
  void down_box(Fl_Boxtype b) {style()->set(down_box_id_,b);}

  /// (for backwards compatibility)
  void shortcut(const char *s) {shortcut(fl_old_shortcut(s));}

  /// (for backwards compatibility)
  Fl_Color down_color() const {return selection_color();}

Changes to FL/Fl_Light_Button.H.
32
33
34
35
36
37
38

39
40
41
42
43
44
45

  Buttons generate callbacks when they are clicked by the user.  You
  control exactly when and how by changing the values for type() and when().
  <P ALIGN=CENTER>\image html Fl_Light_Button.png</P> 
  \image latex Fl_Light_Button.png "Fl_Light_Button" width=4cm
*/
class FL_EXPORT Fl_Light_Button : public Fl_Button {

protected:
    virtual void draw();
public:
    virtual int handle(int);
    Fl_Light_Button(int x,int y,int w,int h,const char *l = 0);
};








>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

  Buttons generate callbacks when they are clicked by the user.  You
  control exactly when and how by changing the values for type() and when().
  <P ALIGN=CENTER>\image html Fl_Light_Button.png</P> 
  \image latex Fl_Light_Button.png "Fl_Light_Button" width=4cm
*/
class FL_EXPORT Fl_Light_Button : public Fl_Button {
    int pushed_box_id_;
protected:
    virtual void draw();
public:
    virtual int handle(int);
    Fl_Light_Button(int x,int y,int w,int h,const char *l = 0);
};

Changes to FL/Fl_Widget.H.
103
104
105
106
107
108
109
110
111
112
113
114
115
116





































117
118
119
120
121
122
123
124



125
126
127
128
129
130
131

  Fl_Group* parent_;
  Fl_Callback* callback_;
  void* user_data_;
  int x_,y_,w_,h_;
  Fl_Label label_;
  unsigned int flags_;
  Fl_Color color_;
  Fl_Color color2_;
  uchar type_;
  uchar damage_;
  uchar box_;
  uchar when_;






































  const char *tooltip_;

  /** unimplemented copy ctor */
  Fl_Widget(const Fl_Widget &);
  /** unimplemented assignment operator */
  Fl_Widget& operator=(const Fl_Widget &);

protected:




  /** Creates a widget at the given position and size.

      The Fl_Widget is a protected constructor, but all derived widgets have a 
      matching public constructor. It takes a value for x(), y(), w(), h(), and 
      an optional value for label().
    







|
|


|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

  Fl_Group* parent_;
  Fl_Callback* callback_;
  void* user_data_;
  int x_,y_,w_,h_;
  Fl_Label label_;
  unsigned int flags_;
  int color_id_; 
  int color2_id_;
  uchar type_;
  uchar damage_;
  int box_id_;
  uchar when_;
   
  struct Style {    
    Style() : properties_(0), count_(0), class_name_(0) {        
    }
    ~Style();
    /** creates a full class name eg "widget.button.check" and
        re-initializes properties of base class if already exists
        Note! call it only once in constructor of your class  */
    int register_class(const char* cn);

    /** adds new name and returns its index, 
        saves defval in order to use in case if such property is not exist.
        the returned index is used to access the property */
    int add(const char* name, int defval=0);

    /** value of property */
    int get(int prop_id) const;

    /** saves the local property value
        since the moment we will ignore the global table of styles*/
    void set(int prop_id, int value);

    /** redirects requests to the global table again */
    void reset(int prop_id);
            
    /**  an array to requested properties */
    struct properties {
        int value_; // unique property value for every object (not class!)
        char use_local_; // flag to use local value instead of the global table
        int table_id_; // ID of the property, used to access global table
        char* sname_; // string to keep the property name
    } *properties_;
    /* size of the array */
    int count_; 
    /* full class name including names of all base classes */
    char *class_name_;  
  } style_;
 
  const char *tooltip_;

  /** unimplemented copy ctor */
  Fl_Widget(const Fl_Widget &);
  /** unimplemented assignment operator */
  Fl_Widget& operator=(const Fl_Widget &);

protected:
   /** getters to access styles */
   const Style* style() const {return &style_;}
   Style* style() {return &style_;}

  /** Creates a widget at the given position and size.

      The Fl_Widget is a protected constructor, but all derived widgets have a 
      matching public constructor. It takes a value for x(), y(), w(), h(), and 
      an optional value for label().
    
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
   */
  void align(Fl_Align alignment) {label_.align_ = alignment;}

  /** Gets the box type of the widget.
      \return the current box type
      \see box(Fl_Boxtype), Fl_Boxtype
   */
  Fl_Boxtype box() const {return (Fl_Boxtype)box_;}
  
  /** Sets the box type for the widget. 
      This identifies a routine that draws the background of the widget.
      See Fl_Boxtype for the available types. The default depends on the 
      widget, but is usually FL_NO_BOX or FL_UP_BOX.
      \param[in] new_box the new box type
      \see box(), Fl_Boxtype
   */
  void box(Fl_Boxtype new_box) {box_ = new_box;}

  /** Gets the background color of the widget.
      \return current background color
      \see color(Fl_Color), color(Fl_Color, Fl_Color)
   */
  Fl_Color color() const {return color_;}

  /** Sets the background color of the widget. 
      The color is passed to the box routine. The color is either an index into 
      an internal table of RGB colors or an RGB color value generated using 
      fl_rgb_color().
      
      The default for most widgets is FL_BACKGROUND_COLOR. Use Fl::set_color()
      to redefine colors in the color map.
      \param[in] bg background color
      \see color(), color(Fl_Color, Fl_Color), selection_color(Fl_Color)
   */
  void color(Fl_Color bg) {color_ = bg;}

  /** Gets the selection color.
      \return the current selection color
      \see selection_color(Fl_Color), color(Fl_Color, Fl_Color)
   */
  Fl_Color selection_color() const {return color2_;}

  /** Sets the selection color.
      The selection color is defined for Forms compatibility and is usually 
      used to color the widget when it is selected, although some widgets 
      use this color for other purposes. You can set both colors at once 
      with color(Fl_Color bg, Fl_Color sel).
      \param[in] a the new selection color
      \see selection_color(), color(Fl_Color, Fl_Color)
   */
  void selection_color(Fl_Color a) {color2_ = a;}

  /** Sets the background and selection color of the widget. 

      The two color form sets both the background and selection colors. 
      \param[in] bg background color
      \param[in] sel selection color
      \see color(unsigned), selection_color(unsigned)
   */
  void color(Fl_Color bg, Fl_Color sel) {color_=bg; color2_=sel;}

  /** Gets the current label text.
      \return a pointer to the current label text
      \see label(const char *), copy_label(const char *)
   */
  const char* label() const {return label_.value;}








|








|





|











|





|









|








|







396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
   */
  void align(Fl_Align alignment) {label_.align_ = alignment;}

  /** Gets the box type of the widget.
      \return the current box type
      \see box(Fl_Boxtype), Fl_Boxtype
   */
  Fl_Boxtype box() const {return (Fl_Boxtype)style()->get(box_id_);}
  
  /** Sets the box type for the widget. 
      This identifies a routine that draws the background of the widget.
      See Fl_Boxtype for the available types. The default depends on the 
      widget, but is usually FL_NO_BOX or FL_UP_BOX.
      \param[in] new_box the new box type
      \see box(), Fl_Boxtype
   */
  void box(Fl_Boxtype new_box) {style()->set(box_id_,new_box);}

  /** Gets the background color of the widget.
      \return current background color
      \see color(Fl_Color), color(Fl_Color, Fl_Color)
   */
  Fl_Color color() const {return style()->get(color_id_);}

  /** Sets the background color of the widget. 
      The color is passed to the box routine. The color is either an index into 
      an internal table of RGB colors or an RGB color value generated using 
      fl_rgb_color().
      
      The default for most widgets is FL_BACKGROUND_COLOR. Use Fl::set_color()
      to redefine colors in the color map.
      \param[in] bg background color
      \see color(), color(Fl_Color, Fl_Color), selection_color(Fl_Color)
   */
  void color(Fl_Color bg) {style()->set(color_id_,bg);}

  /** Gets the selection color.
      \return the current selection color
      \see selection_color(Fl_Color), color(Fl_Color, Fl_Color)
   */
  Fl_Color selection_color() const {return style()->get(color2_id_);}

  /** Sets the selection color.
      The selection color is defined for Forms compatibility and is usually 
      used to color the widget when it is selected, although some widgets 
      use this color for other purposes. You can set both colors at once 
      with color(Fl_Color bg, Fl_Color sel).
      \param[in] a the new selection color
      \see selection_color(), color(Fl_Color, Fl_Color)
   */
  void selection_color(Fl_Color a) {style()->set(color2_id_, a);}

  /** Sets the background and selection color of the widget. 

      The two color form sets both the background and selection colors. 
      \param[in] bg background color
      \param[in] sel selection color
      \see color(unsigned), selection_color(unsigned)
   */
  void color(Fl_Color bg, Fl_Color sel) {style()->set(color_id_,bg); style()->set(color2_id_,sel);}

  /** Gets the current label text.
      \return a pointer to the current label text
      \see label(const char *), copy_label(const char *)
   */
  const char* label() const {return label_.value;}

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
  /** Returns non zero if MAC_USE_ACCENTS_MENU flag is set, 0 otherwise. 
   */
  int use_accents_menu() { return flags() & MAC_USE_ACCENTS_MENU; }
  
  /** For back compatibility only.
      \deprecated Use selection_color() instead.
  */
  Fl_Color color2() const {return (Fl_Color)color2_;}

  /** For back compatibility only.
      \deprecated Use selection_color(unsigned) instead.
  */
  void color2(unsigned a) {color2_ = a;}
};

/**
    Reserved type numbers (necessary for my cheapo RTTI) start here.
    Grep the header files for "RESERVED_TYPE" to find the next available
    number.
*/







|




|







1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
  /** Returns non zero if MAC_USE_ACCENTS_MENU flag is set, 0 otherwise. 
   */
  int use_accents_menu() { return flags() & MAC_USE_ACCENTS_MENU; }
  
  /** For back compatibility only.
      \deprecated Use selection_color() instead.
  */
  Fl_Color color2() const {return (Fl_Color)style()->get(color2_id_);}

  /** For back compatibility only.
      \deprecated Use selection_color(unsigned) instead.
  */
  void color2(unsigned a) {style()->set(color2_id_, a);}
};

/**
    Reserved type numbers (necessary for my cheapo RTTI) start here.
    Grep the header files for "RESERVED_TYPE" to find the next available
    number.
*/
Changes to src/Fl_Button.cxx.
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
  Derived classes may handle this differently.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *L)
: Fl_Widget(X,Y,W,H,L) {

  box(FL_UP_BOX);
  down_box(FL_NO_BOX);
  value_ = oldval = 0;
  shortcut_ = 0;
  set_flag(SHORTCUT_LABEL);
}

/**
  The constructor creates the button using the given position, size, and label.

  The Button type() is set to FL_RADIO_BUTTON.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Radio_Button::Fl_Radio_Button(int X,int Y,int W,int H,const char *L)
: Fl_Button(X, Y, W, H, L) {

  type(FL_RADIO_BUTTON);
}

/**
  The constructor creates the button using the given position, size, and label.

  The Button type() is set to FL_TOGGLE_BUTTON.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Toggle_Button::Fl_Toggle_Button(int X,int Y,int W,int H,const char *L)
: Fl_Button(X,Y,W,H,L)
{

  type(FL_TOGGLE_BUTTON);
}


//
// End of "$Id$".
//







>
|
|















>














>







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  Derived classes may handle this differently.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *L)
: Fl_Widget(X,Y,W,H,L) {
  style()->register_class("button");
  //box(FL_UP_BOX);
  down_box_id_ = style()->add("down-box", FL_NO_BOX);
  value_ = oldval = 0;
  shortcut_ = 0;
  set_flag(SHORTCUT_LABEL);
}

/**
  The constructor creates the button using the given position, size, and label.

  The Button type() is set to FL_RADIO_BUTTON.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Radio_Button::Fl_Radio_Button(int X,int Y,int W,int H,const char *L)
: Fl_Button(X, Y, W, H, L) {
  style()->register_class("radio");
  type(FL_RADIO_BUTTON);
}

/**
  The constructor creates the button using the given position, size, and label.

  The Button type() is set to FL_TOGGLE_BUTTON.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Toggle_Button::Fl_Toggle_Button(int X,int Y,int W,int H,const char *L)
: Fl_Button(X,Y,W,H,L)
{
  style()->register_class("toggle");
  type(FL_TOGGLE_BUTTON);
}


//
// End of "$Id$".
//
Changes to src/Fl_Check_Button.cxx.
46
47
48
49
50
51
52

53
54
55
56
  Default is FL_DOWN_BOX.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Check_Button::Fl_Check_Button(int X, int Y, int W, int H, const char *L)
: Fl_Light_Button(X, Y, W, H, L) {

  box(FL_NO_BOX);
  down_box(FL_DOWN_BOX);
  selection_color(FL_FOREGROUND_COLOR);
}







>
|
|
|

46
47
48
49
50
51
52
53
54
55
56
57
  Default is FL_DOWN_BOX.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
 */
Fl_Check_Button::Fl_Check_Button(int X, int Y, int W, int H, const char *L)
: Fl_Light_Button(X, Y, W, H, L) {
  style()->register_class("check");
  //box(FL_NO_BOX);
  //down_box(FL_DOWN_BOX);
  //selection_color(FL_FOREGROUND_COLOR);
}
Changes to src/Fl_Light_Button.cxx.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <FL/Fl.H>
#include <FL/Fl_Light_Button.H>
#include <FL/Fl_Radio_Light_Button.H>
#include <FL/fl_draw.H>
#include "flstring.h"

void Fl_Light_Button::draw() {
  if (box()) draw_box(this==Fl::pushed() ? fl_down(box()) : box(), color());
  Fl_Color col = value() ? (active_r() ? selection_color() :
                            fl_inactive(selection_color())) : color();

  int W  = labelsize();
  int bx = Fl::box_dx(box());	// box frame width
  int dx = bx + 2;		// relative position of check mark etc.
  int dy = (h() - W) / 2;	// neg. offset o.k. for vertical centering







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <FL/Fl.H>
#include <FL/Fl_Light_Button.H>
#include <FL/Fl_Radio_Light_Button.H>
#include <FL/fl_draw.H>
#include "flstring.h"

void Fl_Light_Button::draw() {
  if (box()) draw_box(this==Fl::pushed() ? (Fl_Boxtype)style()->get(pushed_box_id_) : box(), color());
  Fl_Color col = value() ? (active_r() ? selection_color() :
                            fl_inactive(selection_color())) : color();

  int W  = labelsize();
  int bx = Fl::box_dx(box());	// box frame width
  int dx = bx + 2;		// relative position of check mark etc.
  int dy = (h() - W) / 2;	// neg. offset o.k. for vertical centering
151
152
153
154
155
156
157


158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
/**
  Creates a new Fl_Light_Button widget using the given
  position, size, and label string.
  <P>The destructor deletes the check button.
*/
Fl_Light_Button::Fl_Light_Button(int X, int Y, int W, int H, const char* l)
: Fl_Button(X, Y, W, H, l) {


  type(FL_TOGGLE_BUTTON);
  selection_color(FL_YELLOW);
  align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
}


Fl_Radio_Light_Button::Fl_Radio_Light_Button(int X,int Y,int W,int H,const char *l)
: Fl_Light_Button(X,Y,W,H,l) 
{

  type(FL_RADIO_BUTTON);
}


//
// End of "$Id$".
//







>
>

|







>







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/**
  Creates a new Fl_Light_Button widget using the given
  position, size, and label string.
  <P>The destructor deletes the check button.
*/
Fl_Light_Button::Fl_Light_Button(int X, int Y, int W, int H, const char* l)
: Fl_Button(X, Y, W, H, l) {
  style()->register_class("light");
  pushed_box_id_ = style()->add("pushed-box", FL_DOWN_BOX);
  type(FL_TOGGLE_BUTTON);
  //selection_color(FL_YELLOW);
  align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
}


Fl_Radio_Light_Button::Fl_Radio_Light_Button(int X,int Y,int W,int H,const char *l)
: Fl_Light_Button(X,Y,W,H,l) 
{
  style()->register_class("radio");
  type(FL_RADIO_BUTTON);
}


//
// End of "$Id$".
//
Changes to src/Fl_Repeat_Button.cxx.
56
57
58
59
60
61
62

63
64
65
66
67
68
  }
}


Fl_Repeat_Button::Fl_Repeat_Button(int X,int Y,int W,int H,const char *l)
: Fl_Button(X,Y,W,H,l) 
{

}


//
// End of "$Id$".
//







>






56
57
58
59
60
61
62
63
64
65
66
67
68
69
  }
}


Fl_Repeat_Button::Fl_Repeat_Button(int X,int Y,int W,int H,const char *l)
: Fl_Button(X,Y,W,H,l) 
{
  style()->register_class("repeat");
}


//
// End of "$Id$".
//
Changes to src/Fl_Return_Button.cxx.
60
61
62
63
64
65
66

67
68
69
70
71
72
    return Fl_Button::handle(event);
}


Fl_Return_Button::Fl_Return_Button(int X, int Y, int W, int H,const char *l)
: Fl_Button(X,Y,W,H,l) 
{

}


//
// End of "$Id$".
//







>






60
61
62
63
64
65
66
67
68
69
70
71
72
73
    return Fl_Button::handle(event);
}


Fl_Return_Button::Fl_Return_Button(int X, int Y, int W, int H,const char *l)
: Fl_Button(X,Y,W,H,l) 
{
  style()->register_class("return");
}


//
// End of "$Id$".
//
Changes to src/Fl_Round_Button.cxx.
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
  which defaults to FL_FOREGROUND_COLOR (usually black).

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
*/
Fl_Round_Button::Fl_Round_Button(int X,int Y,int W,int H, const char *L)
: Fl_Light_Button(X,Y,W,H,L) {

  box(FL_NO_BOX);
  down_box(FL_ROUND_DOWN_BOX);
  selection_color(FL_FOREGROUND_COLOR);
}

/**
  Creates a new Fl_Radio_Button widget using the given position, size, and label string.

  The button type() is set to FL_RADIO_BUTTON.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
*/

Fl_Radio_Round_Button::Fl_Radio_Round_Button(int X,int Y,int W,int H,const char *L)
: Fl_Round_Button(X,Y,W,H,L)
{

  type(FL_RADIO_BUTTON);
}


//
// End of "$Id$".
//







>
|
|
|














>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  which defaults to FL_FOREGROUND_COLOR (usually black).

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
*/
Fl_Round_Button::Fl_Round_Button(int X,int Y,int W,int H, const char *L)
: Fl_Light_Button(X,Y,W,H,L) {
  style()->register_class("round");
  //box(FL_NO_BOX);
  //down_box(FL_ROUND_DOWN_BOX);
  //selection_color(FL_FOREGROUND_COLOR);
}

/**
  Creates a new Fl_Radio_Button widget using the given position, size, and label string.

  The button type() is set to FL_RADIO_BUTTON.

  \param[in] X, Y, W, H position and size of the widget
  \param[in] L widget label, default is no label
*/

Fl_Radio_Round_Button::Fl_Radio_Round_Button(int X,int Y,int W,int H,const char *L)
: Fl_Round_Button(X,Y,W,H,L)
{
  style()->register_class("radio");
  type(FL_RADIO_BUTTON);
}


//
// End of "$Id$".
//
Changes to src/Fl_Widget.cxx.
105
106
107
108
109
110
111

















































































































































































































































112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
    } // valid entry
    if (entry == old_head) break;
  }
  return;
}
////////////////////////////////////////////////////////////////


















































































































































































































































int Fl_Widget::handle(int) {
  return 0;
}

/** Default font size for widgets */
Fl_Fontsize FL_NORMAL_SIZE = 14;

Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {

  x_ = X; y_ = Y; w_ = W; h_ = H;

  label_.value	 = L;
  label_.image   = 0;
  label_.deimage = 0;
  label_.type	 = FL_NORMAL_LABEL;
  label_.font	 = FL_HELVETICA;
  label_.size	 = FL_NORMAL_SIZE;
  label_.color	 = FL_FOREGROUND_COLOR;
  label_.align_	 = FL_ALIGN_CENTER;
  tooltip_       = 0;
  callback_	 = default_callback;
  user_data_ 	 = 0;
  type_		 = 0;
  flags_	 = VISIBLE_FOCUS;
  damage_	 = 0;
  box_		 = FL_NO_BOX;
  color_	 = FL_GRAY;
  color2_	 = FL_GRAY;
  when_		 = FL_WHEN_RELEASE;

  parent_ = 0;
  if (Fl_Group::current()) Fl_Group::current()->add(this);
  if (!fl_graphics_driver) {
    // Make sure fl_graphics_driver is initialized. Important if we are called by a static initializer.
    Fl_Display_Device::display_device();







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
















|
|
|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
    } // valid entry
    if (entry == old_head) break;
  }
  return;
}
////////////////////////////////////////////////////////////////

/** styles stuff by Nikita Egorov */
typedef struct {
    struct prop_item {
        char* name_;
        int value_;
    } *prop_table_;

    /** returns value of the given property index or 0 if not exists */
    int value(int prop_id) {
        if (prop_id >= 0 && prop_id < count_)
            return prop_table_[prop_id].value_;
        return 0;
    }

    /** returns index for gived name of property or -1 if not exists */
    int prop_id(const char* prop_name) {
        for (int i = 0; i < count_; i++) {
            /** search our name */
            if (strcmp(prop_table_[i].name_, prop_name) == 0) return i;
        }
        return -1;
    }

    /** saves value for property */
    int value(const char* prop_name, int value) {
        /* is the name in list */
        int id = prop_id(prop_name);
        if (id < 0) {
            /* need create new item */ 
            id = count_++;
            /* increase sizes of lists */
            prop_table_ = (prop_item*)realloc(prop_table_, count_ * sizeof(prop_item));
            /* save copy of name */
            prop_table_[id].name_ = strdup(prop_name);            
        }
        /* update value */
        prop_table_[id].value_ = value;
        /* return current index */
        return id;
    }
    /** name of class */
    char* name_;    
    /** size of the lists */
    int count_;
} style_value_t;

static style_value_t **style_table = NULL;

static int table_size = 0;

/** returns value of property; 
    hi-word of the ID is index of class,
    lo-word of the ID is index of property */
static int style(int id) {
    if (!style_table || (id >> 16) >= table_size) return 0;    
    return style_table[id >> 16]->value(id & 0xFFFF);
}

/** searches all prefixes in table, which contain in given name of class;
    eg, name => "widget.button.light",
    then the function can write up to three indices in the ret array :
    [0] => indexof("widget"), [1] => indexof("widget.button") and [2] => indexof("widget.button.light")
    */
static int class_id(const char* class_name, int* ret) {    
    int max_len = -1;
    int cnt = 0;
    /** loop over items of styles table */
    for (int i = 0; i < table_size; i++) {
        const char* a = style_table[i]->name_;    
        const char* b = class_name;
        /* search either end of strings or first mismatch */
        while (*a && *b && *a==*b) {++a;++b;}
        /* if we found end of style name, then it can be prefix of class name */
        if (*a == 0) { 
            /* if it's end of class name then we have exactly what we found */
            if (*b == 0) {
                /** save current position and exit */
                ret[cnt++] = i;
                return cnt;
            }
            /* we make sure we are on border between words */
            if (*b == '.') {
                int len = b - class_name;
                /* if length of found string is greater than previous one, 
                   saves the current position and updates maximum length */
                if (len > max_len) {
                    ret[cnt++] = i;
                    max_len = len;                    
                }
            }
        }        
    }
    return cnt;
}

static const int MAX_DEEP = 32;

/** searches the nearest class name with given property name
    returns ID of found property or -1 if none */
static int table_id(const char* class_name, const char* prop_name) {
    if (!style_table)
        return -1;
    /* list of indices */
    int ids[MAX_DEEP];
    /* getting list of suitable records */
    int cnt = class_id(class_name, ids);
    /* testing every item in reverse order, because the last - the more suitable */
    for (int i = cnt-1; i >=0; i--) {
        int cid = ids[i];
        /* is the record containing our property ? */
        int pid = style_table[cid]->prop_id(prop_name);
        if (pid >= 0) {
            /** make ID and return it */
            return (cid << 16) | pid;
        }
    }
    /** none records found */
    return -1;
}

/** puts new value for given class and property names */
static int put_style(const char* class_name, const char* prop_name, int value) {
    /* list of indices to records */
    int ids[MAX_DEEP];
    /* find suitable records */
    int cnt = class_id(class_name, ids);
    int id;
    /** we need only equal names */ 
    if (cnt == 0 || strcmp(style_table[ids[cnt-1]]->name_, class_name) != 0) {
        /* creating new record */
        style_value_t* t = (style_value_t*)calloc(1, sizeof(style_value_t));
        t->name_ = strdup(class_name);
        /* resize table */
        id = table_size++;
        style_table = (style_value_t**)realloc(style_table, table_size * sizeof(style_value_t*));
        /* sort table by length of name */
        int len = strlen(class_name);
        --id;
        while (id >= 0 && len < strlen(style_table[id]->name_)) {
            style_table[id+1] = style_table[id];
            --id;
        }
        style_table[++id] = t;
    } else {
        id = ids[cnt-1];
    }
    /** update property value */
    style_table[id]->value(prop_name, value);    
    return id;
}

/** creates table of styles */
static int simple_styles_table() {
    struct {
        const char* name;
        int value;
    } table[] = {        
        {"widget.box", FL_NO_BOX},
        {"widget.color", FL_GRAY},
        {"widget.color2", FL_GRAY},

        {"widget.button.box", FL_UP_BOX},
        {"widget.button.down-box", FL_NO_BOX},

        {"widget.button.light.pushed-box", FL_GTK_DOWN_BOX},
        {"widget.button.light.color2", FL_YELLOW},        

        {"widget.button.light.check.box", FL_BORDER_BOX},        
        {"widget.button.light.check.down-box", FL_DOWN_BOX},
        {"widget.button.light.check.color2", FL_BLUE},

        {"widget.button.light.round.box", FL_NO_BOX},
        {"widget.button.light.round.down-box", FL_ROUND_DOWN_BOX},
        {"widget.button.light.round.color2", FL_GREEN},
    };
    int i;
    for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) {
        char* class_name = strdup(table[i].name);
        char* prop_name = strrchr(class_name, '.');
        prop_name[0] = '\0'; ++prop_name;
        put_style(class_name, prop_name, table[i].value);
        free(class_name);
    }
    return i;
}

int Fl_Widget::Style::add(const char* name, int defval) {
    int last = count_++;
    properties_ = (properties*)realloc(properties_, sizeof(properties_[0]) * count_);
    properties_[last].value_ = defval;
    properties_[last].table_id_ = table_id(class_name_, name);
    properties_[last].use_local_ = (properties_[last].table_id_ < 0) ? 1 : 0;
    properties_[last].sname_ = strdup(name);
    return last;
}    

int Fl_Widget::Style::register_class(const char* name) {
    /** create styles before first using */
    static int temp = simple_styles_table(); 

    if (class_name_) {
        /** if full class name already is exist, we append the current name to it */
        class_name_ = (char*)realloc(class_name_, strlen(class_name_) + 1 + strlen(name) + 1);
        strcat(class_name_, ".");
        strcat(class_name_, name);
        /* in this case we need update properties, because name of the class is changed ! */
        for (int i = 0; i < count_; i++) {
            properties_[i].table_id_ = table_id(class_name_, properties_[i].sname_);
        }
    } else /** otherwise make a copy */
        class_name_ = strdup(name);

    return 0;
}

Fl_Widget::Style::~Style() {
    for (int i=0;i<count_;i++) {
        free(properties_[i].sname_);
    }
    free(properties_);
    free(class_name_);
}

int Fl_Widget::Style::get(int prop_id) const {
    properties* v = properties_ + prop_id;
    return v->use_local_ ? v->value_ : ::style(v->table_id_);
}

void Fl_Widget::Style::set(int prop_id, int value) {
    properties* v = properties_ + prop_id;
    v->value_=value;
    v->use_local_=1;
}

void Fl_Widget::Style::reset(int prop_id) {
    properties* v = properties_ + prop_id;
    v->use_local_=0; 
}

////////////////////////////////////////////////////////////////////////

int Fl_Widget::handle(int) {
  return 0;
}

/** Default font size for widgets */
Fl_Fontsize FL_NORMAL_SIZE = 14;

Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {
  style()->register_class("widget");
  x_ = X; y_ = Y; w_ = W; h_ = H;

  label_.value	 = L;
  label_.image   = 0;
  label_.deimage = 0;
  label_.type	 = FL_NORMAL_LABEL;
  label_.font	 = FL_HELVETICA;
  label_.size	 = FL_NORMAL_SIZE;
  label_.color	 = FL_FOREGROUND_COLOR;
  label_.align_	 = FL_ALIGN_CENTER;
  tooltip_       = 0;
  callback_	 = default_callback;
  user_data_ 	 = 0;
  type_		 = 0;
  flags_	 = VISIBLE_FOCUS;
  damage_	 = 0;
  box_id_	 = style()->add("box", FL_NO_BOX);
  color_id_	 = style()->add("color", FL_GRAY);
  color2_id_ = style()->add("color2", FL_GRAY);
  when_		 = FL_WHEN_RELEASE;

  parent_ = 0;
  if (Fl_Group::current()) Fl_Group::current()->add(this);
  if (!fl_graphics_driver) {
    // Make sure fl_graphics_driver is initialized. Important if we are called by a static initializer.
    Fl_Display_Device::display_device();
Changes to src/fl_boxtype.cxx.
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) {
  if (t && fl_box_table[t].f) fl_box_table[t].f(x,y,w,h,c);
}

//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.cxx
/** Draws the widget box according its box style */
void Fl_Widget::draw_box() const {
  if (box_) draw_box((Fl_Boxtype)box_, x_, y_, w_, h_, color_);
  draw_backdrop();
}
/** If FL_ALIGN_IMAGE_BACKDROP is set, the image or deimage will be drawn */
void Fl_Widget::draw_backdrop() const {
  if (align() & FL_ALIGN_IMAGE_BACKDROP) {
    const Fl_Image *img = image();
    // if there is no image, we will not draw the deimage either







|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) {
  if (t && fl_box_table[t].f) fl_box_table[t].f(x,y,w,h,c);
}

//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.cxx
/** Draws the widget box according its box style */
void Fl_Widget::draw_box() const {
  if (box()) draw_box((Fl_Boxtype)box(), x_, y_, w_, h_, color());
  draw_backdrop();
}
/** If FL_ALIGN_IMAGE_BACKDROP is set, the image or deimage will be drawn */
void Fl_Widget::draw_backdrop() const {
  if (align() & FL_ALIGN_IMAGE_BACKDROP) {
    const Fl_Image *img = image();
    // if there is no image, we will not draw the deimage either