lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] How InputSequenceEditor::remove_row() works [Was: master 78a4d


From: Greg Chicares
Subject: Re: [lmi] How InputSequenceEditor::remove_row() works [Was: master 78a4de0 5/7: Enable '-Wnull-dereference'; fix the issues it flags]
Date: Sat, 23 Mar 2019 18:20:21 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1

On 2019-03-23 16:42, Vadim Zeitlin wrote:
> On Fri, 22 Mar 2019 21:08:27 +0000 Greg Chicares <address@hidden> wrote:

[...deleting one row from a two-dimensional array...]

> GC> I'd point out how trivial this would be in APL, but

[...until the wxAPL port is completed...]

>  I don't believe that even the power of APL would help to deal with the
> poor wxSizer API here. The real problem is that it doesn't provide
> something like erase(begin, end) method that would allow doing what this
> code does without using an explicit loop and, more generally, that it uses
> indices instead of iterators. I think it's too late to change the latter,
> but I think it would be generally useful to do something about the former.

I don't understand.

  https://docs.wxwidgets.org/3.0/classwx_sizer.html

  wxSizerItemList& wxSizer::GetChildren() const
  // The elements of type-safe wxList wxSizerItemList are pointers to
  // objects of type wxSizerItem.

I take that to mean that there's a data member of type wxList<wxSizerItem>
that contains all the sizer-items, and we can get a writable reference to
it. Then can't we get iterators like std::list::begin(), and erase ranges
of iterators as with std::list::erase(), can't we?

> Unfortunately it's not as simple as just adding another Remove() overload
> because we need to destroy the window as well, but adding Destroy() family
> of methods similar to the existing Remove/Detach ones and including an
> overload working with a range could be a good solution.
> 
>  And then the lmi code could become just
> 
>         int index = row * Col_Max;
>         sizer_->Destroy(index, index + Col_Max);
> 
> which would be much simpler to understand.

Yes, it would greatly simplify this particular case. However...

>  What do you think?

The way I understand it, no sizer should own or delete a wxWindow,
so I was thinking along these lines instead:

    int index = row * Col_Max;
    // new function to get a subrange of items:
    auto& a_row_of_items = sizer_->GetItems(index, index + Col_Max);
    for(wxSizerItem& x : a_row_of_items) {x.DeleteWindows()}

According to the comment just added in HEAD:

    sizer_->Detach(index); // Superfluous--Destroy() does this anyway.
    win->Destroy();

we shouldn't need to call any non-const member of wxSizer here;
we just delete the wxWindows, and the sizer adapts to the deletion.

In this case, we have a grid sizer:
    wxFlexGridSizer* sizer_;
to which a member like this might be added:
  wxSizerItemList& wxGridSizer::GetChildrenInRow(int row_number);
and then we could write:

    auto& a_row_of_items = sizer_->GetChildrenInRow(int row_number);
    for(wxSizerItem& x : a_row_of_items) {x.DeleteWindows();}

or, eliminating the intermediate variable:

    for(wxSizerItem& x : sizer_->GetChildrenInRow(int row_number))
      {x.DeleteWindows();}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]