I have more-less complete highlighting for fltk-1.3

If you are impatient and trust my executable (and the wires in-between) 
you can try a MingW compiled scheme.exe at

    http://phy19.phy.tcd.ie/fltk/highlighting/

This is exclusively fluid-implemented demo which would go to /test 
subdirectory. The patch there is against a few days old 1.3 tree, I have 
to make an update.

Below is (very long, sorry) description of the changes. I would like to 
hear your comments and if you like the implementation, it can go to the 
trunk very soon because everything works as expected, does not seem to 
break anything (fingers crossed) and all applications in the test 
directory and fluid  cab be instantly highlighted if you pass 
highlighted scheme as a command line parameter (without any change ;-).



SCHEME SUPPORT CHANGES
----------------------
I went through the fltk source and removed all code like
    if(!strcmp(Fl::scheme(), "plastic"){
     ... draw some glyph ...
    }else{
    ... draw other glyph ...
    }
Instead I have placed these drawings (like various scroll arrow glyphs, 
grippers, return arrow, check and radio glyphs and a few more)
into the box table so that they can be much  easier schemeable and
can also be highlighted (see below). To save space these glyphs are NOT 
members of widget classes, instead drawing functions reference  directly 
the boxtype.
I have also little  bit shifted position of plastic and gtk boxtypes so 
that they are now modulo 16 aligned within the table. This allows easier 
detection and testing of box character using masking. So code like
   if(box()==FL_DOWN_BOX || box()== FL_PLASTIV_DOWN_BOX)...
(which was in a few places missing gtk boxtypes) could be replaced by 
more general (and faster) testing. Some free space between schemes can 
be used for later additions without breaking binary compatibility. I 
have also registered original boxtype functions under names like 
FL_CLASIC_DOWN_BOX, ... because they were shadowed when a scheme was 
applied.


Changes to scheme API:
----------------------------

   int Fl::register_scheme( const char * name, void (*f)(void),
                          int replace = 1);

Registers a new scheme function under some name. If such a name is 
already registered and replace is 0, nothing is done and returns 0.
Once function is registered, it can be processed ie by 
Fl_Window::show(argc,argv).


   int Fl::register_standard_schemes();

Registers core fltk schemes (with replace = 0). Note that plastic and 
gtk objects are not statically linked by default any more but only if 
you use this function or Fl_Window::show(argc, argv) with arguments (it 
calls this function for for backward compatibility) bun not when you use 
Fl::scheme(const char *). That means if you do not want to link to 
unwanted schemes, use Fl_Window::show() without arguments.


   int Fl::scheme(const char*)

Now it just executes a registered scheme function.

   int Fl::count_schemes();
   const char * scheme_name(int i);

For iteration among registered schemes.






HIGHLIGHTING SUPPORT
----------------------
Things which can be highlighted:
  1) boxes (box(), down_box()) by shape or color or both
  2) various glyphs (shape or color or both)
  3) labels (by color, type, font, size or combination of these)
  4) Images (ie for highlighting within a toolbar)

draw(0 and handle() methods of following widget classes (and the 
derivatives which use the same or calls draw() and handle()) were 
already modified and classes can be highlighted:

   Fl_Button
       Fl_Return_Button, ...
   Fl_Light_Button
      Fl_Check_Button
      Fl_Round_Button
   Fl_Menu_Bar(highlighting of horizontal items)
   Fl_Menu_Button
   Fl_Slider
   Fl_Scrollbar
   Fl_Chioce

Highlighting of some other widgets (like composite Fl_Spinner)
works fine for box/color highlighting of these small buttons but 
highlighting of glyphs is not yet implemented.



Implementation API:
-------------------

void Fl::set_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, uchar, uchar, uchar, 
uchar, Fl_Boxtype highlighted = Fl_Boxtype(0), Fl_Color_Function* cf=0);

New form of Fl::set_boxtype() has couple more (default) parameters:

- shape change for highlighted version
- color function which modifies the color passed to the boxtype function

The rationale is that to get consistent highlighting you want to change 
shape or color of particular boxtypes in a particular way or you do not 
want highlighting at all. Like boxtype can get bolder (or flat-box can 
change to up-box for icons within a toolbar) and color can be changed ie 
by fl_lighter() or fl_darker() function. Glyphs can just replace the 
color to FL_SELECTION_COLOR or so. So boxtype table was increased by a 
function pointer (highlighted version is just combined with the set bit).

