Re: [fltk.development] Article/video on Widget design : How to use type() ?
On 18.04.2013 15:09, Duncan Gibson wrote: In Fl_Slider.H there are definitions that are used for subclasses: pre // values for type(), lowest bit indicate horizontal: #define FL_VERT_SLIDER 0 #define FL_HOR_SLIDER 1 #define FL_VERT_FILL_SLIDER 2 #define FL_HOR_FILL_SLIDER 3 #define FL_VERT_NICE_SLIDER 4 #define FL_HOR_NICE_SLIDER 5 /pre although the class documentation doesn't mention the first two, it uses the values defined in Fl_Valuator.H instead: pre // shared type() values for classes that work in both directions: #define FL_VERTICAL 0 /// The valuator can work vertically #define FL_HORIZONTAL 1 /// The valuator can work horizontally /pre and indeed Fl_Slider makes use of Fl_Valuator::horizontal() which tests type() against FL_HORIZONTAL. So far this is all okay and somewhat plausible, since all Fl_*Slider widgets inherit FL_Valuator. It would probably be more consistent to define ... #define FL_VERT_SLIDER FL_VERTICAL // must be 0 #define FL_HOR_SLIDER FL_HORIZONTAL // must be 1 or something like that. At least this correlation should be mentioned in the docs... In Adding and Extending Widgets it says that type() is an arbitrary 8-bit identifier and you can use it for any purpose you want. ... except as noted elsewhere (see Greg's posting about FL_WINDOW and such). It seems to me that if I subclass some existing widgets, such as Fl_Slider, then I am not completely free to overwrite type() with my own arbitrary values. Yep, within one widget hierarchy (e.g. all widgets derived from Fl_Valuator) all widgets need to respect the type() values of all other widgets in the same hierarchy. That's *really* a bad thing IMO: in fact it means all other widgets in this (part of the) widget hierarchy *now and in the future*. So you are not free to derive your own widgets and assign different type() values if you don't know what values will be assigned in other sibling widgets, maybe later. And who can look into the future? Therefore, are there general guidelines on type(), or do they only apply on widget-by-widget basis? I don't think that there are any general guidelines. However, as things are, it would be consistent to use type() values from scratch in own widget hierarchies, if you need a type for discrimination of different widgets in your own hierarchy. However, if you derive from Fl_Valuator, then you're bound to its set of type() values. Seeing the problems as described, it could be useful not to derive from Fl_Valuator. However that's something I wouldn't want to decide based on the type() values used, but more on functionality. That said, what did the author of the FLU sliders (as mentioned by Ian in a later posting) do? Did he add other type values? What if someone uses FLU in his application, and we add conflicting type values for our new slider widgets in the same (Fl_Valuator-derived) widget hierarchy ??? One more note: it seems useful to (re)use FL_VERTICAL and FL_HORIZONTAL for your slider class(es). However, they are defined in Fl_Valuator.H, although they are not defined inside the class (name space). So we could maybe move them 'up' to Fl_Widget as a more general class, but then there might be other conflicts (with type values 0 and 1 in other classes that don't *mean* FL_VERTICAL and FL_HORIZONTAL, resp.). Otherwise, if you wouldn't derive from Fl_Valuator, FL_VERTICAL and FL_HORIZONTAL should not be used - I wouldn't like the idea to have to include Fl_Valuator.H if I don't use any of its (derived) classes. Difficult to say what's best ... Albrecht ___ fltk-dev mailing list fltk-dev@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-dev
Re: [fltk.development] Article/video on Widget design : How to use type() ?
On 18.04.2013 18:52, Greg Ercolano wrote: I usually try to avoid type(), because while looking at FLTK's own code, I've seen coding techniques that disagree with the above, namely: Fl.cxx:if (w-type()=FL_WINDOW) {dx -= w-x(); dy -= w-y();} Fl.cxx: if (p-type() = FL_WINDOW) break; // don't do the unmap Fl.cxx: if (type() FL_WINDOW) { Fl.cxx: while (wi-type() FL_WINDOW) { Fl_Group.cxx: if (o-type() FL_WINDOW) return o-handle(event); Fl_Group.cxx:if (type() FL_WINDOW) {p[0] = x(); p[2] = y();} else {p[0] = p[2] = 0;} Fl_Group.cxx:if (type() FL_WINDOW) { Fl_Group.cxx:if (type() = FL_WINDOW) dx = dy = 0; In this case, FL_WINDOW is defined as 0xf0, and the comment from FL/Fl_Window.H says: ../FL/Fl_Window.H:#define FL_WINDOW 0xF0/// window type id all subclasses have type() = this So it sounds like you can do whatever you want.. but only with the low order 4 bits if type(). That's not entirely correct, for some interpretation of correct. 0xF0 means decimal 240, so there's a bunch of 240 values (0-239) you can use, whereas only with the low order 4 bits seems to assume only 15 distinct values. However, it is correct that you can only use 4 bits if you want to base your type() distinction on something like a bit mask - then you can only use 4 bits. type() is actually one of those things I try not to mess with in favor of using my own type() in my derived classes because of the above. Do you mean type() literally, or does it stand for a differently named, but similar method? I would not recommend to overload type() in a way that it uses another member variable in a derived class. Although it is possible, it could lead to some confusion. And since the FLTK core makes use of type() for some decisions, it must be clear that FLTK always uses Fl_Widget::type(), whereas your class would always have to make sure that it uses YourClass::type(), i.e. you can't use a (Fl_Widget *) pointer and use type() with this (because it's not virtual, but this is so by design). And when you derive from a base class that has decided to make use of type() a certain way, you're kinda bound to the parameters of its use in your derived class. True. I usually try to make my own 'flags' variable in my class, and make methods that manipulate it, rather than overload type(). Ah, okay, I should have read this before I wrote my comments above. ;-) I guess you could override type() with your own, and manage a uchar type_ in your derived class so that the user can use type() on your class without affecting the base class. See above, I wouldn't do this. Therefore, are there general guidelines on type(), or do they only apply on widget-by-widget basis? I have a feeling the design is read the source luke; look at how the widget you derive from is implemented, (i.e. how it makes use of type()) and then design your work as an extension of that implementation. As much as object oriented programming tries to make a black box so that one shouldn't have to be concerned with implementation internals, when deriving classes you kinda have to. Yep, unless all is documented so well that you don't need to. You can't access the source code for libraries you don't get as sources, for instance. And who would try to read the sources of system libs, or X11, for instance. In fltk it's often important for instance how base classes implement handle(), as often your derived class has to take the base class's implementation of handle() into account to keep the code details in sync. I try to compare the code implementation with the docs to see what the general philosophy is, and then try to design along a line between the two. I try to get as intimate as possible with the implementation of the base class, so the derived widget becomes an extension not only in function but implementation as well. Theoretically you shouldn't even *try* to know how it is implemented, because one OOP principle is that implementation can change, as long as the interface is kept stable, but in practice ... (you said it). Albrecht ___ fltk-dev mailing list fltk-dev@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-dev
Re: [fltk.development] Article/video on Widget design : How to use type() ?
On 18.04.2013 23:44, Duncan Gibson wrote: I saw the other comment in the docs about type() that it was a hold over from the Forms implementation. Please ignore Forms compatibility. We're going to remove this, and AFAICT Matt has removed everything Forms related in FLTK 3.0. I was struggling to relate different uses of type() in different parts of the library to one consistent whole There is no consistent whole, it's always only used consistently in one (part of the) widget hierarchy, as written elsewhere. but it never occurred to me that I might not need to use type at all. I believe that you don't need such things like type() in a widget hierarchy if you design everything correctly (in the OOP sense), maybe with virtual methods and such. However, in (FLTK) practice we can see that the base class often has a draw() method that must know which derived classes may exist, and for which one of these it is called in /this/ instance of an object. This can lead to such problems as we can see in this thread. I suppose that if you are creating a new hierarchy of widgets then you are free to implement RTTI within those widgets in any way you want, as long as you respect the existing use of type(). True. So would current developer advice be to implement local RTTI ? I don't know. Or should we be looking at more modern template or prototype classes where implementation is passed in? [I'm not sure if I'm using the GoF Design Pattern nomenclature correcty here]. Do it as fits best, I guess. A moderate use of type() within a new class hierarchy may be okay, but adding classes to the Fl_Valuator hierarchy (with pseudo RTTI via type()) might result in problems. Maybe. Albrecht ___ fltk-dev mailing list fltk-dev@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-dev
Re: [fltk.general] Fl_tile: don't shrink, just shift
Hmm, now, I seem to recall that Jason Bryan's FLU widget extensions = for fltk had something like that - they wo uld be worth a look. OK; his pages at OSC.edu appear to be down, but there's a mirror here = that still seems to work: This came up a year ago - check STR2795 Latest FLU is hosted on sourceforge http://sourceforge.net/projects/flufltk/ Thanks Martin; I did not know about that Sourceforge location. That could be handy. Though... does that actually work for anyone? I just tried, and there don't seem to be any files to download there? Probably I'm doing something stupid again... Jason gave permission to integrate them, Fabien Constantini reported that he had ported the full FLU2.14 widget set to 1.3 and volunteered to integrate (at least?) its Fl_Tree implementation in 1.3/3.0 Though we now have Greg's tree widget implemented anyway, so the need is less pressing now! Selex ES Ltd Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL A company registered in England Wales. Company no. 02426132 This email and any attachments are confidential to the intended recipient and may also be privileged. If you are not the intended recipient please delete it from your system and notify the sender. You should not copy it or use it for any purpose nor disclose or distribute its contents to any other person. ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] Fl_tile: don't shrink, just shift
Thank you all so much for your hints: now I understand the real purpose and design of Fl_tile! I think I'll opt for a derived Fl_Group as suggested by Ian and Greg. Mainly by Greg, I thought his description was pretty good. I might be tempted to make his resizer widget out of a group, so that it could contain the widget(s) that it was resizing, without have to search quite so much for them. Or... that might be a bad idea. Dunno... Let us know what happens! Selex ES Ltd Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL A company registered in England Wales. Company no. 02426132 This email and any attachments are confidential to the intended recipient and may also be privileged. If you are not the intended recipient please delete it from your system and notify the sender. You should not copy it or use it for any purpose nor disclose or distribute its contents to any other person. ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] Fl_tile: don't shrink, just shift
... Jason Bryan's FLU widget extensions ... OK; his pages at OSC.edu appear to be down, This came up a year ago - check STR2795 Latest FLU is hosted on sourceforge http://sourceforge.net/projects/flufltk/ ... does that actually work for anyone? I just tried, and there don't seem to be any files to download there? If you click on the blue Browse Code button then you can certainly peruse the individual files, don't know about svn checkout though, BUT if you click on the web site link you get redirected to some wierd site which doesn't appear to have anything to do with it. So unclear if a site has been hijacked or expired and re-acquired... D. ___ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk
Re: [fltk.general] Fl_tile: don't shrink, just shift
On 04/21/13 10:50, Greg Ercolano wrote: I made one of these once; in my case I didn't use a tile, just used a regular Fl_Group in which the widgets were positioned, and put a thin widget between each that acted as a 'resizer' which: 1) enlarged/shrunk the widget above it 2) enlarged/shrunk the parent group 3) moved all the children below it up/down +---Fl_tile---+ | +-+ | | | | | | | widget 0| | | | | | | +-+ | | | resizer | | | +-+ | | | | | | | widget 1| | | | | | | +-+ | | | resizer | | | +-+ | | | | | | | widget 2| | | | | | | +-+ | +-+ Here's an example implementation of the above based on an older work. This assumes the parent is an *Fl_Scroll*. This is so that widgets off-screen can be reached with a scroll bar. The ResizerButton class is what you would use in your app. The main() below it shows how to use it. The example code creates 10 Fl_Box widgets with a resizer below each. You can drag the resizers around to change the size of the widget above; the other widgets below will be moved around inside the scroller to accommodate. Scrollbars will appear for widgets that are off-screen. --- snip #include FL/Fl.H #include FL/Fl_Window.H #include FL/Fl_Scroll.H #include FL/Fl_Box.H #include FL/Fl_Button.H #include FL/fl_draw.h #include stdio.h // // Demonstrate a resizer class for widgets in an Fl_Scroll // erco 1.0 ??/??/04 - original test program // erco 1.1 04/21/13 - modernized // // CLASS FOR HANDLING A 'RESIZER' BETWEEN WIDGETS IN AN Fl_Scroll // // Shows a resize cursor when hovered over // Assumes: * Parent is an Fl_Scroll // * All children of Fl_Scroll are vertically arranged // * The widget above us has a bottom edge touching our top edge // ie. (w-y()+w-h() == this-y()) // //When this widget is dragged: // * The widget above us (with a common edge) will be /resized/ vertically // * All children below us will be /moved/ vertically // class ResizerButton : public Fl_Button { int orig_h; int last_y; int min_h; // min height for widget above us void HandleDrag(int diff) { Fl_Scroll *grp = (Fl_Scroll*)parent(); int top = y(); int bot = y()+h(); // First pass: find widget directly above us with common edge //Possibly clamp 'diff' if widget would get too small.. // for ( int t=0; tgrp-children(); t++ ) { Fl_Widget *w = grp-child(t); if ( (w-y()+w-h()) == top ) { // found widget directly above? if ( (w-h()+diff) min_h ) diff = w-h() - min_h; // clamp w-resize(w-x(), w-y(), w-w(), w-h()+diff); // change height break; // done with first pass } } // Second pass: find widgets below us, move based on clamped diff for ( int t=0; tgrp-children(); t++ ) { Fl_Widget *w = grp-child(t); if ( w-y() = bot )// found widget below us? w-resize(w-x(), w-y()+diff, w-w(), w-h()); // change position } // Change our position last resize(x(),y()+diff,w(),h()); grp-init_sizes(); grp-redraw(); } public: ResizerButton(int X,int Y,int W,int H) : Fl_Button(X,Y,W,H,///) { orig_h = H; last_y = 0; min_h = 10; align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); labelfont(FL_COURIER); labelsize(6); } void SetMinHeight(int val) { min_h = val; } int GetMinHeight() const { return min_h; } int handle(int e) { int ret = 0; int this_y = Fl::event_y_root(); switch (e) { case FL_FOCUS: ret = 1; break; case FL_ENTER: ret = 1; fl_cursor(FL_CURSOR_NS); break; case FL_LEAVE: ret = 1; fl_cursor(FL_CURSOR_DEFAULT); break; case FL_PUSH: ret = 1; last_y = this_y; break; case FL_DRAG: HandleDrag(this_y-last_y); last_y = this_y; ret = 1; break; default: break; } return(Fl_Button::handle(e) | ret); } void resize(int X,int Y,int W,int H) { Fl_Button::resize(X,Y,W,orig_h);