We value your input! Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey
2022-10-31 07:31 PM - edited 2022-10-31 07:33 PM
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?
2022-11-01 02:01 PM
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();
}
2022-11-01 07:15 PM
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.
2022-11-02 10:56 AM
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.
2022-11-02 04:04 PM
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
2022-11-02 04:52 PM - edited 2022-11-03 07:21 AM
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. 😅