enum Fl_Highlight{
     FL_HIGHLIGHT_BOX = 1,
     FL_HIGHLIGHT_DOWN_BOX = 2,
     FL_HIGHLIGHT_COLOR = 4,
     FL_HIGHLIGHT_SELECTION_COLOR = 8,
     FL_HIGHLIGHT_GLYPH = 0x10,
     FL_HIGHLIGHT_GLYPH_COLOR = 0x20,
     FL_HIGHLIGHT_LABELTYPE = 0x100,
     FL_HIGHLIGHT_LABELSIZE = 0x200,
     FL_HIGHLIGHT_LABELFONT = 0x400,
     FL_HIGHLIGHT_LABELCOLOR = 0x800,
     FL_HIGHLIGHT_IMAGE = 0x1000,
};

These new enumerations can be used to individually enable or disable 
particular highlighting of a widget using functions

   void Fl_Widget::enable_highlight(int h);
   void Fl_Widget::disable_highlight(int h);
   Fl_Highlight Fl_Widget::highlight();

One short int member (highlight_) was added to the widget.
These flags can be enabled by default by widget classes - except for 
FL_HIGHLIGHT_IMAGE (see below)

   int handle_highlight(int event, Fl_Boxtype box = Fl_Boxtype(0),
                                   Fl_Boxtype down_box = Fl_Boxtype(0),
                                   Fl_Boxtype glyph = Fl_Boxtype(0),
                                   int damage_box = FL_DAMAGE_ALL,
                                   int damage_down_box = FL_DAMAGE_ALL,
                                   int damage_glyph = FL_DAMAGE_ALL);

This is a protected helper function handling highlighting of most 
widgets. It performs:

- checks if event is FL_ENTER or FL_LEAVE
- checks if widget is active_r()
- checks box, down_box and glyph against particular flags enabled
   (zero boxtype is not checked)
- checks if used boxes have h. version or highlighting function set
   within the table
- sets or resets HIGHLIGHT flag to signalise the widgets state
- performs redraw (and/or redraw_label()) ONLY WHEN NEEDED
   (widget really changes its look)
- returns event if it is FL_ENTER or FL_LEAVE, otherwise returns 0

Default FL_DAMAGE_ALL can be replaced by other damage if only partial 
redraw is required. DAMAGE_HIGHLIGHT was added among damage enumerations 
for that purpose.

It can be used like:
int Fl_Return_Button::handle(int event){
   // if value is 1, down_box() is drawn
   if(handle_highlight(event,
                       value()? FL_NO_BOX: box(),
                       value()? (down_box()? down_box():fl_down()):
                                FL_NO_BOX,
                       FL_RETURN_GLYPH))
         return 1; // event is FL_ENTER or FL_LEAVE

   ... // handling other events
}

but some other (like Fl_Scroll_Bar, Fl_Menu_Mar) use more sophisticated 
handling.

There is also a modified function

   void Fl_Widget::draw_box(Fl_Boxtype, int,int,int,int,Fl_Color,
                   int highlight_mask = 0) const;

with additional default parameter for highlight mask. It again checks 
the highlighting availability and draws particular highlighted(or not) 
version, inchuding handling of color and boxtype change.

Highlighting Images
-------------------
This is actually very simple: widget when draws things, it sets
a global variable flag  Fl::draw_highlighted() and a multi-image can 
check this mask against FL_HIGHLIGHT_IMAGE flag (within its draw(..) 
method) and draw a highlighted version. The widget's FL_HIGHLIGHT_IMAGE 
flag is off by default to avoid unnecessary label redraws. It should be 
enabled only when the widget is  used with highlight-aware image.
I have also glorified Fl::draw_box_active() hack so that it is also 
set/reset during label drawing.  From now a multi-image can have (ie 
created internally on-demand) three versions: normal, highlighted and 
inactive - see simple Fl_Multi_Image class within scheme.fl for such a 
simple class which merely references an existing image and creates 
internal modified versions on-demand only. This would be also preferred 
use instead of clasic Fl_Widget::deimage(...) function as it can save 
memory if inactive version is never required.

Uff, thats all, folks.

R.












_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to