diff --git a/src/Toplo/BlElement.extension.st b/src/Toplo/BlElement.extension.st index 263ff5abc..4f5cbb85b 100644 --- a/src/Toplo/BlElement.extension.st +++ b/src/Toplo/BlElement.extension.st @@ -15,6 +15,14 @@ BlElement >> dispatchLookEvent: anEvent [ self childrenDo: [ :child | child dispatchLookEvent: anEvent ] ] +{ #category : #'*Toplo' } +BlElement >> dispatchSkinChangedEvent [ + + self dispatchEvent: ToElementSkinChangedEvent new. + self childrenDo: [ :child | child dispatchSkinChangedEvent ] + +] + { #category : #'*Toplo' } BlElement >> holder [ @@ -76,5 +84,7 @@ BlElement >> toTheme: aTheme [ BlElement >> toThemeChanged [ self dispatchEvent: ToThemeChangedEvent new. - self childrenDo: [ :c | c toThemeChanged ] + self childrenDo: [ :c | c toThemeChanged ]. + + ] diff --git a/src/Toplo/TToCheckable.trait.st b/src/Toplo/TToCheckable.trait.st index 2e3a26f30..766760c84 100644 --- a/src/Toplo/TToCheckable.trait.st +++ b/src/Toplo/TToCheckable.trait.st @@ -56,6 +56,13 @@ TToCheckable >> group: aCheckableGroup [ group := aCheckableGroup ] +{ #category : #initialization } +TToCheckable >> initialize [ + + self class initializeSlots: self. + super initialize. +] + { #category : #'t - checkable initializing' } TToCheckable >> initializeCheckable [ diff --git a/src/Toplo/TToSkinable.trait.st b/src/Toplo/TToSkinable.trait.st index 5a4355ff4..1dcb554ac 100644 --- a/src/Toplo/TToSkinable.trait.st +++ b/src/Toplo/TToSkinable.trait.st @@ -44,9 +44,9 @@ TToSkinable >> withSkin: aSkin [ self withoutSkin. privateSkin := aSkin. Toplo useLookAndFeel ifTrue: [ ^ self ]. - privateSkin ifNotNil: [ self addEventHandler: privateSkin ]. - - + privateSkin ifNotNil: [ + self addEventHandler: privateSkin. + self dispatchSkinChangedEvent ] ] { #category : #'t - skin accessing' } diff --git a/src/Toplo/ToButtonImageSkin.class.st b/src/Toplo/ToButtonImageSkin.class.st index fa767145d..b825ad2ed 100644 --- a/src/Toplo/ToButtonImageSkin.class.st +++ b/src/Toplo/ToButtonImageSkin.class.st @@ -20,11 +20,11 @@ ToButtonImageSkin >> buttonType: aButtonType [ ] { #category : #'api - install/uninstall hook' } -ToButtonImageSkin >> whenAddedToSpace: anEvent in: anElement [ +ToButtonImageSkin >> onSkinInstalledIn: anElement [ | iconLook | iconLook := self buttonType iconLookIn: anElement. self addLook: iconLook. - super whenAddedToSpace: anEvent in: anElement. + super onSkinInstalledIn: anElement ] diff --git a/src/Toplo/ToButtonLabelSkin.class.st b/src/Toplo/ToButtonLabelSkin.class.st index 97a997eba..5514e8719 100644 --- a/src/Toplo/ToButtonLabelSkin.class.st +++ b/src/Toplo/ToButtonLabelSkin.class.st @@ -19,6 +19,20 @@ ToButtonLabelSkin >> buttonType: aButtonType [ buttonType := aButtonType ] +{ #category : #'api - install/uninstall hook' } +ToButtonLabelSkin >> onSkinInstalledIn: anElement [ + + | labelLook attrBuilder | + + attrBuilder := self textAttributesBuilderFromElement: anElement. + labelLook := self buttonType labelLookIn: anElement. + labelLook attrBuilder: attrBuilder. + self addLook: labelLook. + + super onSkinInstalledIn: anElement + +] + { #category : #accessing } ToButtonLabelSkin >> textAttributesBuilderFromElement: anElement [ @@ -32,17 +46,3 @@ ToButtonLabelSkin >> textAttributesBuilderFromElement: anElement [ ^ builder ] - -{ #category : #'api - install/uninstall hook' } -ToButtonLabelSkin >> whenAddedToSpace: anEvent in: anElement [ - - | labelLook attrBuilder | - - attrBuilder := self textAttributesBuilderFromElement: anElement. - labelLook := self buttonType labelLookIn: anElement. - labelLook attrBuilder: attrBuilder. - self addLook: labelLook. - - super whenAddedToSpace: anEvent in: anElement. - -] diff --git a/src/Toplo/ToButtonSkin.class.st b/src/Toplo/ToButtonSkin.class.st index d9a1595ea..c3df217a6 100644 --- a/src/Toplo/ToButtonSkin.class.st +++ b/src/Toplo/ToButtonSkin.class.st @@ -52,6 +52,24 @@ ToButtonSkin >> eventsToHandle [ ^ super eventsToHandle, { ToButtonIconChanged. ToButtonLabelChanged } ] +{ #category : #'api - install/uninstall hook' } +ToButtonSkin >> onSkinInstalledIn: anElement [ + + " must send to super ** after ** the look is initialize from type " + self type onSkinInstalled: self in: anElement. + super onSkinInstalledIn: anElement + +] + +{ #category : #'api - install/uninstall hook' } +ToButtonSkin >> onSkinUninstalledIn: anElement [ + + self type onSkinUninstalled: self in: anElement. + super onSkinUninstalledIn: anElement + + +] + { #category : #accessing } ToButtonSkin >> type [ @@ -66,20 +84,3 @@ ToButtonSkin >> type: aSkinType [ "#default, #primary, #link or #text" type := aSkinType ] - -{ #category : #'api - install/uninstall hook' } -ToButtonSkin >> whenAddedToSpace: anEvent in: anElement [ - - " must send to super ** after ** the look is initialize from type " - self type whenAddedToSpace: anEvent in: anElement fromSkin: self. - super whenAddedToSpace: anEvent in: anElement. - -] - -{ #category : #'api - install/uninstall hook' } -ToButtonSkin >> whenRemovedFromSpace: anEvent in: anElement [ - - self type whenRemovedFromSpace: anEvent in: anElement fromSkin: self. - super whenRemovedFromSpace: anEvent in: anElement. - -] diff --git a/src/Toplo/ToButtonType.class.st b/src/Toplo/ToButtonType.class.st index 5f1d91400..c6a8200f5 100644 --- a/src/Toplo/ToButtonType.class.st +++ b/src/Toplo/ToButtonType.class.st @@ -78,19 +78,7 @@ ToButtonType >> labelLookIn: anElement [ ] { #category : #'api - install/uninstall hook' } -ToButtonType >> regularFormLookIn: anElement [ - - self subclassResponsibility -] - -{ #category : #'api - install/uninstall hook' } -ToButtonType >> regularLabelLookIn: anElement [ - - self subclassResponsibility -] - -{ #category : #'api - install/uninstall hook' } -ToButtonType >> whenAddedToSpace: anEvent in: anElement fromSkin: aSkin [ +ToButtonType >> onSkinInstalled: aSkin in: anElement [ | borderLook backgroundLook | anElement geometry: (BlRoundedRectangleGeometry cornerRadius: anElement toTheme borderRadius). @@ -108,7 +96,19 @@ ToButtonType >> whenAddedToSpace: anEvent in: anElement fromSkin: aSkin [ ] { #category : #'api - install/uninstall hook' } -ToButtonType >> whenRemovedFromSpace: anEvent in: anElement fromSkin: aSkin [ +ToButtonType >> onSkinUninstalled: aSkin in: anElement [ ] + +{ #category : #'api - install/uninstall hook' } +ToButtonType >> regularFormLookIn: anElement [ + + self subclassResponsibility +] + +{ #category : #'api - install/uninstall hook' } +ToButtonType >> regularLabelLookIn: anElement [ + + self subclassResponsibility +] diff --git a/src/Toplo/ToCheckableSkin.class.st b/src/Toplo/ToCheckableSkin.class.st index 750966781..2d975d989 100644 --- a/src/Toplo/ToCheckableSkin.class.st +++ b/src/Toplo/ToCheckableSkin.class.st @@ -22,18 +22,10 @@ ToCheckableSkin >> indeterminateImageIn: anElement [ ^ self subclassResponsibility ] -{ #category : #accessing } -ToCheckableSkin >> uncheckedImageIn: anElement [ - - ^ self subclassResponsibility -] - { #category : #'api - install/uninstall hook' } -ToCheckableSkin >> whenAddedToSpace: anEvent in: anElement [ +ToCheckableSkin >> onSkinInstalledIn: anElement [ - super whenAddedToSpace: anEvent in: anElement. - anElement spacingWidth: - anElement toTheme paddingContentHorizontal / 2. + anElement spacingWidth: anElement toTheme paddingContentHorizontal / 2. anElement icon: (ToImage inner: (anElement isChecked ifTrue: [ self checkedImageIn: anElement ] ifFalse: [ self uncheckedImageIn: anElement ])). @@ -42,5 +34,12 @@ ToCheckableSkin >> whenAddedToSpace: anEvent in: anElement [ checkedImage: (self checkedImageIn: anElement); uncheckedImage: (self uncheckedImageIn: anElement); indeterminateImage: (self indeterminateImageIn: anElement); - yourself) + yourself). + super onSkinInstalledIn: anElement +] + +{ #category : #accessing } +ToCheckableSkin >> uncheckedImageIn: anElement [ + + ^ self subclassResponsibility ] diff --git a/src/Toplo/ToCheckboxImageSkin.class.st b/src/Toplo/ToCheckboxImageSkin.class.st index 45054e317..8c2c74d9a 100644 --- a/src/Toplo/ToCheckboxImageSkin.class.st +++ b/src/Toplo/ToCheckboxImageSkin.class.st @@ -5,7 +5,7 @@ Class { } { #category : #'api - install/uninstall hook' } -ToCheckboxImageSkin >> whenAddedToSpace: anEvent in: anElement [ +ToCheckboxImageSkin >> onSkinInstalledIn: anElement [ | borderLook | @@ -17,6 +17,6 @@ ToCheckboxImageSkin >> whenAddedToSpace: anEvent in: anElement [ width: 1. self addLook: borderLook. - super whenAddedToSpace: anEvent in: anElement. + super onSkinInstalledIn: anElement ] diff --git a/src/Toplo/ToElementSkinChangedEvent.class.st b/src/Toplo/ToElementSkinChangedEvent.class.st new file mode 100644 index 000000000..ee66a554f --- /dev/null +++ b/src/Toplo/ToElementSkinChangedEvent.class.st @@ -0,0 +1,11 @@ +Class { + #name : #ToElementSkinChangedEvent, + #superclass : #BlEvent, + #category : #'Toplo-Core-Theme' +} + +{ #category : #sending } +ToElementSkinChangedEvent >> sendTo: anObject [ + + anObject elementSkinChangedEvent: self +] diff --git a/src/Toplo/ToImage.class.st b/src/Toplo/ToImage.class.st index 9f9b977c7..93b872b94 100644 --- a/src/Toplo/ToImage.class.st +++ b/src/Toplo/ToImage.class.st @@ -41,11 +41,13 @@ ToImage >> hasInnerImage [ ToImage >> initialize [ super initialize. - + self fitContent. self innerImage: self defaultInnerImage. " I ** must be ** considered as a leaf of a UI element tree. Otherwise, click may not work on me. This is why my children are not allowed to manage mouse events. Related to https://github.com/plantec/Toplo/issues/41" self preventChildrenMouseEvents. + self whenInnerImageChangedDo: [ :new :prev | + self dispatchEvent: (ToInnerImageChangedEvent current: new previous: prev) ] ] { #category : #'form accessing' } @@ -75,7 +77,7 @@ ToImage >> innerImage: anImage [ ] { #category : #'api - change hook' } -ToImage >> whenInnerImageReplacedDo: aBlock [ +ToImage >> whenInnerImageChangedDo: aBlock [ "set a block to perform after that the image has been changed, and its action performed" diff --git a/src/Toplo/ToImageModel.class.st b/src/Toplo/ToImageModel.class.st index 7e25d069b..f3503eda0 100644 --- a/src/Toplo/ToImageModel.class.st +++ b/src/Toplo/ToImageModel.class.st @@ -17,9 +17,9 @@ ToImageModel >> privateWidgetClass [ ] { #category : #'api - change hook' } -ToImageModel >> whenInnerImageReplacedDo: aBlock [ +ToImageModel >> whenInnerImageChangedDo: aBlock [ "set a block to perform after that the image has been changed, and its action performed" - self widgetDo: [ :widget | widget whenInnerImageReplacedDo: aBlock ] + self widgetDo: [ :widget | widget whenInnerImageChangedDo: aBlock ] ] diff --git a/src/Toplo/ToInnerImageChangedEvent.class.st b/src/Toplo/ToInnerImageChangedEvent.class.st new file mode 100644 index 000000000..266831b3a --- /dev/null +++ b/src/Toplo/ToInnerImageChangedEvent.class.st @@ -0,0 +1,11 @@ +Class { + #name : #ToInnerImageChangedEvent, + #superclass : #ToElementPropertyChanged, + #category : #'Toplo-Widget-Image' +} + +{ #category : #sending } +ToInnerImageChangedEvent >> sendTo: anObject [ + + anObject innerImageChanged: self +] diff --git a/src/Toplo/ToLabelMultiLineInnerElement.class.st b/src/Toplo/ToLabelMultiLineInnerElement.class.st index d5aa0d72f..314b10845 100644 --- a/src/Toplo/ToLabelMultiLineInnerElement.class.st +++ b/src/Toplo/ToLabelMultiLineInnerElement.class.st @@ -1,6 +1,6 @@ Class { #name : #ToLabelMultiLineInnerElement, - #superclass : #BlElement, + #superclass : #ToElement, #traits : 'TToLabelInnerElement + TObservable + TBlLayoutResizable', #classTraits : 'TToLabelInnerElement classTrait + TObservable classTrait + TBlLayoutResizable classTrait', #instVars : [ diff --git a/src/Toplo/ToRadioImageSkin.class.st b/src/Toplo/ToRadioImageSkin.class.st index 82b7b04da..75ffd13ca 100644 --- a/src/Toplo/ToRadioImageSkin.class.st +++ b/src/Toplo/ToRadioImageSkin.class.st @@ -5,7 +5,7 @@ Class { } { #category : #'api - install/uninstall hook' } -ToRadioImageSkin >> whenAddedToSpace: anEvent in: anElement [ +ToRadioImageSkin >> onSkinInstalledIn: anElement [ | borderLook | @@ -17,6 +17,6 @@ ToRadioImageSkin >> whenAddedToSpace: anEvent in: anElement [ width: 1. self addLook: borderLook. - super whenAddedToSpace: anEvent in: anElement. + super onSkinInstalledIn: anElement ] diff --git a/src/Toplo/ToSandBox.class.st b/src/Toplo/ToSandBox.class.st index f0abe71e4..827cc4198 100644 --- a/src/Toplo/ToSandBox.class.st +++ b/src/Toplo/ToSandBox.class.st @@ -943,14 +943,14 @@ ToSandBox class >> example_ToButtonSkins [ space root layout: (BlLinearLayout vertical cellSpacing: 10). - "themeSwitcher := ToChoiceBox new. + themeSwitcher := ToChoiceBox new. themeSwitcher data addAll: { ToThemeLight. ToThemeDark }. themeSwitcher whenSelectedIndexChangedDo: [ space toTheme: themeSwitcher selectedData new ]. themeSwitcher selectData: space toTheme class. - space root addChild: themeSwitcher." + space root addChild: themeSwitcher. -space switchThemeDarkOrLight. +"space switchThemeDarkOrLight." butBuilder := [ ToImage new innerImage: ToThemeIcons iconSearchOutlined16x16 ]. buttonSpecsBuilder := [ { @@ -1115,8 +1115,9 @@ ToSandBox class >> example_ToButtonWithPrimarySkin [ space root addChild: button1. space root when: BlElementAddedToSceneGraphEvent do: [ button1 labelText: 'Primary button 3'. - button1 iconImage: (ToThemeIcons iconSearchOutlined16x16) ]. + button1 icon: (ToImage inner: (ToThemeIcons iconSearchOutlined16x16)) ]. space show. + ] { #category : #button } diff --git a/src/Toplo/ToToggleSkin.class.st b/src/Toplo/ToToggleSkin.class.st index e2d5b9028..1c07b2cdc 100644 --- a/src/Toplo/ToToggleSkin.class.st +++ b/src/Toplo/ToToggleSkin.class.st @@ -32,6 +32,20 @@ ToToggleSkin >> buttonLabelChanged: anEvent [ ] +{ #category : #'api - install/uninstall hook' } +ToToggleSkin >> onSkinInstalledIn: anElement [ + + anElement spacingWidth: anElement toTheme paddingContentHorizontal / 2. + anElement geometry: (BlRoundedRectangleGeometry cornerRadius: (self trackBorderRadiusIn: anElement)). + anElement padding: (BlInsets + top: anElement toTheme paddingXS / 2 + left: anElement toTheme paddingContentHorizontal + bottom: anElement toTheme paddingXS / 2 + right: anElement toTheme paddingContentHorizontal). + self setupTrackElementIn: anElement. + super onSkinInstalledIn: anElement +] + { #category : #'api - install/uninstall hook' } ToToggleSkin >> setupTrackElementIn: anElement [ @@ -58,17 +72,3 @@ ToToggleSkin >> trackBorderRadiusIn: anElement [ ^ 26 ] - -{ #category : #'api - install/uninstall hook' } -ToToggleSkin >> whenAddedToSpace: anEvent in: anElement [ - - anElement spacingWidth: anElement toTheme paddingContentHorizontal / 2. - anElement geometry: (BlRoundedRectangleGeometry cornerRadius: (self trackBorderRadiusIn: anElement)). - anElement padding: (BlInsets - top: anElement toTheme paddingXS / 2 - left: anElement toTheme paddingContentHorizontal - bottom: anElement toTheme paddingXS / 2 - right: anElement toTheme paddingContentHorizontal). - self setupTrackElementIn: anElement. - super whenAddedToSpace: anEvent in: anElement -] diff --git a/src/Toplo/ToToggleTrackSkin.class.st b/src/Toplo/ToToggleTrackSkin.class.st index 32c9d862f..1949a90b4 100644 --- a/src/Toplo/ToToggleTrackSkin.class.st +++ b/src/Toplo/ToToggleTrackSkin.class.st @@ -7,14 +7,8 @@ Class { #category : #'Toplo-Widget-Button-Toggle-Skins' } -{ #category : #accessing } -ToToggleTrackSkin >> toggleButton: aToggleButton [ - - toggleButton := aToggleButton -] - { #category : #'api - install/uninstall hook' } -ToToggleTrackSkin >> whenAddedToSpace: anEvent in: anElement [ +ToToggleTrackSkin >> onSkinInstalledIn: anElement [ toggleButton := anElement parent. self addLook: (ToBackgroundLook new @@ -35,5 +29,11 @@ ToToggleTrackSkin >> whenAddedToSpace: anEvent in: anElement [ animate: true; toggleButton: toggleButton; yourself). - super whenAddedToSpace: anEvent in: anElement + super onSkinInstalledIn: anElement +] + +{ #category : #accessing } +ToToggleTrackSkin >> toggleButton: aToggleButton [ + + toggleButton := aToggleButton ] diff --git a/src/Toplo/ToWidgetSkin.class.st b/src/Toplo/ToWidgetSkin.class.st index a42c2ea9f..8004a4a2f 100644 --- a/src/Toplo/ToWidgetSkin.class.st +++ b/src/Toplo/ToWidgetSkin.class.st @@ -2,7 +2,6 @@ Class { #name : #ToWidgetSkin, #superclass : #BlCustomEventHandler, #instVars : [ - 'addedToSpace', 'look' ], #category : #'Toplo-Core-Theme' @@ -16,18 +15,10 @@ ToWidgetSkin >> addLook: aLook [ self privateLook: aLook ] -{ #category : #accessing } -ToWidgetSkin >> addedToSpace [ - - ^ addedToSpace -] - -{ #category : #'event handling' } +{ #category : #'as yet unclassified' } ToWidgetSkin >> elementAddedToSceneGraphEvent: anEvent [ - addedToSpace ifTrue: [ ^ self ]. - self whenAddedToSpace: anEvent in: anEvent currentTarget. - addedToSpace := true + self whenAddedToSpace: anEvent in: anEvent currentTarget ] { #category : #'event handling' } @@ -36,25 +27,22 @@ ToWidgetSkin >> elementLookEvent: anEvent [ anEvent sendTo: self look ] -{ #category : #'event handling' } +{ #category : #'as yet unclassified' } ToWidgetSkin >> elementRemovedFromSceneGraphEvent: anEvent [ - addedToSpace ifFalse: [ ^ self ]. - self whenRemovedFromSpace: anEvent in: anEvent currentTarget. - addedToSpace := false + self whenRemovedFromSpace: anEvent in: anEvent currentTarget ] -{ #category : #'api - accessing' } -ToWidgetSkin >> eventsToHandle [ +{ #category : #'event handling' } +ToWidgetSkin >> elementSkinChangedEvent: anEvent [ - ^ { BlElementAddedToSceneGraphEvent. BlElementRemovedFromSceneGraphEvent. ToElementLookEvent } + ] -{ #category : #initialization } -ToWidgetSkin >> initialize [ +{ #category : #'api - accessing' } +ToWidgetSkin >> eventsToHandle [ - super initialize. - addedToSpace := false. + ^ { BlElementAddedToSceneGraphEvent. BlElementRemovedFromSceneGraphEvent . ToElementLookEvent } ] { #category : #accessing } @@ -68,10 +56,20 @@ ToWidgetSkin >> onInstalledIn: anElement [ super onInstalledIn: anElement. self privateLook: ToNullElementLook new. - addedToSpace := anElement isAttachedToSceneGraph. - addedToSpace - ifTrue: [ self whenAddedToSpace: nil in: anElement ] - ifFalse: [ self whenRemovedFromSpace: nil in: anElement ] + + +] + +{ #category : #'api - install/uninstall hook' } +ToWidgetSkin >> onSkinInstalledIn: anElement [ + + +] + +{ #category : #'api - install/uninstall hook' } +ToWidgetSkin >> onSkinUninstalledIn: anElement [ + + ] { #category : #'api - install/uninstall hook' } @@ -98,20 +96,24 @@ ToWidgetSkin >> removeLook: aLook [ { #category : #'event handling' } ToWidgetSkin >> themeChangedEvent: anEvent [ - self whenRemovedFromSpace: anEvent in: anEvent currentTarget. - self whenAddedToSpace: anEvent in: anEvent currentTarget + self onSkinUninstalledIn: anEvent currentTarget. + self onSkinInstalledIn: anEvent currentTarget. + anEvent currentTarget dispatchLookEvent: ToInstallLookEvent new. + anEvent currentTarget whenLayoutedDoOnce: [ anEvent currentTarget switchToState: ToInitialState new ] ] { #category : #'api - install/uninstall hook' } ToWidgetSkin >> whenAddedToSpace: anEvent in: anElement [ - anElement whenLayoutedDoOnce: [ - anElement dispatchLookEvent: (ToInstallLookEvent new copyFrom: anEvent). - anElement dispatchLookEvent: ((ToElementStateChangedEvent new state: ToInitialState new) copyFrom: anEvent) ] + self onSkinInstalledIn: anElement. + anElement dispatchLookEvent: ToInstallLookEvent new. + anElement whenLayoutedDoOnce: [ anElement switchToState: ToInitialState new ] ] { #category : #'api - install/uninstall hook' } ToWidgetSkin >> whenRemovedFromSpace: anEvent in: anElement [ - anElement dispatchLookEvent: (ToUninstallLookEvent new copyFrom: anEvent) + anElement dispatchLookEvent: ToUninstallLookEvent new. + self onSkinUninstalledIn: anElement. + ] diff --git a/src/Toplo/ToWindowElement.class.st b/src/Toplo/ToWindowElement.class.st index 0e02b41f4..da2162a1c 100644 --- a/src/Toplo/ToWindowElement.class.st +++ b/src/Toplo/ToWindowElement.class.st @@ -85,6 +85,7 @@ ToWindowElement >> initialize [ geometry: self defaultGeometry; clipChildren: false; fitContent. + self constraintsDo: [ :c | c ignoreByLayout ]. self addChildren: self elements. ]