gtoolkit icon indicating copy to clipboard operation
gtoolkit copied to clipboard

Child elements in `GtPlotterHorizontalValueProjectionsElement` are all linked to the same domain object because of initialization of `GtPlotterSingleScaleContext` outside of loop.

Open botwhytho opened this issue 2 years ago • 1 comments

Original Discord thread here. The below code always spawns the last domain object of the values collection no matter on which element you click.

aDay := Date today.
aDuration := Timespan starting: DateAndTime today + 5 hours duration: 1 hour.
anotherDuration := Timespan
        starting: DateAndTime today + 17 hours
        duration: 3 hour.
durations := {aDuration. anotherDuration}.
durations2 := {anotherDuration. aDuration}.
ticks := ((GtPlotterNumberTicks
        from: 0
        to: 24
        count: 24) gtPreviewFor: GtPhlowProtoView new) asElement.
plotter := GtPlotterHorizontalValueProjectionsElement new
        scale: (GtPlotterLinearScale new domainFrom: 0 to: 24 * 60);
        scaleData: [ :each | each start asTime asSeconds // 60 ];
        constraintsDo: [ :c | 
            c vertical fitContent.
            c horizontal matchParent ];
        valueElement: [ :aGtPlotterSingleScaleContext | BlElement new ];
        valueStyle: [ :anElement :aGtPlotterSingleScaleContext | 
            anElement
                background: Color red;
                constraintsDo: [ :c | 
                    c horizontal matchParent.
                    c frame horizontal
                        weight: aGtPlotterSingleScaleContext originalValue duration asMinutes / (24 * 60) ];
                when: BlClickEvent
                    do: [ :anEvent | anEvent target phlow spawnObject: aGtPlotterSingleScaleContext originalValue ] ];
        values: durations.
BrVerticalPane new
    hMatchParent;
    vFitContent;
    aptitude: BrShadowAptitude;
    background: Color white;
    addChildren: {plotter.
            ticks}

You can confirm issue by swapping durations & durations2 as the parameter to values:.

The issue lies in GtPlotterSingleScaleValueBasedElement>>#initializeElements where aScaleContext := GtPlotterSingleScaleContext new. is currently ran outside of the looping through values, where it should happen inside the loop so that every context references it's own domain object. Changing code as below resolves the issue.

image

botwhytho avatar Nov 19 '23 21:11 botwhytho

Seems like other implementors of initializeElements have similar issues where contexts need to be initialized inside loops. Can be found below:

GtPlotterScaleBasedElement gtIsOrInheritsFrom & #initializeElements gtImplementors

botwhytho avatar Nov 20 '23 02:11 botwhytho