Supposing I have a domain model, Activity, which looks like this:
Object subclass: #Activity instanceVariableNames: 'title cost' classVariableNames: '' category: 'PERT' Then I have the expected accessors for title and cost. I make a Polymorph dialog for editing one of these things like so: PolymorphEditActivity>>edit: anActivity | builder content dialog | activity := anActivity. builder := Smalltalk ui theme builder. content := builder newLabelGroup: { 'Title' -> (builder newTextEntryFor: self activity getText: #title setText: #title: help: 'The title of the activity'). 'Cost' -> (builder newTextEntryFor: self activity getText: #cost setText: #cost: help: 'The cost of the activity') }. dialog := builder newPluggableDialogWindow: 'Edit activity' for: content. ^ builder openModal: dialog. *First question*: how do I return a value from the dialog? Now the Spec version of this I have looks like this: ComposableModel subclass: #SpecEditActivity instanceVariableNames: 'activity titleLabel costLabel titleWidget costWidget' classVariableNames: '' category: 'PERT' SpecEditActivity>>initializeWidgets "Set up the widgets for the dialog" titleWidget := self newTextInput. titleLabel := self newLabel. costWidget := self newTextInput. costLabel := self newLabel. titleLabel label: 'Title:'. costLabel label: 'Cost:'. self focusOrder add: titleWidget; add: costWidget SpecEditActivity>>initializePresenter super initializePresenter. titleWidget whenTextChanged: [ :newText | activity title: newText ]. costWidget whenTextChanged: [ :newCost | activity cost: newCost ] Then on the class side of things, I have this layout: SpecEditActivity class>>layout <spec> ^ SpecLayout composed newColumn: [ :column | column newRow: [ :row | row add: #titleLabel; add: #titleWidget ]; newRow: [ :row | row add: #costLabel; add: #costWidget ] ]; yourself I make all the expected "getter" methods. I can see how to get the model value out: I do something like this: activityDialog := SpecEditActivity new openDialogWithSpec; yourself. activityDialog model activity I have two questions about the Spec side of the house: 1. The title/costWidget whenTextChanged: stuff. With Polymorph, I can just say, here's an object, here's the getter/setter, deal with it. Does Spec have anything like this, or do you have to do this manual data shuffling? Is there an example I can learn from? 2. This layout is a bit on the ugly side. I looked at the examples and saw usage of the expert layout with asking how tall a line is. Is that the best that can be done, or is there something more like Polymorph's label layout that can be used instead? Thanks for your time and patience! — Daniel Lyons |
2014-12-20 5:49 GMT+01:00 Daniel Lyons <[hidden email]>: Supposing I have a domain model, Activity, which looks like this: You don't need the return something, you don't even need to use a separate instvar in the PolymorphEditActivity. If "anActivity" is a Activity with the accessor #title / #title: #cost/#cost:, the PluggableDialogWindow will change this attributes only if the dialog is closed with "OK" | anActivity builder content dialog | anActivity := Activity new. anActivity title: 'what'. anActivity cost: '100'. builder := Smalltalk ui theme builder. content := builder newLabelGroup: {('Title' -> (builder newTextEntryFor: anActivity getText: #title setText: #title: help: 'The title of the activity')). ('Cost' -> (builder newTextEntryFor: anActivity getText: #cost setText: #cost: help: 'The cost of the activity'))}. dialog := builder newPluggableDialogWindow: 'Edit activity' for: content. builder openModal: dialog. anActivity inspect |
In reply to this post by Daniel Lyons
The spec part of your question:
2014-12-20 5:49 GMT+01:00 Daniel Lyons <[hidden email]>: Supposing I have a domain model, Activity, which looks like this: First, please don't add a method #layout on the class side, this conflicts with the notion of "Slots" (bug reported, but it is not fixed yet)
If you just want to show an edit dialog, I would separate the Acitivty-Model (two textfields) from your domain model "Activity". Then you don't need this "whenTextChanged". This is only needed if other elements from the model depend on the textfield content. Now you can use spec to only show a dialog and after closing this dialog you can retrieve the values with activitiy title: theDialogModel titleWidget text activity cost: theDialogModel costWidget text ....
you can define the hight of the rows based on the inputfield default height (based on the current theme) (ComposableModel class >>#defaultInputHeight Take a look at Komitters CredentialEditor
|
Don't add a method to do the layout or don't name it #layout? The tutorial doesn't say what to name the method, just that it can be named anything using the pragma.
OK, but two questions: 1. How do I know when the dialog is finished? 2. That's going to be a lot of manual copying compared to the Polymorph version. Is that just life or are there "pluggable" widgets that will talk to my model directly?
Thanks!
—
Daniel Lyons |
dont name it layout.
|
Free forum by Nabble | Edit this page |