Skip to content

Commit

Permalink
GridView, TreeGridView: allow items in dataProvider to be string
Browse files Browse the repository at this point in the history
Similar to ListView and other components, check if item is String and use separate StringMap for those values because they can't be stored in ObjectMap
  • Loading branch information
joshtynjala committed Sep 9, 2024
1 parent beba18a commit 8825e92
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 39 deletions.
86 changes: 66 additions & 20 deletions src/feathers/controls/GridView.hx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@

package feathers.controls;

import feathers.dragDrop.DragDropManager;
import feathers.dragDrop.DragData;
import feathers.dragDrop.IDropTarget;
import feathers.dragDrop.IDragSource;
import openfl.Lib;
import feathers.layout.IDragDropLayout;
import feathers.events.DragDropEvent;
import feathers.controls.dataRenderers.GridViewRowRenderer;
import feathers.controls.dataRenderers.IGridViewHeaderRenderer;
import feathers.controls.dataRenderers.ItemRenderer;
Expand All @@ -35,11 +28,17 @@ import feathers.data.GridViewHeaderState;
import feathers.data.IFlatCollection;
import feathers.data.ISortOrderObserver;
import feathers.data.SortOrder;
import feathers.dragDrop.DragData;
import feathers.dragDrop.DragDropManager;
import feathers.dragDrop.IDragSource;
import feathers.dragDrop.IDropTarget;
import feathers.events.DragDropEvent;
import feathers.events.FeathersEvent;
import feathers.events.FlatCollectionEvent;
import feathers.events.GridViewEvent;
import feathers.events.TriggerEvent;
import feathers.layout.GridViewRowLayout;
import feathers.layout.IDragDropLayout;
import feathers.layout.IKeyboardNavigationLayout;
import feathers.layout.ILayout;
import feathers.layout.ILayoutIndexObject;
Expand All @@ -56,6 +55,8 @@ import feathers.utils.DisplayUtil;
import feathers.utils.ExclusivePointer;
import feathers.utils.MathUtil;
import haxe.ds.ObjectMap;
import haxe.ds.StringMap;
import openfl.Lib;
import openfl.display.DisplayObject;
import openfl.display.DisplayObjectContainer;
import openfl.display.InteractiveObject;
Expand Down Expand Up @@ -1194,7 +1195,8 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
private var headerRendererToHeaderState = new ObjectMap<DisplayObject, GridViewHeaderState>();
private var inactiveRowRenderers:Array<GridViewRowRenderer> = [];
private var activeRowRenderers:Array<GridViewRowRenderer> = [];
private var dataToRowRenderer = new ObjectMap<Dynamic, GridViewRowRenderer>();
private var stringDataToRowRenderer = new StringMap<GridViewRowRenderer>();
private var objectDataToRowRenderer = new ObjectMap<Dynamic, GridViewRowRenderer>();
private var rowRendererToRowState = new ObjectMap<GridViewRowRenderer, GridViewRowState>();
private var headerStatePool = new ObjectPool(() -> new GridViewHeaderState());
private var rowStatePool = new ObjectPool(() -> new GridViewRowState());
Expand Down Expand Up @@ -1484,7 +1486,12 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
if (item == null) {
return null;
}
var rowRenderer = this.dataToRowRenderer.get(item);
var rowRenderer:GridViewRowRenderer = null;
if ((item is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast item);
} else {
rowRenderer = this.objectDataToRowRenderer.get(item);
}
if (rowRenderer == null) {
return null;
}
Expand Down Expand Up @@ -1527,7 +1534,12 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
if (item == null) {
return null;
}
var rowRenderer = this.dataToRowRenderer.get(item);
var rowRenderer:GridViewRowRenderer = null;
if ((item is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast item);
} else {
rowRenderer = this.objectDataToRowRenderer.get(item);
}
if (rowRenderer == null) {
return null;
}
Expand Down Expand Up @@ -1792,8 +1804,12 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
var newColumns:ArrayCollection<GridViewColumn> = null;
if (this._dataProvider != null && this._dataProvider.length > 0) {
var item = this._dataProvider.get(0);
newColumns = new ArrayCollection(Reflect.fields(item)
.map((fieldName) -> new GridViewColumn(fieldName, (item) -> Std.string(Reflect.getProperty(item, fieldName)))));
newColumns = new ArrayCollection(Reflect.fields(item).map((fieldName) -> {
return new GridViewColumn(fieldName, (item) -> {
var propertyValue = Reflect.getProperty(item, fieldName);
return Std.string(propertyValue);
});
}));
} else {
newColumns = new ArrayCollection();
}
Expand Down Expand Up @@ -2324,7 +2340,11 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
}
var item = state.data;
this.rowRendererToRowState.remove(rowRenderer);
this.dataToRowRenderer.remove(item);
if ((item is String)) {
this.stringDataToRowRenderer.remove(cast item);
} else {
this.objectDataToRowRenderer.remove(item);
}
rowRenderer.removeEventListener(GridViewEvent.CELL_TRIGGER, gridView_rowRenderer_cellTriggerHandler);
rowRenderer.removeEventListener(TriggerEvent.TRIGGER, gridView_rowRenderer_triggerHandler);
rowRenderer.removeEventListener(MouseEvent.MOUSE_DOWN, gridView_rowRenderer_mouseDownHandler);
Expand Down Expand Up @@ -2382,7 +2402,12 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
}
for (i in this._visibleIndices.start...this._visibleIndices.end + 1) {
var item = this._dataProvider.get(i);
var rowRenderer = this.dataToRowRenderer.get(item);
var rowRenderer:GridViewRowRenderer = null;
if ((item is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast item);
} else {
rowRenderer = this.objectDataToRowRenderer.get(item);
}
if (rowRenderer != null) {
var state = this.rowRendererToRowState.get(rowRenderer);
var changed = this.populateCurrentRowState(item, i, state, this._forceItemStateUpdate);
Expand Down Expand Up @@ -2437,7 +2462,12 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
rowRenderer.addEventListener(TriggerEvent.TRIGGER, gridView_rowRenderer_triggerHandler);
rowRenderer.addEventListener(MouseEvent.MOUSE_DOWN, gridView_rowRenderer_mouseDownHandler);
this.rowRendererToRowState.set(rowRenderer, state);
this.dataToRowRenderer.set(state.data, rowRenderer);
var row = state.data;
if ((row is String)) {
this.stringDataToRowRenderer.set(cast row, rowRenderer);
} else {
this.objectDataToRowRenderer.set(row, rowRenderer);
}
return rowRenderer;
}

Expand Down Expand Up @@ -2700,7 +2730,13 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
}
var changed = this._selectedIndex != result;
if (!changed && result != -1) {
var rowRenderer = this.dataToRowRenderer.get(this._dataProvider.get(result));
var rowRenderer:GridViewRowRenderer = null;
var row = this._dataProvider.get(result);
if ((row is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast row);
} else {
rowRenderer = this.objectDataToRowRenderer.get(row);
}
if (rowRenderer == null) {
// if we can't find the item renderer, we need to scroll
changed = true;
Expand Down Expand Up @@ -2807,7 +2843,12 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
targetY = result.y;
} else {
var row = this._dataProvider.get(rowIndex);
var rowRenderer = this.dataToRowRenderer.get(row);
var rowRenderer:GridViewRowRenderer = null;
if ((row is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast row);
} else {
rowRenderer = this.objectDataToRowRenderer.get(row);
}
if (rowRenderer == null) {
return;
}
Expand Down Expand Up @@ -3105,8 +3146,13 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
if (this._virtualCache != null) {
this._virtualCache[index] = null;
}
var item = this._dataProvider.get(index);
var rowRenderer = this.dataToRowRenderer.get(item);
var row = this._dataProvider.get(index);
var rowRenderer:GridViewRowRenderer = null;
if ((row is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast row);
} else {
rowRenderer = this.objectDataToRowRenderer.get(row);
}
if (rowRenderer == null) {
// doesn't exist yet, so we need to do a full invalidation
this.setInvalid(DATA);
Expand All @@ -3118,7 +3164,7 @@ class GridView extends BaseScrollContainer implements IIndexSelector implements
return;
}
rowRenderer.updateCells();
this.populateCurrentRowState(item, index, state, true);
this.populateCurrentRowState(row, index, state, true);
// 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.
Expand Down
89 changes: 70 additions & 19 deletions src/feathers/controls/TreeGridView.hx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import feathers.utils.DisplayUtil;
import feathers.utils.ExclusivePointer;
import feathers.utils.MathUtil;
import haxe.ds.ObjectMap;
import haxe.ds.StringMap;
import openfl.display.DisplayObject;
import openfl.display.DisplayObjectContainer;
import openfl.display.InteractiveObject;
Expand Down Expand Up @@ -961,7 +962,8 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
private var headerRendererToHeaderState = new ObjectMap<DisplayObject, TreeGridViewHeaderState>();
private var inactiveRowRenderers:Array<TreeGridViewRowRenderer> = [];
private var activeRowRenderers:Array<TreeGridViewRowRenderer> = [];
private var dataToRowRenderer = new ObjectMap<Dynamic, TreeGridViewRowRenderer>();
private var stringDataToRowRenderer = new StringMap<TreeGridViewRowRenderer>();
private var objectDataToRowRenderer = new ObjectMap<Dynamic, TreeGridViewRowRenderer>();
private var rowRendererToRowState = new ObjectMap<TreeGridViewRowRenderer, TreeGridViewRowState>();
private var headerStatePool = new ObjectPool(() -> new TreeGridViewHeaderState());
private var rowStatePool = new ObjectPool(() -> new TreeGridViewRowState());
Expand Down Expand Up @@ -1074,7 +1076,12 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
if (item == null) {
return null;
}
var rowRenderer = this.dataToRowRenderer.get(item);
var rowRenderer:TreeGridViewRowRenderer = null;
if ((item is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast item);
} else {
rowRenderer = this.objectDataToRowRenderer.get(item);
}
if (rowRenderer == null) {
return null;
}
Expand Down Expand Up @@ -1171,7 +1178,12 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
if (item == null) {
return null;
}
var rowRenderer = this.dataToRowRenderer.get(item);
var rowRenderer:TreeGridViewRowRenderer = null;
if ((item is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast item);
} else {
rowRenderer = this.objectDataToRowRenderer.get(item);
}
if (rowRenderer == null) {
return null;
}
Expand Down Expand Up @@ -1429,8 +1441,12 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
var newColumns:ArrayCollection<TreeGridViewColumn> = null;
if (this._dataProvider != null && this._dataProvider.getLength() > 0) {
var item = this._dataProvider.get([0]);
newColumns = new ArrayCollection(Reflect.fields(item)
.map((fieldName) -> new TreeGridViewColumn(fieldName, (item) -> Std.string(Reflect.getProperty(item, fieldName)))));
newColumns = new ArrayCollection(Reflect.fields(item).map((fieldName) -> {
return new TreeGridViewColumn(fieldName, (item) -> {
var propertyValue = Reflect.getProperty(item, fieldName);
return Std.string(propertyValue);
});
}));
} else {
newColumns = new ArrayCollection();
}
Expand Down Expand Up @@ -1959,9 +1975,13 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
if (state == null) {
continue;
}
var item = state.data;
var row = state.data;
this.rowRendererToRowState.remove(rowRenderer);
this.dataToRowRenderer.remove(item);
if ((row is String)) {
this.stringDataToRowRenderer.remove(cast row);
} else {
this.objectDataToRowRenderer.remove(row);
}
rowRenderer.removeEventListener(TreeGridViewEvent.CELL_TRIGGER, treeGridView_rowRenderer_cellTriggerHandler);
rowRenderer.removeEventListener(TriggerEvent.TRIGGER, treeGridView_rowRenderer_triggerHandler);
rowRenderer.removeEventListener(Event.OPEN, treeGridView_rowRenderer_openHandler);
Expand Down Expand Up @@ -2043,15 +2063,20 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
return layoutIndex;
}

private function findRowRenderer(item:Dynamic, location:Array<Int>, layoutIndex:Int):Void {
var rowRenderer = this.dataToRowRenderer.get(item);
private function findRowRenderer(row:Dynamic, location:Array<Int>, layoutIndex:Int):Void {
var rowRenderer:TreeGridViewRowRenderer = null;
if ((row is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast row);
} else {
rowRenderer = this.objectDataToRowRenderer.get(row);
}
if (rowRenderer == null) {
this._unrenderedLocations.push(location);
this._unrenderedLayoutIndices.push(layoutIndex);
return;
}
var state = this.rowRendererToRowState.get(rowRenderer);
var changed = this.populateCurrentRowState(item, location, layoutIndex, state, this._forceItemStateUpdate);
var changed = this.populateCurrentRowState(row, location, layoutIndex, state, this._forceItemStateUpdate);
if (changed) {
this.updateRowRenderer(rowRenderer, state);
}
Expand Down Expand Up @@ -2103,7 +2128,12 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
rowRenderer.addEventListener(Event.OPEN, treeGridView_rowRenderer_openHandler);
rowRenderer.addEventListener(Event.CLOSE, treeGridView_rowRenderer_closeHandler);
this.rowRendererToRowState.set(rowRenderer, state);
this.dataToRowRenderer.set(state.data, rowRenderer);
var row = state.data;
if ((row is String)) {
this.stringDataToRowRenderer.set(cast row, rowRenderer);
} else {
this.objectDataToRowRenderer.set(row, rowRenderer);
}
this.activeRowRenderers.push(rowRenderer);
return rowRenderer;
}
Expand Down Expand Up @@ -2494,8 +2524,14 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
var pendingLocation:Array<Int> = null;
if (!changed && result != -1) {
pendingLocation = this.displayIndexToLocation(result);
var itemRenderer = this.dataToRowRenderer.get(this._dataProvider.get(pendingLocation));
if (itemRenderer == null) {
var row = this._dataProvider.get(pendingLocation);
var rowRenderer:TreeGridViewRowRenderer = null;
if ((row is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast row);
} else {
rowRenderer = this.objectDataToRowRenderer.get(row);
}
if (rowRenderer == null) {
// if we can't find the item renderer, we need to scroll
changed = true;
} else if ((this.layout is IScrollLayout)) {
Expand Down Expand Up @@ -2551,8 +2587,13 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
targetX = result.x;
targetY = result.y;
} else {
var item = this._dataProvider.get(location);
var rowRenderer = this.dataToRowRenderer.get(item);
var row = this._dataProvider.get(location);
var rowRenderer:TreeGridViewRowRenderer = null;
if ((row is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast row);
} else {
rowRenderer = this.objectDataToRowRenderer.get(row);
}
if (rowRenderer == null) {
return;
}
Expand Down Expand Up @@ -2584,7 +2625,12 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
}

private function toggleBranchInternal(branch:Dynamic, location:Array<Int>, layoutIndex:Int, open:Bool):Int {
var rowRenderer = this.dataToRowRenderer.get(branch);
var rowRenderer:TreeGridViewRowRenderer = null;
if ((branch is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast branch);
} else {
rowRenderer = this.objectDataToRowRenderer.get(branch);
}
var state:TreeGridViewRowState = null;
if (rowRenderer != null) {
state = this.rowRendererToRowState.get(rowRenderer);
Expand Down Expand Up @@ -2813,8 +2859,13 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
if (this._virtualCache != null && layoutIndex != -1) {
this._virtualCache[layoutIndex] = null;
}
var item = this._dataProvider.get(location);
var rowRenderer = this.dataToRowRenderer.get(item);
var row = this._dataProvider.get(location);
var rowRenderer:TreeGridViewRowRenderer = null;
if ((row is String)) {
rowRenderer = this.stringDataToRowRenderer.get(cast row);
} else {
rowRenderer = this.objectDataToRowRenderer.get(row);
}
if (rowRenderer == null) {
// doesn't exist yet, so we need to do a full invalidation
this.setInvalid(DATA);
Expand All @@ -2826,7 +2877,7 @@ class TreeGridView extends BaseScrollContainer implements IDataSelector<Dynamic>
return;
}
rowRenderer.updateCells();
this.populateCurrentRowState(item, location, layoutIndex, state, true);
this.populateCurrentRowState(row, location, layoutIndex, state, true);
// 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.
Expand Down

0 comments on commit 8825e92

Please sign in to comment.