Skip to content

Commit

Permalink
ButtonBar, TabBar: fix wrong recycler being used when multiple are re…
Browse files Browse the repository at this point in the history
…gistered
  • Loading branch information
joshtynjala committed Mar 8, 2025
1 parent 11fd4ff commit 43416b2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 24 deletions.
27 changes: 15 additions & 12 deletions src/feathers/controls/ButtonBar.hx
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ class ButtonBar extends FeathersControl {
if (factoryInvalid) {
this.recoverInactiveButtons(storage);
this.freeInactiveButtons(storage);
storage.oldButtonRecycler = null;
}
}

Expand All @@ -741,17 +742,18 @@ class ButtonBar extends FeathersControl {
this.objectDataToButton.remove(item);
}
button.removeEventListener(TriggerEvent.TRIGGER, buttonBar_button_triggerHandler);
this.resetButton(button, state);
this.resetButton(button, state, storage);
this.itemStatePool.release(state);
}
}

private function freeInactiveButtons(storage:ButtonStorage):Void {
var recycler = storage.oldButtonRecycler != null ? storage.oldButtonRecycler : storage.buttonRecycler;
for (button in storage.inactiveButtons) {
if (button == null) {
continue;
}
this.destroyButton(button);
this.destroyButton(button, recycler);
}
#if (hl && haxe_ver < 4.3)
storage.inactiveButtons.splice(0, storage.inactiveButtons.length);
Expand Down Expand Up @@ -899,7 +901,7 @@ class ButtonBar extends FeathersControl {
var storage = this.itemStateToStorage(state);
var button:Button = null;
if (storage.inactiveButtons.length == 0) {
button = this.buttonRecycler.create();
button = storage.buttonRecycler.create();
if (button.variant == null) {
// if the factory set a variant already, don't use the default
var variant = this.customButtonVariant != null ? this.customButtonVariant : ButtonBar.CHILD_VARIANT_BUTTON;
Expand All @@ -924,10 +926,10 @@ class ButtonBar extends FeathersControl {
return button;
}

private function destroyButton(button:Button):Void {
private function destroyButton(button:Button, recycler:DisplayObjectRecycler<Dynamic, ButtonBarItemState, Button>):Void {
this.removeChild(button);
if (this.buttonRecycler.destroy != null) {
this.buttonRecycler.destroy(button);
if (recycler != null && recycler.destroy != null) {
recycler.destroy(button);
}
}

Expand Down Expand Up @@ -993,18 +995,19 @@ class ButtonBar extends FeathersControl {
state.recyclerID = storage.id;
var oldIgnoreSelectionChange = this._ignoreSelectionChange;
this._ignoreSelectionChange = true;
if (this.buttonRecycler.update != null) {
this.buttonRecycler.update(button, state);
if (storage.buttonRecycler.update != null) {
storage.buttonRecycler.update(button, state);
}
this._ignoreSelectionChange = oldIgnoreSelectionChange;
this.refreshButtonProperties(button, state);
}

private function resetButton(button:Button, state:ButtonBarItemState):Void {
private function resetButton(button:Button, state:ButtonBarItemState, storage:ButtonStorage):Void {
var oldIgnoreSelectionChange = this._ignoreSelectionChange;
this._ignoreSelectionChange = true;
if (this.buttonRecycler != null && this.buttonRecycler.reset != null) {
this.buttonRecycler.reset(button, state);
var recycler = storage.oldButtonRecycler != null ? storage.oldButtonRecycler : storage.buttonRecycler;
if (recycler != null && recycler.reset != null) {
recycler.reset(button, state);
}
this._ignoreSelectionChange = oldIgnoreSelectionChange;
this.refreshButtonProperties(button, RESET_BUTTON_STATE);
Expand Down Expand Up @@ -1063,7 +1066,7 @@ class ButtonBar extends FeathersControl {
// in order to display the same item with modified properties, this
// hack tricks the item renderer into thinking that it has been given
// a different item to render.
this.resetButton(button, state);
this.resetButton(button, state, storage);
// ensures that the change is detected when we validate later
state.owner = null;
this.setInvalid(DATA);
Expand Down
27 changes: 15 additions & 12 deletions src/feathers/controls/TabBar.hx
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ class TabBar extends FeathersControl implements IIndexSelector implements IDataS
if (factoryInvalid) {
this.recoverInactiveTabs(storage);
this.freeInactiveTabs(storage);
storage.oldTabRecycler = null;
}
}

Expand All @@ -871,17 +872,18 @@ class TabBar extends FeathersControl implements IIndexSelector implements IDataS
}
tab.removeEventListener(TriggerEvent.TRIGGER, tabBar_tab_triggerHandler);
tab.removeEventListener(Event.CHANGE, tabBar_tab_changeHandler);
this.resetTab(tab, state);
this.resetTab(tab, state, storage);
this.itemStatePool.release(state);
}
}

private function freeInactiveTabs(storage:TabStorage):Void {
var recycler = storage.oldTabRecycler != null ? storage.oldTabRecycler : storage.tabRecycler;
for (tab in storage.inactiveTabs) {
if (tab == null) {
continue;
}
this.destroyTab(tab);
this.destroyTab(tab, recycler);
}
#if (hl && haxe_ver < 4.3)
storage.inactiveTabs.splice(0, storage.inactiveTabs.length);
Expand Down Expand Up @@ -1029,7 +1031,7 @@ class TabBar extends FeathersControl implements IIndexSelector implements IDataS
var storage = this.itemStateToStorage(state);
var tab:ToggleButton = null;
if (storage.inactiveTabs.length == 0) {
tab = this.tabRecycler.create();
tab = storage.tabRecycler.create();
if (tab.variant == null) {
// if the factory set a variant already, don't use the default
var variant = this.customTabVariant != null ? this.customTabVariant : TabBar.CHILD_VARIANT_TAB;
Expand All @@ -1056,10 +1058,10 @@ class TabBar extends FeathersControl implements IIndexSelector implements IDataS
return tab;
}

private function destroyTab(tab:ToggleButton):Void {
private function destroyTab(tab:ToggleButton, recycler:DisplayObjectRecycler<Dynamic, TabBarItemState, ToggleButton>):Void {
this.removeChild(tab);
if (this.tabRecycler.destroy != null) {
this.tabRecycler.destroy(tab);
if (recycler != null && recycler.destroy != null) {
recycler.destroy(tab);
}
}

Expand Down Expand Up @@ -1130,18 +1132,19 @@ class TabBar extends FeathersControl implements IIndexSelector implements IDataS
state.recyclerID = storage.id;
var oldIgnoreSelectionChange = this._ignoreSelectionChange;
this._ignoreSelectionChange = true;
if (this.tabRecycler.update != null) {
this.tabRecycler.update(tab, state);
if (storage.tabRecycler.update != null) {
storage.tabRecycler.update(tab, state);
}
this._ignoreSelectionChange = oldIgnoreSelectionChange;
this.refreshTabProperties(tab, state);
}

private function resetTab(tab:ToggleButton, state:TabBarItemState):Void {
private function resetTab(tab:ToggleButton, state:TabBarItemState, storage:TabStorage):Void {
var oldIgnoreSelectionChange = this._ignoreSelectionChange;
this._ignoreSelectionChange = true;
if (this.tabRecycler != null && this.tabRecycler.reset != null) {
this.tabRecycler.reset(tab, state);
var recycler = storage.oldTabRecycler != null ? storage.oldTabRecycler : storage.tabRecycler;
if (recycler != null && recycler.reset != null) {
recycler.reset(tab, state);
}
this._ignoreSelectionChange = oldIgnoreSelectionChange;
this.refreshTabProperties(tab, RESET_TAB_STATE);
Expand Down Expand Up @@ -1337,7 +1340,7 @@ class TabBar extends FeathersControl implements IIndexSelector implements IDataS
// in order to display the same item with modified properties, this
// hack tricks the item renderer into thinking that it has been given
// a different item to render.
this.resetTab(tab, state);
this.resetTab(tab, state, storage);
// ensures that the change is detected when we validate later
state.owner = null;
this.setInvalid(DATA);
Expand Down

0 comments on commit 43416b2

Please sign in to comment.