Archicad C++ API
About Archicad add-on development using the C++ API.

DG::ListBox layouting doesn't work on Mac after changing the number of tab fields

kovacsv
Booster

Hey,

 

I'm targeting AC26 and I'd like to make all columns of a DG::ListBox the same width in a way that they fill up the whole width of the ListBox. It works fine, but whenever I change the number of tab fields and recalculate the layout the changes are not visible on Mac. On Windows everything works like charm, but on Mac I need to do a resize for columns to get the final width.

 

 

Probably I'm doing something wrong. Here is my example code that fills the ListBox with dummy elements, and changes the number of tab field by clicking on a button.

 

GRC

 

'GDLG' ID_TEST_DIALOG Modal | grow   0   0  200  100  "Test Dialog" {
/* [  1] */ Button           10   10  140  23    LargePlain "Change Tab Field Count"
/* [  2] */ SingleSelList    10   43  180  47    LargePlain  PartialItems  18 HasHeader 18
}

'DLGH' ID_TEST_DIALOG Palette_Test_Dialog {
1    ""    TestButton
2    ""    TestList
}

 

C++

 

class TestDialog :
    public DG::ModalDialog,
    public DG::PanelObserver,
    public DG::ButtonItemObserver
{
public:
    TestDialog () :
        DG::ModalDialog (ACAPI_GetOwnResModule (), ID_TEST_DIALOG, ACAPI_GetOwnResModule ()),
        mButton (GetReference (), 1),
        mListBox (GetReference (), 2),
        mTabFieldCount (2)
    {
        Attach (*this);
        mButton.Attach (*this);

        mListBox.SetHeaderSynchronState (true);
        FillListBox ();
    }

private:
    virtual void PanelResized (const DG::PanelResizeEvent& ev) override
    {
        if (ev.GetSource () == this) {
            BeginMoveResizeItems ();
            mListBox.MoveAndResize (0, 0, ev.GetHorizontalChange (), ev.GetVerticalChange ());
            EndMoveResizeItems ();
            LayoutListBoxTabs ();
        }
    }

    virtual void ButtonClicked (const DG::ButtonClickEvent& ev) override
    {
        if (ev.GetSource () == &mButton) {
            mTabFieldCount = (mTabFieldCount == 2 ? 3 : 2);
            FillListBox ();
        }
    }

    void FillListBox ()
    {
        mListBox.DeleteItem (DG::ListBox::AllItems);
        mListBox.SetTabFieldCount (mTabFieldCount);

        for (short j = 1; j <= mTabFieldCount; j++) {
            mListBox.SetHeaderItemText (j, GS::UniString::Printf ("header %d", j));
        }

        for (short i = 1; i <= 10; i++) {
            mListBox.AppendItem ();
            for (short j = 1; j <= mTabFieldCount; j++) {
                mListBox.SetTabItemText (DG::ListBox::BottomItem, j, GS::UniString::Printf ("item %d %d", i, j));
            }
        }

        LayoutListBoxTabs ();
    }

    void LayoutListBoxTabs ()
    {
        short tabFieldWidth = mListBox.GetItemWidth () / mTabFieldCount;
        for (short i = 1; i <= mTabFieldCount; i++) {
            mListBox.SetTabFieldBeginEndPosition (i, (i - 1) * tabFieldWidth, i * tabFieldWidth);
        }
    }

    DG::Button mButton;
    DG::SingleSelListBox mListBox;
    short mTabFieldCount;
};

 

 Any idea how to resolve this?

5 REPLIES 5
Oleg
Expert

I dont know a reason, but some ideas:

1. In FillListBox try to move call of LayoutListBox before items filling. After SetTabItemCount.

2. Call after items filling mListBox.Redraw() or mListBox.Invalidate()


PS:
I am usually do filling like this:

 

void TabSelectorLink::UpdateTable()
{
	Filter* sel = GetSelectedFilter();
	if ( !sel )
		sel = m_data.link;

	mi_list.DisableDraw();
	mi_list.DeleteItem( DG::ListBox::AllItems );

	FillList( sel );

	mi_list.EnableDraw();
	mi_list.Invalidate();
}

 

Thanks for the suggestion. Unfortunately I've tried all combinations of DisableDraw, EnableDraw and Invalidate calls. It seems that it has something to do with the number of the tab fields. It's clearly visible in the video that the columns are aligned well for a couple of milliseconds, but then they jump to a wrong position.

Oleg
Expert

Unfortunataly I have no a Mac to try. So may be there is some mac's specific.

 

Are you tried my first idea ?


In the function FillListBox move call of LayoutListBox right after mListBox.SetTabItemCount(..) line.


There is may be a column "jump" reason. 

Hi!

I tried your example on macOS and I was able to resolve the issue by setting the HeaderSynchronState to 'false' and then manually changing the header count and header item width. Here are the changed functions:

 ...
   void FillListBox ()
    {
        mListBox.DeleteItem (DG::ListBox::AllItems);
        mListBox.SetTabFieldCount (mTabFieldCount);
        mListBox.SetHeaderItemCount (mTabFieldCount);

        for (short j = 1; j <= mTabFieldCount; j++) {
            mListBox.SetHeaderItemText (j, GS::UniString::Printf ("header %d", j));
        }

        for (short i = 1; i <= 10; i++) {
            mListBox.AppendItem ();
            for (short j = 1; j <= mTabFieldCount; j++) {
                mListBox.SetTabItemText (DG::ListBox::BottomItem, j, GS::UniString::Printf ("item %d %d", i, j));
            }
        }

        LayoutListBoxTabs ();
    }

    void LayoutListBoxTabs ()
    {
        short tabFieldWidth = mListBox.GetItemWidth () / mTabFieldCount;
        for (short i = 1; i <= mTabFieldCount; i++) {
						mListBox.SetHeaderItemSize (i, tabFieldWidth);
            mListBox.SetTabFieldBeginEndPosition (i, (i - 1) * tabFieldWidth, i * tabFieldWidth);
        }
    }
...

 

There's still a weird "two step" of resizing happening, but now it stays as intended. Maybe the "two step" visual artifact can be resolved by filling order as you've discussed with Oleg.

My suspicion is, that the header synchron state is behaving differently on Windows and macOS.

Hope this helps,
Bernd

Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: bschwb.com

Yes, this is what I found, too. Doing manually gives better result, but still with that annoying delay in layouting. Moving the layout function earlier doesn’t solve it. Maybe I’ll end up maintaining separate list boxes for different column counts. 😅