Hi
I'm trying to build a dynamic ui (UI without a #windowSpec). I saw that this is possible for Dialogs (Example: SimpleDialog>>choose:labels:values:default:equalize:for:) My first solution was to subclass SimpleDialog. This works basically but there are two problems: 1. Since I'm subclassing SimpleDialog my window blocks the whole environment until I close my window 2. When you execute the following code you will notice that you can't close the dialog with the "x" in the title bar (You can only close the dialog by clicking a button) SimpleDialog new choose: 'Are you completely sure?' labels: (Array with: 'definitely' with: 'sort of no' with: 'sort of yes' with: 'nope') values: #(#yes #maybeNo #maybeYes #no) default: #no equalize: false for: Dialog defaultParentWindow Does anybody know how I can solve problem 1 + 2? I guess subclassing ApplicationModel would be an idea but I haven't got a clue which methods I would have to change. Cheers, michael |
Michael
There are a few techniques to building a dynamic UI. I suggest you describe what you really want to do and someone will point you the way. Terry =========================================================== Terry Raymond Smalltalk Professional Debug Package Crafted Smalltalk 80 Lazywood Ln. Tiverton, RI 02878 (401) 624-4517 [hidden email] <http://www.craftedsmalltalk.com> =========================================================== > -----Original Message----- > From: Michael Meyer [mailto:[hidden email]] > Sent: Thursday, March 30, 2006 12:22 PM > To: [hidden email] > Subject: Build a ui at runtime without using a #windowSpec > > Hi > I'm trying to build a dynamic ui (UI without a #windowSpec). I saw that > this is possible for > Dialogs (Example: > SimpleDialog>>choose:labels:values:default:equalize:for:) > > My first solution was to subclass SimpleDialog. This works basically but > there > are two problems: > > 1. Since I'm subclassing SimpleDialog my window blocks the whole > environment until > I close my window > > 2. When you execute the following code you will notice that you can't > close the > dialog with the "x" in the title bar (You can only close the dialog by > clicking a button) > > SimpleDialog new > choose: 'Are you completely sure?' > labels: (Array with: 'definitely' with: 'sort of no' with: 'sort of > yes' with: 'nope') > values: #(#yes #maybeNo #maybeYes #no) > default: #no > equalize: false > for: Dialog defaultParentWindow > > Does anybody know how I can solve problem 1 + 2? I guess subclassing > ApplicationModel would > be an idea but I haven't got a clue which methods I would have to change. > > Cheers, michael > |
In reply to this post by Michael Meyer-6
A similar question was asked in comp.lang.smalltalk last month:
http://groups.google.com/group/comp.lang.smalltalk/browse_frm/thread/ae1 92d2a94056e8b/38d1911f80caa3ff?lnk=st&q=group%3Acomp.lang.smalltalk+wind owSpec+Steve&rnum=1&hl=fi#38d1911f80caa3ff I wouldn't recommend looking at Pollock yet, since it's only in preview (pre-beta), major changes are still happening there, and there are far more people who can help you with the current Wrapper framework. To provide some background to David Buck's comments in the thread, you can simply supply your own FullSpec via your own #interfaceSpecFor: method. Follow the method through in a debugger, and you'll see a normal window starts life as a literal array returned by #windowSpec. #specificationFor: returns that array, and #interfaceSpecFor: turns it into a FullSpec (which has a WindowSpec for the actual window bit, plus the main contents as parts of a SpecCollection). #allButOpenInterface:* then handles the rest: the WindowSpec part is dealt with with a call to #hookUpWindow:spec:builder:, and the main content of the spec is dealt with in a simple "builder add: spec". In addition to adding the components to the builder, the add: does the main work of actually creating all the various Views to correspond to the Specs supplied. There are thus four different forms in which you can programmatically build your window: 1) literal array, as found in #windowSpec methods, corresponding to the structure in 2) 2) FullSpec containing WindowSpec and SpecCollection, the latter containing the actual WidgetSpecs of the widgets you want 3) Do what SimpleDialog does: Override the normal building mechanism to start with a skeleton windowSpec, build that bit as normal, then add new WidgetSpecs to the builder bit by bit. Finally, call the remaining bits of the normal building and opening mechanism. 4) "just" build the actual Views etc. programmatically I'd steer clear of 4! It bypasses the ability of UIBuilder to make appropriate platform-specific Views from the generic WidgetSpecs. If you choose 1), override #specificationFor: in your subclass to return that array. If you choose 2), override #interfaceSpecFor: to return your FullSpec. If you choose 3), override #openInterface:withPolicy:inSession:, and add your own widgets to the builder after "builder add: spec". Again, the best advice is just to debug opening a normal window, e.g. "Workspace open", and step through the messages to see how the symbol #windowSpec gets turned into an array, then a FullSpec, then via the builder and UI & widget policy into Views. HTH, Steve > -----Original Message----- > From: Michael Meyer [mailto:[hidden email]] > Sent: 30 March 2006 20:22 > To: [hidden email] > Subject: Build a ui at runtime without using a #windowSpec > > Hi > I'm trying to build a dynamic ui (UI without a #windowSpec). I saw that > this is possible for > Dialogs (Example: > SimpleDialog>>choose:labels:values:default:equalize:for:) > > My first solution was to subclass SimpleDialog. This works basically but > there > are two problems: > > 1. Since I'm subclassing SimpleDialog my window blocks the whole > environment until > I close my window > > 2. When you execute the following code you will notice that you can't > close the > dialog with the "x" in the title bar (You can only close the dialog by > clicking a button) > > SimpleDialog new > choose: 'Are you completely sure?' > labels: (Array with: 'definitely' with: 'sort of no' with: 'sort > yes' with: 'nope') > values: #(#yes #maybeNo #maybeYes #no) > default: #no > equalize: false > for: Dialog defaultParentWindow > > Does anybody know how I can solve problem 1 + 2? I guess subclassing > ApplicationModel would > be an idea but I haven't got a clue which methods I would have to change. > > Cheers, michael > > |
Thanks a lot for that huge reply. The whole dynamic ui thing seems a
lot less scary now :-) Cheers, michael Steven Kelly schrieb: > A similar question was asked in comp.lang.smalltalk last month: > > http://groups.google.com/group/comp.lang.smalltalk/browse_frm/thread/ae1 > 92d2a94056e8b/38d1911f80caa3ff?lnk=st&q=group%3Acomp.lang.smalltalk+wind > owSpec+Steve&rnum=1&hl=fi#38d1911f80caa3ff > > I wouldn't recommend looking at Pollock yet, since it's only in preview > (pre-beta), major changes are still happening there, and there are far > more people who can help you with the current Wrapper framework. > > To provide some background to David Buck's comments in the thread, you > can simply supply your own FullSpec via your own #interfaceSpecFor: > method. Follow the method through in a debugger, and you'll see a normal > window starts life as a literal array returned by #windowSpec. > #specificationFor: returns that array, and #interfaceSpecFor: turns it > into a FullSpec (which has a WindowSpec for the actual window bit, plus > the main contents as parts of a SpecCollection). > > #allButOpenInterface:* then handles the rest: the WindowSpec part is > dealt with with a call to #hookUpWindow:spec:builder:, and the main > content of the spec is dealt with in a simple "builder add: spec". In > addition to adding the components to the builder, the add: does the main > work of actually creating all the various Views to correspond to the > Specs supplied. > > There are thus four different forms in which you can programmatically > build your window: > 1) literal array, as found in #windowSpec methods, corresponding to the > structure in 2) > 2) FullSpec containing WindowSpec and SpecCollection, the latter > containing the actual WidgetSpecs of the widgets you want > 3) Do what SimpleDialog does: Override the normal building mechanism to > start with a skeleton windowSpec, build that bit as normal, then add new > WidgetSpecs to the builder bit by bit. Finally, call the remaining bits > of the normal building and opening mechanism. > 4) "just" build the actual Views etc. programmatically > > I'd steer clear of 4! It bypasses the ability of UIBuilder to make > appropriate platform-specific Views from the generic WidgetSpecs. If you > choose 1), override #specificationFor: in your subclass to return that > array. If you choose 2), override #interfaceSpecFor: to return your > FullSpec. If you choose 3), override > #openInterface:withPolicy:inSession:, and add your own widgets to the > builder after "builder add: spec". > > Again, the best advice is just to debug opening a normal window, e.g. > "Workspace open", and step through the messages to see how the symbol > #windowSpec gets turned into an array, then a FullSpec, then via the > builder and UI & widget policy into Views. > > HTH, > Steve > >> -----Original Message----- >> From: Michael Meyer [mailto:[hidden email]] >> Sent: 30 March 2006 20:22 >> To: [hidden email] >> Subject: Build a ui at runtime without using a #windowSpec >> >> Hi >> I'm trying to build a dynamic ui (UI without a #windowSpec). I saw > that >> this is possible for >> Dialogs (Example: >> SimpleDialog>>choose:labels:values:default:equalize:for:) >> >> My first solution was to subclass SimpleDialog. This works basically > but >> there >> are two problems: >> >> 1. Since I'm subclassing SimpleDialog my window blocks the whole >> environment until >> I close my window >> >> 2. When you execute the following code you will notice that you can't >> close the >> dialog with the "x" in the title bar (You can only close the dialog by >> clicking a button) >> >> SimpleDialog new >> choose: 'Are you completely sure?' >> labels: (Array with: 'definitely' with: 'sort of no' with: 'sort > of >> yes' with: 'nope') >> values: #(#yes #maybeNo #maybeYes #no) >> default: #no >> equalize: false >> for: Dialog defaultParentWindow >> >> Does anybody know how I can solve problem 1 + 2? I guess subclassing >> ApplicationModel would >> be an idea but I haven't got a clue which methods I would have to > change. >> Cheers, michael >> >> > > |
Michael Meyer wrote:
> Thanks a lot for that huge reply. The whole dynamic ui thing seems a > lot less scary now :-) > My experience is that option 2 suggested by Steven is dead-easy, I advise you to start with that one if the standard widgets give you the capabilities you need. It helps a lot to mock up an example UI with the UIPainter, so you can study the generated windowSpec literal array for the messages you need to send to configure your Spec instances. R - |
In reply to this post by Michael Meyer-6
Michael
Depending on how complex the requirements for your view are you can also work of the Settings Framework. Check out SettingsDomain and SettingsManager. This framework is the one that displays the VW system settings. It lets you provide a specification for a domain model and will then dynamically build a GUI for it. As a bonus it will even persist you data to an XML file. The framework takes a bit of study but once you get your head around it its quite easy to re-use. Joerg ----- > -----Original Message----- > From: Michael Meyer [mailto:[hidden email]] > Sent: Thursday, March 30, 2006 12:10 PM > To: [hidden email] > Subject: Re: Build a ui at runtime without using a #windowSpec > > Thanks a lot for that huge reply. The whole dynamic ui thing seems a > lot less scary now :-) > > Cheers, michael > > Steven Kelly schrieb: > > A similar question was asked in comp.lang.smalltalk last month: > > > > > > 92d2a94056e8b/38d1911f80caa3ff?lnk=st&q=group%3Acomp.lang.smalltalk+wind > > owSpec+Steve&rnum=1&hl=fi#38d1911f80caa3ff > > > > I wouldn't recommend looking at Pollock yet, since it's only in preview > > (pre-beta), major changes are still happening there, and there are far > > more people who can help you with the current Wrapper framework. > > > > To provide some background to David Buck's comments in the thread, you > > can simply supply your own FullSpec via your own #interfaceSpecFor: > > method. Follow the method through in a debugger, and you'll see a normal > > window starts life as a literal array returned by #windowSpec. > > #specificationFor: returns that array, and #interfaceSpecFor: turns it > > into a FullSpec (which has a WindowSpec for the actual window bit, plus > > the main contents as parts of a SpecCollection). > > > > #allButOpenInterface:* then handles the rest: the WindowSpec part is > > dealt with with a call to #hookUpWindow:spec:builder:, and the main > > content of the spec is dealt with in a simple "builder add: spec". In > > addition to adding the components to the builder, the add: does the main > > work of actually creating all the various Views to correspond to the > > Specs supplied. > > > > There are thus four different forms in which you can programmatically > > build your window: > > 1) literal array, as found in #windowSpec methods, corresponding to the > > structure in 2) > > 2) FullSpec containing WindowSpec and SpecCollection, the latter > > containing the actual WidgetSpecs of the widgets you want > > 3) Do what SimpleDialog does: Override the normal building mechanism to > > start with a skeleton windowSpec, build that bit as normal, then add new > > WidgetSpecs to the builder bit by bit. Finally, call the remaining bits > > of the normal building and opening mechanism. > > 4) "just" build the actual Views etc. programmatically > > > > I'd steer clear of 4! It bypasses the ability of UIBuilder to make > > appropriate platform-specific Views from the generic WidgetSpecs. If you > > choose 1), override #specificationFor: in your subclass to return that > > array. If you choose 2), override #interfaceSpecFor: to return your > > FullSpec. If you choose 3), override > > #openInterface:withPolicy:inSession:, and add your own widgets to the > > builder after "builder add: spec". > > > > Again, the best advice is just to debug opening a normal window, e.g. > > "Workspace open", and step through the messages to see how the symbol > > #windowSpec gets turned into an array, then a FullSpec, then via the > > builder and UI & widget policy into Views. > > > > HTH, > > Steve > > > >> -----Original Message----- > >> From: Michael Meyer [mailto:[hidden email]] > >> Sent: 30 March 2006 20:22 > >> To: [hidden email] > >> Subject: Build a ui at runtime without using a #windowSpec > >> > >> Hi > >> I'm trying to build a dynamic ui (UI without a #windowSpec). I saw > > that > >> this is possible for > >> Dialogs (Example: > >> SimpleDialog>>choose:labels:values:default:equalize:for:) > >> > >> My first solution was to subclass SimpleDialog. This works > > but > >> there > >> are two problems: > >> > >> 1. Since I'm subclassing SimpleDialog my window blocks the whole > >> environment until > >> I close my window > >> > >> 2. When you execute the following code you will notice that you can't > >> close the > >> dialog with the "x" in the title bar (You can only close the dialog by > >> clicking a button) > >> > >> SimpleDialog new > >> choose: 'Are you completely sure?' > >> labels: (Array with: 'definitely' with: 'sort of no' with: 'sort > > of > >> yes' with: 'nope') > >> values: #(#yes #maybeNo #maybeYes #no) > >> default: #no > >> equalize: false > >> for: Dialog defaultParentWindow > >> > >> Does anybody know how I can solve problem 1 + 2? I guess subclassing > >> ApplicationModel would > >> be an idea but I haven't got a clue which methods I would have to > > change. > >> Cheers, michael > >> > >> > > > > |
In reply to this post by Michael Meyer-6
Michael Meyer wrote:
> Hi > I'm trying to build a dynamic ui (UI without a #windowSpec). I saw > that this is possible for > Dialogs (Example: > SimpleDialog>>choose:labels:values:default:equalize:for:) > > My first solution was to subclass SimpleDialog. This works basically > but there > are two problems: > > 1. Since I'm subclassing SimpleDialog my window blocks the whole > environment until > I close my window > > 2. When you execute the following code you will notice that you can't > close the > dialog with the "x" in the title bar (You can only close the dialog by > clicking a button) > > SimpleDialog new > choose: 'Are you completely sure?' > labels: (Array with: 'definitely' with: 'sort of no' with: 'sort > of yes' with: 'nope') > values: #(#yes #maybeNo #maybeYes #no) > default: #no > equalize: false > for: Dialog defaultParentWindow > > Does anybody know how I can solve problem 1 + 2? I guess subclassing > ApplicationModel would > be an idea but I haven't got a clue which methods I would have to change. Well, I've done this (several times now) in the past. If you are happy with existing widgets, then you can try the following (my latest approach): 1) Create subclass of ApplicationModel (say DynamicUI) which only contains aViewHolder on aCompositePart (via UIPainter). 2) Create specialized subclasses of ApplicationModel for all types of 'widgets' you want to 'generate' (again via UIPainter). 3) Add functionality for adding subcanvases to (resp. removing subcanvases from) DynamicUI. You can even change frames of existing subcanvases to achieve dynamic changes (even animations) but don't forget to invalidate afterwards. The add/remove functionality is basically delegated to aCompositePart that DynamicUI intrenally holds. Advantages: * It is quite simple, because you don't actually have to really build the UIs, but rather you pick from prepared ones. * It is easily extendible, because you just create new ApplicationModel as usual and just use it in your DynamicUI. Disadvantages: * If you want to support scrolling of DynamicUI content, you will have to 'manually' invalidate the ScrollWrapper to reflect the change when you add or remove something from DynamicUI. Hope it will be to some use to you... Ladislav Lenart |
In reply to this post by Michael Meyer-6
it kind of also gets down to understanding what is the "really" dynamic
aspect of your app view, once you understand that you can decide just to swap a subcanvas for another, or make somethings invisible/visible there a number of techniques that one can employ all the way up to fully building the window from scratch so it basically amounts to what Terry said, what are you trying to do? -Charles On Thu, 30 Mar 2006 15:10:25 -0500, Michael Meyer <[hidden email]> wrote: > Thanks a lot for that huge reply. The whole dynamic ui thing seems a > lot less scary now :-) > > Cheers, michael > > Steven Kelly schrieb: >> A similar question was asked in comp.lang.smalltalk last month: >> >> http://groups.google.com/group/comp.lang.smalltalk/browse_frm/thread/ae1 >> 92d2a94056e8b/38d1911f80caa3ff?lnk=st&q=group%3Acomp.lang.smalltalk+wind >> owSpec+Steve&rnum=1&hl=fi#38d1911f80caa3ff >> I wouldn't recommend looking at Pollock yet, since it's only in preview >> (pre-beta), major changes are still happening there, and there are far >> more people who can help you with the current Wrapper framework. >> To provide some background to David Buck's comments in the thread, you >> can simply supply your own FullSpec via your own #interfaceSpecFor: >> method. Follow the method through in a debugger, and you'll see a normal >> window starts life as a literal array returned by #windowSpec. >> #specificationFor: returns that array, and #interfaceSpecFor: turns it >> into a FullSpec (which has a WindowSpec for the actual window bit, plus >> the main contents as parts of a SpecCollection). >> #allButOpenInterface:* then handles the rest: the WindowSpec part is >> dealt with with a call to #hookUpWindow:spec:builder:, and the main >> content of the spec is dealt with in a simple "builder add: spec". In >> addition to adding the components to the builder, the add: does the main >> work of actually creating all the various Views to correspond to the >> Specs supplied. >> There are thus four different forms in which you can programmatically >> build your window: >> 1) literal array, as found in #windowSpec methods, corresponding to the >> structure in 2) >> 2) FullSpec containing WindowSpec and SpecCollection, the latter >> containing the actual WidgetSpecs of the widgets you want >> 3) Do what SimpleDialog does: Override the normal building mechanism to >> start with a skeleton windowSpec, build that bit as normal, then add new >> WidgetSpecs to the builder bit by bit. Finally, call the remaining bits >> of the normal building and opening mechanism. >> 4) "just" build the actual Views etc. programmatically >> I'd steer clear of 4! It bypasses the ability of UIBuilder to make >> appropriate platform-specific Views from the generic WidgetSpecs. If you >> choose 1), override #specificationFor: in your subclass to return that >> array. If you choose 2), override #interfaceSpecFor: to return your >> FullSpec. If you choose 3), override >> #openInterface:withPolicy:inSession:, and add your own widgets to the >> builder after "builder add: spec". >> Again, the best advice is just to debug opening a normal window, e.g. >> "Workspace open", and step through the messages to see how the symbol >> #windowSpec gets turned into an array, then a FullSpec, then via the >> builder and UI & widget policy into Views. >> HTH, >> Steve >> >>> -----Original Message----- >>> From: Michael Meyer [mailto:[hidden email]] >>> Sent: 30 March 2006 20:22 >>> To: [hidden email] >>> Subject: Build a ui at runtime without using a #windowSpec >>> >>> Hi >>> I'm trying to build a dynamic ui (UI without a #windowSpec). I saw >> that >>> this is possible for >>> Dialogs (Example: >>> SimpleDialog>>choose:labels:values:default:equalize:for:) >>> >>> My first solution was to subclass SimpleDialog. This works basically >> but >>> there >>> are two problems: >>> >>> 1. Since I'm subclassing SimpleDialog my window blocks the whole >>> environment until >>> I close my window >>> >>> 2. When you execute the following code you will notice that you can't >>> close the >>> dialog with the "x" in the title bar (You can only close the dialog by >>> clicking a button) >>> >>> SimpleDialog new >>> choose: 'Are you completely sure?' >>> labels: (Array with: 'definitely' with: 'sort of no' with: 'sort >> of >>> yes' with: 'nope') >>> values: #(#yes #maybeNo #maybeYes #no) >>> default: #no >>> equalize: false >>> for: Dialog defaultParentWindow >>> >>> Does anybody know how I can solve problem 1 + 2? I guess subclassing >>> ApplicationModel would >>> be an idea but I haven't got a clue which methods I would have to >> change. >>> Cheers, michael >>> >>> >> -- Charles A. Monteiro |
Hi
Thanks again for all the replies. I want to create a "Properties Editor" Basically I have objects that have a method #description that returns an array of tuples. Each tuple consists of a "human readable name", a setter and a getter. The method in object A might look like this: description ^#(#('Name' #name: #name) #('Age' #age: #age)) And in object B like this: description ^#(#('Product' #product: #product) #('Price' #price: #price) #('Stock' #stock: #stock)) Now I want to open my "dynamic ui" on one of those objects and get a simple ui that looks like this: {Label } {Combobox} {Label } {Combobox} {Label } {Combobox} ..... Today I've been playing aroung with option 2 that Steven explained in his response. But no running version yet :-) Cheers, michael Charles A. Monteiro schrieb: > it kind of also gets down to understanding what is the "really" dynamic > aspect of your app view, once you understand that you can decide just to > swap a subcanvas for another, or make somethings invisible/visible there > a number of techniques that one can employ all the way up to fully > building the window from scratch so it basically amounts to what Terry > said, what are you trying to do? > > -Charles > |
Reminds me of a "visual inspector" I once built i.e. one meant for end
user consumption. In my case I basically had both a dynamic dataset and dynamic tree that I used. The idea was to have a basic view into objects in the system that provided both a read and edit capabilities depending on some meta that was persisted by an admin type which included authentication etc. In my case columns were being built on the fly. In your case its simpler it seems like you would get a way with for example a dataset where one column represents the aspect (property) in question and the other column represents the both the potential choices and the current choice i.e. a combo box. So it then it is actually not very dynamic per se,there of course a few ways of skinning this cat but it could possibly go like this 1. Target object is asked for a collection of spec/description etc objects 2. Said collection is passed to dataset 3. spec objects would understand e.g. propertyName, currentValue, valueChoices, potentially oldValue i.e. sort of Command like 4. users would make changes in dataset which obviously would be registered with the spec objects 5. then changes could be applied to target object, persisted etc Now this breaks if your current value can be a collection of things. However, your example alludes that you are content with using ComboBoxes so off the top of my head this may work for you. BTW, the Aragon Dataset allows you to use a tree as an editor type. -Charles On Fri, 31 Mar 2006 11:08:55 -0500, Michael Meyer <[hidden email]> wrote: > Hi > > Thanks again for all the replies. I want to create a "Properties Editor" > Basically I have objects that have a method #description that returns > an array of tuples. Each tuple consists of a "human readable name", > a setter and a getter. > > The method in object A might look like this: > description > ^#(#('Name' #name: #name) #('Age' #age: #age)) > > And in object B like this: > description > ^#(#('Product' #product: #product) #('Price' #price: #price) > #('Stock' #stock: #stock)) > > Now I want to open my "dynamic ui" on one of those objects and get a > simple ui that looks like > this: > > {Label } {Combobox} > {Label } {Combobox} > {Label } {Combobox} > ..... > > Today I've been playing aroung with option 2 that Steven explained in > his response. But no > running version yet :-) > > Cheers, > michael > > Charles A. Monteiro schrieb: >> it kind of also gets down to understanding what is the "really" dynamic >> aspect of your app view, once you understand that you can decide just >> to swap a subcanvas for another, or make somethings invisible/visible >> there a number of techniques that one can employ all the way up to >> fully building the window from scratch so it basically amounts to what >> Terry said, what are you trying to do? >> -Charles >> -- Charles A. Monteiro |
Free forum by Nabble | Edit this page |