Adding a new variant of Fl_Box_Draw_F and Fl_Label_Draw_F for Go bindings

13 views
Skip to first unread message

Piotr Wieczorek

unread,
Apr 1, 2022, 2:37:03 PM4/1/22
to fltk.general
Hi,
At first I've submitted this question as a github issue, but I was informed that I should write here.
I've created (for my personal use) a Go binding to the FLTK library. And now another user wanted to add support for custom Box types.
This turned out be problematic.
If I were creating a custom box type in C++ I could just write a separate function for drawing each of them.
In Go a user of the binding cannot create a new C/C++ function only a Go function.
If one of the Fl_Box_Draw_F's arguments was the Fl_BoxType that the function is supposed to draw, it could pass this information to the Go side which could decide which Go function to call. 
But as it stands now I see no way to define more than one custom box type, because I have no information to pass to the "Go side" to inform it which draw function to call.
The same issue applies to Fl_Label_Draw_F as far as I can tell.

Do you think there a chance of creating a new variant of Fl_Box_Draw_F which would take BoxType as one of its arguments?
Or can you see any other way to implement this feature?

Thanks in advance!
Piotr Wieczorek

Matthias Melcher

unread,
Apr 1, 2022, 4:36:39 PM4/1/22
to fltk.general
Boxtype is an enum, so it is at least a 4 byte integer. Adding a box type adds a function pointer into an array. Drawing a box will call teh function in that array, using the boxtype itself as the index. I don't know if there is such a thing a function pointers in "Go", but your interface from C to Go can easily simulate this. You create number of functions that you associate with the boxtype and add the parameter there: `void BoxDrawFuncUser1(int x int y, int w, int h, Fl_Color c) { CallGo("BoxDraw", 1, x, y, w, h, c); }` and so on. Since C++ can't create functions on the fly, you have to provide a finite number of these interfaces.

Piotr Wieczorek

unread,
Apr 2, 2022, 5:31:27 AM4/2/22
to fltk.general
Thanks.
As far as I can tell, this would allow the user to create a limited number of box types.
Without changing the FLTK itself, there's no way to allow user create arbitrary number of custom box types.

Cheers,
Piotr

imm

unread,
Apr 3, 2022, 5:17:25 AM4/3/22
to General FLTK
On Sat, 2 Apr 2022, 10:31 Piotr Wieczorek wrote:
Thanks.
As far as I can tell, this would allow the user to create a limited number of box types.
Without changing the FLTK itself, there's no way to allow user create arbitrary number of custom box types.


Any computer has finite resources, so ultimately any scheme has a limited number of box types.

So the crux here is simply whether the available number is more than is needed by the user; unless the user is creating an awful lot of unique box types, it should be fine.

Cosmetically if you are using more than a few box types there's a real danger the UI will look like an incoherent mess, so in that regard a constraint may also be a benefit!

YMMV.
--
Ian
From my Fairphone FP3

Matthias Melcher

unread,
Apr 3, 2022, 7:58:28 PM4/3/22
to fltk.general
You can create lamba functions with captures which can then be converted into function pointers in modern C++ With those, you can have as many box types and label types as you like.:

Piotr Wieczorek

unread,
Apr 4, 2022, 3:30:53 AM4/4/22
to fltkg...@googlegroups.com
I don't understand, how it's supposed to work.
In C++ only captureless lambdas can be converted into function pointers.
The "hack" presented in the link works because you can control the places where the function is called from.
I my case it's being called whenever FLTK decides to draw a box, which is out of my control, afaict. 
I still can't see how I could implement bindings to fully generic box drawibg without some kind of user data pointer or such.

Best, 
Piotr

On Mon, 4 Apr 2022, 01:58 'Matthias Melcher' via fltk.general, <fltkg...@googlegroups.com> wrote:
You can create lamba functions with captures which can then be converted into function pointers in modern C++ With those, you can have as many box types and label types as you like.:

--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/dOrkdXu8LYg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to fltkgeneral...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/e395fdb9-8b32-41e7-999b-07fac052518en%40googlegroups.com.

Ian MacArthur

