Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow replacing an element of an Fl_Group (without deleting it) #994

Closed
ggarra13 opened this issue Jun 23, 2024 · 3 comments
Closed

Allow replacing an element of an Fl_Group (without deleting it) #994

ggarra13 opened this issue Jun 23, 2024 · 3 comments
Assignees
Labels
no user support The issue system is not for user support. Please ask user questions in fltk.general.

Comments

@ggarra13
Copy link
Contributor

I have been playing with pyFLTK and have been enjoying it. However, I run into what appears a limitation in its interaction with FLTK's API that would effect probably any other language binding too.

I am trying to change the order of the Fl_Widgets in an Fl_Group, similar to what it is done in Fl_Scroll:

void Fl_Scroll::fix_scrollbar_order() {
  Fl_Widget** a = (Fl_Widget**)array();
  if (children() > 1 &&
      (a[children()-2] != &scrollbar ||
       a[children()-1] != &hscrollbar)) {
    int i, j;
    for (i = j = 0; j < children(); j++) {
      if (a[j] != &hscrollbar && a[j] != &scrollbar)
        a[i++] = a[j];
    }
    a[i++] = &scrollbar;
    a[i++] = &hscrollbar;
  }
}

On Python, there's no way to deal with the pointers directly, afaik. And doing something, like:

      # store widgets
      widgets = []
      for x in range(self.children()):
            widgets.append(self.child(x))
       
       # Sort them     
       widgets = sort_by_some_method(widgets)
      
       self.clear()          # undefined behavior, as FLTK will call "delete" on all the pointers
       for widget in widgets:
              self.add(widgets)

I would like to do:

      widgets = []
      for x in range(self.children()):
            widgets.append(self.child(x))
            
     # Sort them     
      widgets = sort_by_some_method(widgets)
            
       # Replace them, without deleting the original ones
       for index, widget in enumerate(widgets):
              self.replace(idex, widget, delete=False)

I am using FLTK

  • 1.4.0 master

Describe the solution you'd like
Either one of two things (whatever is easier):

  1. Add a flag to Fl_Group to have clear() and remove() not call "delete widget" on its children.
  2. Add a Fl_Group::replace(idx, Fl_Widget& w) to replace the widget at index idx (no bound checking, etc) and, optionally, without deleting the original pointer.

Describe alternatives you've considered
Create my own derived C++ Fl_Group and expose it in pyFLTK.

@Albrecht-S
Copy link
Member

This is a question you should probably ask in pyFLTK support/forum/group/whatever.

As far as FLTK is concerned, did you consider using Fl_Group::remove(child) which removes the child widget w/o deleting it? This should be supported by pyFLTK as well (is it?), and if it is you could do something as in your first example, replacing self.clear() with a loop that removes all children.

Disclaimer: I don't know how pyFLTK (i.e. python itself) operates (WRT memory management) but I believe it uses some kind of garbage collection. Thus, as long as you store all the widgets in the array widgets[] they should be "safe" from deletion while you remove() them from their parent group. Please correct me if that's not true.

Another approach would be to use the FLTK equivalent of Fl_Group::insert() after sorting your widgets in pyFLTK. Insert them in the new order, one by one, at position 1, 2, 3, ...
See the docs linked above, particularly the sentence "This can also be used to rearrange the widgets inside a group". While doing this, all widgets are removed and re-inserted at the requested position.

@Albrecht-S
Copy link
Member

I just noticed that you wrote:

Add a flag to Fl_Group to have clear() and remove() not call "delete widget" on its children.

Your implied assumption in this statement is incorrect: Fl_Group::remove() does NOT delete the child widget - as I wrote above (see the linked docs).

@ggarra13
Copy link
Contributor Author

Your implied assumption in this statement is incorrect: Fl_Group::remove() does NOT delete the child widget - as I wrote above (see the linked docs).

Indeed. I had missed that detail and both Robert Arkiletian (of pyFLTK) and yourself pointed me in the right direction. I am closing the issue. I apologize.

@Albrecht-S Albrecht-S self-assigned this Jun 24, 2024
@Albrecht-S Albrecht-S added the no user support The issue system is not for user support. Please ask user questions in fltk.general. label Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no user support The issue system is not for user support. Please ask user questions in fltk.general.
Projects
None yet
Development

No branches or pull requests

2 participants