Few questions about Spec (instance specific layout and skinning)
Hi ! First, I apologyse for the wall of text. I'm trying my hands at Spec and I have few questions: - How can I implement an instance-dependent layout ? Regarding the layout method lookup, the documentation states that it "starts on instance side, which allows a UI to have a more specific layout depending on the state of the instance" I tried to simply put a layout in an instance method with the *<spec: #default>* pragma. But not only was it not retrieved by *ComposableModel>#defaultSpecSelector* but *ComposableModel>#retrieveSpec:*will send the selector on the class anyway. What I ended up doing was overiding #openWithSpec (which worked) but I'm pretty sure that my model is not composable at all. - Is it possible to change the "skin" of the basic widget ? I would like to implement some sort of toggle button by changing the color of ButtonModel and so far, I failed. I was not able to trace my color change up to the PluggableButtonMorph because it seems to use anoucement and I'm a Smalltalk rookie. I tried however to send #color: directly to the morph which does nothing: the #changed method rolls it back to its previous value. So I may be doing something wrong but it doesn't feel like the issue comes from Spec. Any clue ? - On a side note, I tried to send an argument to the selector that retrieve a widget in the layout method. And I came up with this : layout *add:* {#buttonAt: . 1}; *add:* {#buttonAt: . 2}; *add:* {#buttonAt: . 3} Is it how it's done ? Thanks in advance ! Thomas.
On 02 Apr 2014, at 12:10, Thomas Bany <mun.sysdev@gmail.com> wrote:
Hi !
First, I apologyse for the wall of text.
I'm trying my hands at Spec and I have few questions: How can I implement an instance-dependent layout ? The usual solution is to have a method looking like this on instance side
rebuildMyLayout | layout | layout := self buildStateDependentLayout. self buildWithLayout: layout. buildStateDependentLayout ^ SpecLayout composed etc...
Regarding the layout method lookup, the documentation states that it "starts on instance side, which allows a UI to have a more specific layout depending on the state of the instance"
I tried to simply put a layout in an instance method with the <spec: #default> pragma. But not only was it not retrieved by ComposableModel>#defaultSpecSelector but ComposableModel>#retrieveSpec: will send the selector on the class anyway.
What I ended up doing was overiding #openWithSpec (which worked) but I'm pretty sure that my model is not composable at all.
Indeed, overriding openWithSpec may be a bit hackish, but should still work :) Another solution could be to override defaultSpecSelector and/or retrieveSpec:
Is it possible to change the "skin" of the basic widget ? The hooks are basically here, but the Morphs have an issue with this. The âskinâ of a Morph is supposed to be immutable, hence it takes back its default value at each refresh :S
I would like to implement some sort of toggle button by changing the color of ButtonModel and so far, I failed. I was not able to trace my color change up to the PluggableButtonMorph because it seems to use anoucement and I'm a Smalltalk rookie.
I tried however to send #color: directly to the morph which does nothing: the #changed method rolls it back to its previous value. So I may be doing something wrong but it doesn't feel like the issue comes from Spec. Any clue ?
So far, it will not work, sorry :(
On a side note, I tried to send an argument to the selector that retrieve a widget in the layout method. And I came up with this :
layout add: {#buttonAt: . 1}; add: {#buttonAt: . 2}; add: {#buttonAt: . 3}
Is it how it's done ?
Thatâs a solution. Then if you have a fixed number of buttons, you could also implement a getter for each. If you have an undetermined number of button, then DynamicComposableModel is for you.
Thanks in advance !
You are welcome :) Ben
The usual solution is to have a method looking like this on instance side
rebuildMyLayout
| layout | layout := self buildStateDependentLayout. self buildWithLayout: layout.
buildStateDependentLayout ^ SpecLayout composed etc...
I will defenitly look into that. The "rebuild" may be missleading, is it also called at first building ? The hooks are basically here, but the Morphs have an issue with this.
The "skin" of a Morph is supposed to be immutable, hence it takes back its default value at each refresh :S
Well, I can't even manage to tweak it through hardcoding stuff on the adapter :p Do you think it would be hard to use a SimpleSwitchMorph ? As I understood, there is #asSpecAdapter that permis to plug pretty much everything ? Plus, making a specific adapter seems doable (I mean for a rookie like me).
That's a solution. Then if you have a fixed number of buttons, you could also implement a getter for each.
If you have an undetermined number of button, then DynamicComposableModel is for you.
Well, I definitely have a variable number of buttons, depending on the model instance. Actualy, I want my model to be a matrix of toggle to specify a mask. I create instance with: MaskModel class>#maxIndex: anInteger ^(self basicNew) maxIndex: anInteger; initialize; yourself and instantiate a collection of buttons in #initializeWidgets. It doesn't change much after that so a DynamicComposableModel didn't seem usefull. But I only though that because I never used it. I will give it a try. Anyway, thanks again for your time ! Thomas.
On 03 Apr 2014, at 12:50, Thomas Bany <mun.sysdev@gmail.com> wrote:
I will defenitly look into that. The "rebuild" may be missleading, is it also called at first building ?
Thatâs your own ,method, call it as/when you want
Well, I can't even manage to tweak it through hardcoding stuff on the adapter :p
Yes, itâs hardcoded in the morph themselves
Do you think it would be hard to use a SimpleSwitchMorph ? As I understood, there is #asSpecAdapter that permis to plug pretty much everything ? Plus, making a specific adapter seems doable (I mean for a rookie like me).
Thatâs definitely a solution :)
Well, I definitely have a variable number of buttons, depending on the model instance. Actualy, I want my model to be a matrix of toggle to specify a mask. I create instance with:
MaskModel class>#maxIndex: anInteger ^(self basicNew) maxIndex: anInteger; initialize; yourself
and instantiate a collection of buttons in #initializeWidgets.
It doesn't change much after that so a DynamicComposableModel didn't seem usefull. But I only though that because I never used it. I will give it a try.
In DynamicComposableModel, when you instantiate a model using #instantiateModels: it simulates accessors for you. By example, if you do 1 to: 120 random do: [ :i | self instantiateModels: { (âbâ, i asString) asSymbol . #ButtonModel } Then your layout can be ^ SpecLayout composed add: #b1; add: #b2; etc Ben
Hey, I have a quick question. I'm trying to build an adapter (called MorphicSwitchAdapter) and a model for SimpleSwitchMorp. I based my layout on the ones in existing adapter (namely MorphicButtonAdapter). And I get stuck in an infinite loop during the interpretation of the layout of the adapter. The first lines are: ^ {#SimpleSwitchMorph. #onColor:. #(model onColor). #offColor:. #(model #offColor) etc... At some point, it tries to interpret #(#model #offColor)) and a few step latter, it comes back to step one and tries to interpret #(#MorphicSwitchAdapter #adapt: #model). I tried this alternative {#model. #onColor} (though this one is equivalent to me) and this one #model. #onColor. but to no avail. I have a feeling that the problem stems from the fact that PluggableButtonMorph seems to allready be an adapter which take a model while SimpleSwitchMorp does not. Could you throw some light as to why the interpretation fails ? Again, thanks for your help ! Thomas.
Hum, I was pondering the problem at home and started from scratch. I don't have the issue anymore ... 2014-04-03 18:40 GMT+02:00 Thomas Bany <mun.sysdev@gmail.com>:
Hey,
I have a quick question. I'm trying to build an adapter (called MorphicSwitchAdapter) and a model for SimpleSwitchMorp. I based my layout on the ones in existing adapter (namely MorphicButtonAdapter).
And I get stuck in an infinite loop during the interpretation of the layout of the adapter.
The first lines are:
^ {#SimpleSwitchMorph. #onColor:. #(model onColor). #offColor:. #(model #offColor) etc...
At some point, it tries to interpret #(#model #offColor)) and a few step latter, it comes back to step one and tries to interpret #(#MorphicSwitchAdapter #adapt: #model).
I tried this alternative {#model. #onColor} (though this one is equivalent to me) and this one #model. #onColor. but to no avail.
I have a feeling that the problem stems from the fact that PluggableButtonMorph seems to allready be an adapter which take a model while SimpleSwitchMorp does not.
Could you throw some light as to why the interpretation fails ?
Again, thanks for your help !
Thomas.
Okey so I looked deeper into the interpreter and found that the receiver of the next call is the returned value of the previous. I'm pretty sure it explains the infinite loop I was encountering. It also made it problematic to register the morph to the anouncement of the adapter, since #addDependent: is send with a morph to the model and I needed the other way arround. Adding #beDependentTo: somewhere in the class hierarchy of SimpleSwitchMorph make it work but I'm not sure I should do that. 2014-04-03 20:37 GMT+02:00 Thomas Bany <mun.sysdev@gmail.com>:
Hum, I was pondering the problem at home and started from scratch. I don't have the issue anymore ...
2014-04-03 18:40 GMT+02:00 Thomas Bany <mun.sysdev@gmail.com>:
Hey,
I have a quick question. I'm trying to build an adapter (called MorphicSwitchAdapter) and a model for SimpleSwitchMorp. I based my layout on the ones in existing adapter (namely MorphicButtonAdapter).
And I get stuck in an infinite loop during the interpretation of the layout of the adapter.
The first lines are:
^ {#SimpleSwitchMorph. #onColor:. #(model onColor). #offColor:. #(model #offColor) etc...
At some point, it tries to interpret #(#model #offColor)) and a few step latter, it comes back to step one and tries to interpret #(#MorphicSwitchAdapter #adapt: #model).
I tried this alternative {#model. #onColor} (though this one is equivalent to me) and this one #model. #onColor. but to no avail.
I have a feeling that the problem stems from the fact that PluggableButtonMorph seems to allready be an adapter which take a model while SimpleSwitchMorp does not.
Could you throw some light as to why the interpretation fails ?
Again, thanks for your help !
Thomas.
If you need it the other way around, then instead of calling it in the layout, there is a method on adapter named #buildWidget (or something close) which is the perfect place for this :) Ben On 04 Apr 2014, at 01:53, Thomas Bany <mun.sysdev@gmail.com> wrote:
Okey so I looked deeper into the interpreter and found that the receiver of the next call is the returned value of the previous. I'm pretty sure it explains the infinite loop I was encountering.
It also made it problematic to register the morph to the anouncement of the adapter, since #addDependent: is send with a morph to the model and I needed the other way arround.
Adding #beDependentTo: somewhere in the class hierarchy of SimpleSwitchMorph make it work but I'm not sure I should do that.
2014-04-03 20:37 GMT+02:00 Thomas Bany <mun.sysdev@gmail.com>: Hum, I was pondering the problem at home and started from scratch. I don't have the issue anymore ...
2014-04-03 18:40 GMT+02:00 Thomas Bany <mun.sysdev@gmail.com>:
Hey,
I have a quick question. I'm trying to build an adapter (called MorphicSwitchAdapter) and a model for SimpleSwitchMorp. I based my layout on the ones in existing adapter (namely MorphicButtonAdapter).
And I get stuck in an infinite loop during the interpretation of the layout of the adapter.
The first lines are:
^ {#SimpleSwitchMorph. #onColor:. #(model onColor). #offColor:. #(model #offColor) etc...
At some point, it tries to interpret #(#model #offColor)) and a few step latter, it comes back to step one and tries to interpret #(#MorphicSwitchAdapter #adapt: #model).
I tried this alternative {#model. #onColor} (though this one is equivalent to me) and this one #model. #onColor. but to no avail.
I have a feeling that the problem stems from the fact that PluggableButtonMorph seems to allready be an adapter which take a model while SimpleSwitchMorp does not.
Could you throw some light as to why the interpretation fails ?
Again, thanks for your help !
Thomas.
participants (2)
-
Benjamin -
Thomas Bany