unread,
Apr 4, 2022, 4:08:51 AM4/4/22
to fltk.general
On Monday, 4 April 2022 at 08:30:53 UTC+1  Piotr  wrote:
I don't understand, how it's supposed to work.
In C++ only captureless lambdas can be converted into function pointers.
The "hack" presented in the link works because you can control the places where the function is called from.
I my case it's being called whenever FLTK decides to draw a box, which is out of my control, afaict. 
I still can't see how I could implement bindings to fully generic box drawibg without some kind of user data pointer or such.


In some ways, it seems like you are asking for a capability for the Go port that fltk doesn't readily provide for the native port, in that the emphasis has always been on "fast 'n light", such that theming and ready overloading or replacement of box types was never something fltk was too concerned with.

In some ways, if box styling is a critical feature of your objective, fltk is probably a poor basis to build on - there are other GUI toolkits that support that much more readily.
In fltk, if you want to create your own button style or such, it's often (usually?) easier just to derive your own widget and draw it yourself, rather then trying to persuade the fltk boxtype mechanism to do what you want on the fly. 
Um, OK, Greg has some worked examples http://www.seriss.com/people/erco/fltk/Fl_Matte_Button/ and http://www.seriss.com/people/erco/fltk/Fl_Gel_Tabs/ of deriving widgets for custom drawing... which I think you probably could persuade Go to do for you, using the parts that are already exposed?

Dunno - what do you think?

 

Albrecht Schlosser

unread,
Apr 4, 2022, 9:25:14 AM4/4/22
to fltkg...@googlegroups.com
On 4/4/22 10:08 Ian MacArthur wrote:
On Monday, 4 April 2022 at 08:30:53 UTC+1  Piotr  wrote:
The "hack" presented in the link works because you can control the places where the function is called from.
I my case it's being called whenever FLTK decides to draw a box, which is out of my control, afaict.

@Piotr: That's true, FLTK calls the box drawing code internally for all standard boxtypes, i.e. either the predefined types or those added by Fl::set_boxtype().


I still can't see how I could implement bindings to fully generic box drawibg without some kind of user data pointer or such.

Neither can I.


In some ways, it seems like you are asking for a capability for the Go port that fltk doesn't readily provide for the native port, in that the emphasis has always been on "fast 'n light", such that theming and ready overloading or replacement of box types was never something fltk was too concerned with.

There's another point that should be considered carefully for such a thing like Go bindings. When you use Fl::scheme("any-scheme") all the standard boxtypes are overwritten (in the array of boxtype definitions) by the boxtypes of the selected scheme. This includes the function pointers and all boxtype attributes. It may not matter for additional boxtypes though (because they are not "known" to the schemes) but that's what happens for existing boxtypes of all FLTK schemes.

I'm not happy with this, but this is how FLTK "schemes" were implemented in the early days of FLTK. There's currently no way to change this although I was thinking about a better way for years. Maybe at some time in the future...

Piotr Wieczorek

unread,
Apr 4, 2022, 9:55:15 AM4/4/22
to fltkg...@googlegroups.com
Thanks for all the information!

Best, 
Piotr

--
You received this message because you are subscribed to a topic in the Google Groups "fltk.general" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/fltkgeneral/dOrkdXu8LYg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to fltkgeneral...@googlegroups.com.

Ian MacArthur

unread,
Apr 4, 2022, 10:07:18 AM4/4/22
to fltk.general
On Monday, 4 April 2022 at 14:25:14 UTC+1 Albrecht Schlosser wrote:

There's another point that should be considered carefully for such a thing like Go bindings. When you use Fl::scheme("any-scheme") all the standard boxtypes are overwritten (in the array of boxtype definitions) by the boxtypes of the selected scheme. This includes the function pointers and all boxtype attributes. It may not matter for additional boxtypes though (because they are not "known" to the schemes) but that's what happens for existing boxtypes of all FLTK schemes.

I'm not happy with this, but this is how FLTK "schemes" were implemented in the early days of FLTK. There's currently no way to change this although I was thinking about a better way for years. Maybe at some time in the future...

Though I do think it was the right way at the time (it was a while ago) and is still the low-cost option today, really, so for a lightweight system it probably still makes sense to do it this way...

That said, when I need a widget with a custom appearance I've never really tried to override the boxtypes or set my own scheme or etc., I have always just derived a custom widget and drawn it "myself", which is really the easier way to go I think - and would probably work to address Piotr's use case, since you can pretty much define an arbitrary set of widgets that way. 


Reply all
Reply to author
Forward
0 new messages