| [ Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]
STR #3533
Application: | FLTK Library |
Status: | 1 - Closed w/Resolution |
Priority: | 1 - Request for Enhancement, e.g. asking for a feature |
Scope: | 3 - Applies to all machines and operating systems |
Subsystem: | Core Library |
Summary: | Fl_Counter with fixed arrow widths - preliminary code sample |
Version: | 1.3-feature |
Created By: | nicholas-shea |
Assigned To: | AlbrechtS |
Fix Version: | 1.4.0 |
Fix Commit: | ecc47d0cc3e1784e17ac94829202f2bdbd38a682 |
Update Notification: | |
Trouble Report Files:
Trouble Report Comments:
|
#1 | nicholas-shea 02:12 Jan 29, 2020 |
| When changing the width of an Fl_Counter, the arrow sizes do not remain fixed. This modification draws the arrows with images rather than a font, and re-computes the sizes/positions when the width is changed. The code is prelimary and is posted here at the request of Albrecht Schlosser following a discussion in the Google group fltk.general
Nicholas Shea | |
|
#2 | AlbrechtS 13:20 Nov 15, 2020 |
| I started working on this. My first goal is to convert the given sources / modifications to a patch and/or GitHub Issue and PR for FLTK 1.4.
I'm not yet sure how this will develop: I'd like to include the proposed changes in our Fl_Counter to improve it.
I believe the arrow (*not*) resizing code is worth consideration for the existing Fl_Counter.
I don't know if the included arrow images (?) will make it into the final code. So far I only tried to convert the new sources to 1.4, it'll need further work to integrate, compile and test... | |
|
#3 | nicholas-shea 03:16 Nov 16, 2020 |
| Good to know this might be incorporated into 1.4. Perhaps the best way to do it would be to increase the widget subtype class from the existing two types "Normal" and "Simple", to four types, namely: "Normal", "Normal Fixed Arrows", "Simple", "Simple Fixed Arrows". Then the user could simply choose the widget sub type using the combo menu in fluid. The rest of the implementation would be hidden from the user. Let me know if you would like me to have a go at this. | |
|
#4 | AlbrechtS 03:39 Nov 16, 2020 |
| Thanks for your quick reply and your offer to help further, but I'm now working on it and I currently don't need help. I'll come back to your offer or ask further questions if needed.
WRT your suggestion using type(): I'm not keen on using the type() system more than necessary.
I'm thinking of implementing one or more of these features:
- new behavior (w/o arrow box resizing) should be default (very, very likely) - add an option to use the old arrow resizing behavior (maybe) - make the arrow box width's configurable by the user (less likely)
Basically I think the old behavior is broken and should be replaced unconditionally (thanks for your patch) but I'm not sure if that's feasible (someone may depend on the old behavior).
Regarding your arrow images: I believe I'm not going to uses the images because the arrow drawing code will probably be changed short-term or mid-term. IMHO the selected scheme (i.e. Fl::scheme()) should determine the arrow (and other) drawing functions. Every exception (like using images in the widget code) would be a problem in the transition to this future development.
I'll let you know about the progress... | |
|
#5 | AlbrechtS 10:34 Nov 16, 2020 |
| I'm still testing and trying some modifications but I can report progress as promised:
For now I refactored the sources of Fl_Counter, including functions as you suggested and some more. The gist of the current mods is that I introduced upper and lower size *limits* for the arrow boxes which prevent those large arrows as the old Fl_Counter could draw. I kept the fl_symbol arrow drawing for now but this is now contained in one function.
My intention is to further refactor Fl_Counter to enable users to derive their own classes easier to do such things like you did with "pretty arrow drawing" or other mods.
Note: I'm using Fl_Counter as a prototype and I intend to modify similar widgets (sliders, valuators) in similar ways, but that's ... future.
My work in progress has these two protected members that might help you or others to derive their own classes:
void compute_sizes(int *xx, int *ww); void draw_arrow(int i, Fl_Boxtype boxtype, int X, int W, Fl_Color col); // index i = 1..4
Just FYI for now, but this is all subject to be changed. I'm not yet posting source code because it's still in development.
I attach an image that compares the old Fl_Counter with my modified version in a test program after resizing (enlarging) the windows by a similar amount. See 'Fl_Counter_limit-v1.png'. | |
|
#6 | nicholas-shea 00:59 Nov 17, 2020 |
| That looks like an elegant solution. I’m glad you kept the compute_sizes function; I can foresee this eventually belonging in the base Fl_Widget class, so it can be overridden for all widget types. The only problem with your modification (and this is purely a cosmetic issue), is that the original FLTK fl_symbol drawing routines rarely produce symmetrical triangles, so they tend to suffer aliasing artefacts on at least one diagonal; if this issue was resolved, perhaps the requirement for custom drawing routines would not be so great. Albrecht, thank you very much for looking into this. Your work is highly appreciated. | |
|
#7 | AlbrechtS 11:16 Nov 18, 2020 |
| Hi Nicholas, thanks for your comments. I'm aware that the arrow (triangle) drawing code, particularly that with fl_draw_symbol() is - well, let's say - suboptimal. But I didn't want to touch it yet.
I've meanwhile been working on a standardization of the "arrow drawing" code because it's been so different in different widgets that this needed a standardization before we can "beautify" ;-) it. These changes are now complete (i.e. working in tests) but need some cleanup before I can and want to commit these. As I wrote before the current scheme (i.e. Fl::scheme()) should determine the arrow (and other) drawing functions, but for now I'm glad to have all arrow/triangle drawing functions standardized in one place. I'm going to commit these soon and until that's done my work on Fl_Counter needs to wait. I'll keep you updated.
FTR: the polygon drawing code used in most places will be the new drawing code used everywhere (rather than fl_draw_symbol in Fl_Counter). Overriding the code in a particular widget by subclassing will still be possible. | |
|
#8 | AlbrechtS 13:07 Nov 18, 2020 |
| FYI: I'm attaching another screenshot (file 3: arrows_gtk+_Fl_Scrollbar_scaled-2x_test.png) which is a test version of the new drawing code but not yet the new Fl_Counter code discussed here.
Details:
(1) The FLTK scaling factor is 2.0 (200%) which results in better drawing (the original 100% scaling is still not perfect)
(2) The arrow/triangle symbols with light green background and red borders demonstrate correct positioning and drawing of the arrows with the *new* drawing code. The background and borders are only used in test mode.
(3) The scheme is "gtk+" which renders the arrows a little different.
(4) Fl_Adjuster uses old drawing code with embedded arrow images (will likely not be changed unless we use SVG images in the future?)
(5) Fl_Spinner still uses old "polygon drawing" code (independent of the scheme). This is subject to be changed as well. | |
|
#9 | nicholas-shea 02:36 Nov 19, 2020 |
| This looks so much better. Thanks for giving a peek into your development process. What is apparent here, is that much sweat and toil goes into the datum of a good UI, and too often it is taken for granted. Which makes me ponder on the subtext of this thread. To any uninformed observer, coding arrows might seem trivial or pedantic. But mankind has always been fascinated by the relation between a mental symbol and the actual object, and history proves we strive to make these representations as beautiful and meaningful as possible. As far as computer interfaces go, I know Apple Computer, in its early days, employed a whole team of psychologists and anthropologists to work in its Human Interface Guidelines department; they were primarily concerned with developing an iconography/dialogue between symbol and purpose. Your work here obviously follows on it that tradition. Alfred North Whitehead said “we eke out our knowledge by ‘symbolic transference’ from causal perception to sense-presentation, and vice versa.” Just how much importance can you place upon an arrow? Obviously, never too much! I look forward to using FLTK 1.4 in my projects. Best wishes, Nicholas. | |
|
#10 | AlbrechtS 12:23 Nov 21, 2020 |
| Nicholas, thank you very much for your kind words. It's a pleasure to read that one's work is appreciated. WRT Alfred North Whitehead: interesting person...
My current work is not primarily about drawing arrows, although my intention is always to "do it right". This includes of course also drawing correct arrow symbols. The reason why it takes so long to complete this easy looking task goes much deeper into the FLTK library. It's basically (bad) coding technique that drew my attention: we're having all sorts of arrow drawing code in different widgets, some are using FLTK symbols, some are differentiating by the current FLTK scheme, and last but not least, it's all redundant code which is error prone. You can find lots of code like
if (Fl::is_scheme("<name>")) { ... }
in the FLTK library. This is a maintenance nightmare and it makes creation of new FLTK "schemes" incredibly and unnecessarily difficult, not only WRT arrow drawing code but much more. My vision is to move all this scheme-dependent code from the widget implementations to a base class Fl_Scheme and derived classes. I did already implement parts of this but got blocked/distracted by other work. My current work is, as you may notice, refactoring of "arrow drawing" functions by always calling fl_draw_arrow(...) with appropriate arguments. This function will eventually be integrated in the Fl_Scheme class hierarchy by calling virtual methods that do the scheme specific stuff. The first step is done and I'm currently working on fixing some issues, reimplementing more widget specific code, and also improving the final "arrow drawing" function(s). I'm not yet fully satisfied with the API and some scaling details but I'm making progress. My plan is to commit this new function and whatever is needed soon w/o the final Fl_Scheme class. Stay tuned...
For now I can post another screenshot (arrows-standard.png), as previously announced also with Fl_Spinner using the new drawing code. This time I used the default scheme ("none") w/o scaling (1.0 or 100%). As you can see when you zoom into the image all arrow borders are horizontal, vertical, or other multiples of 45° and draw nicely w/o unexpected artifacts (except the normal "steps"). The resolution is lower, as expected. | |
|
#11 | AlbrechtS 12:25 Nov 21, 2020 |
| PS: once the "arrow drawing code" is finalized I can continue with this STR and the refactoring of Fl_Counter. | |
|
#12 | nicholas-shea 03:14 Nov 22, 2020 |
| When you say “do it right”, I assume you mean following object orientated software construction guidelines, as given by Bertrand Meyer in his book “Object Orientated Software Construction”. Speaking from personal experience, I know it is never a simple task to implement such guidelines, even when starting a project from scratch – much less so when modifying a library that is decades old, as you are doing here. Whilst I am not familiar with all the internals of FLTK, I have a broad comprehension of the problems involved, and realise the task you have undertaken is neither superficial nor easy. What is remarkable, is that you have achieved so much in so little time – as your latest screenshot shows. Clearly you are in your element. Once again, thanks for the update. The new widgets look very clean and sophisticated. | |
|
#13 | AlbrechtS 11:12 Nov 22, 2022 |
| Fixed in Git repository.
Hi Nicholas,
sorry for the long delay. Finally I came back to this STR and finalized the arrow drawing code as written above. This was done in Git commit ecc47d0cc3e1784e17ac94829202f2bdbd38a682 (today).
I believe that your issue is fixed now, although I didn't use any arrow images as you suggested (IIRC). I apologize for not reading back all through this long STR. Can you please verify that the mentioned commit fixes the issue for you and we can close this STR?
Honestly, I'm not sure if everything we talked about has been implemented. Looking forward to your comments.
Thank you very much in advance. | |
|
#14 | AlbrechtS 11:54 Nov 22, 2022 |
| To clarify: the method to compute arrow (box) sizes is now
void arrow_widths(int &w1, int &w2);
See documentation of class Fl_Counter:
https://www.fltk.org/doc-1.4/classFl__Counter.html#ad6e7dcfe3e950cb2c149bdee3022669f | |
|
#15 | nicholas-shea 09:52 Jan 02, 2023 |
| That looks great Albrecht; specifying the arrow box width in the constructor is a good solution. Thanks for fixing this issue and Happy New Year. | |
|
#16 | AlbrechtS 10:39 Jan 02, 2023 |
| Hi Nicholas, thank you for confirmation and a happy new year to you as well.
Closing this STR now. | |
[ Return to Bugs & Features ]
|
| |