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