Changing VW Settings programmatically ...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Changing VW Settings programmatically ...

Dennis smith-4
Is there a preferred way to change VW Settings from code?
one that works for any setting?

Or do we have to hunt and peck to find out how to deal with each one?

--
Dennis Smith                        [hidden email]
Cherniak Software Development Corporation       +1 905.771.7011
400-10 Commerce Valley Dr E                Fax: +1 905.771.6288
Thornhill, ON Canada L3T 7N7    http://www.CherniakSoftware.com

Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

Dave Stevenson-2
Dennis Smith wrote:
> Is there a preferred way to change VW Settings from code?
> one that works for any setting?
>
> Or do we have to hunt and peck to find out how to deal with each one?
>

Dennis,

Below is a thorough excerpt from a recent discussion of how to track
down code to change a given setting, starting from the settings tool.  I
hope it will be helpful.

Dave


How do we figure out where to set the value [of the messages directory
setting]?  We didn't immediately find the answer in the .pdf docs, so we
looked at the settings tool as an example.  Start the settings tool from
the launcher:

     'System' -> 'Settings'

and select the tree node labelled 'Message Catalogs'.  On the right
appears a page for setting this value, and we see it contains a single
value set to:

     a PortableFilename('$(VISUALWORKS)/messages/visualworks')

Note that the $/ separator is just a display artifact, the internal
representation contains no separators, because it is portable.  Now, how
to set the value programmatically?  Right click on the tree node
labelled 'Message Catalogs' and select 'Browse Page and Settings'.  This
opens a method browser on VisualWorksSettings
class>>messageCatalogsPage, whose contents are:

messageCatalogsPage

     <settingsPage: #(system messageCatalogs)>

     ^SequenceSettingPage new
         label: #MessageCatalogs << #labels >> 'Message Catalogs';
         icon: (ListIconLibrary visualFor: #bubble);
         setting: (self settingWithId: #(files messageDirectories))

This is not immediately helpful, since it shows us how to specify a
settings page, and not how the setting itself may be accessed.  We see a
pragma and messages to create the page with certain identifying keys
(symbols).  On the last line we see something that sounds like it might
be referencing an actual setting (#settingWithId:), rather than just
referencing the UI/presentation/display of that setting.  We need to dig
a bit deeper to find something useful.  If we look at the argument to
#settingWithId: we find a symbol that looks promising:
     #messageDirectories

So now lets look at references (senders) of #messageDirectories, which
answers two hits.  One is the method we were just looking at, so that is
not very interesting.  The other is VisualWorksSettings
class>>files20MessageDirectories, which reads

files20MessageDirectories

     <setting: #(files messageDirectories)>

     ^((SequenceSetting of: FilenameSetting mustExist) onUISetting:
#messagesList)
         label: #UserMessageDirectories << #labels >> 'User Message
Directories';
         helpText: #UserMessageDirectoriesHelpText << #dialogs >>
'Message Cata...<snip>'

Again, nothing directly useful, but more clues.  The historical context
regarding the old settings framework and the new is important to
understand at this point.

The old framework is called UISettings, which had several drawbacks.
First, the name suggests settings that apply only to the UI classes,
whereas the settings actually affect all areas of the product.  Second,
the old framework served as the storage location of many of the
settings, which breaks encapsulation.  The settings need to be stored in
the classes that need them, and not in some orthogonal settings
framework.  If there are settings affecting parcels, for example, class
Parcel is the logical place to keep those settings.  The settings
framework should only expose a UI for easy access to the various
settings, not store the actual values.  Third, the old framework was not
easily extensible.  Conflicts with overrides made the system brittle and
decidedly un-scalable.

The new framework overcomes these issues.  It is called
VisualWorksSettings, a more appropriate name.  It does not store any
setting values, but merely provides a central UI to access the settings
that are scattered throughout the system.  And because it uses pragmas,
it is far more scalable, eliminating the need for conflicting overrides.

When Vassili wrote VisualWorksSettings, he tried to make it possible to
create a page with the least amount of coding.  He made template pages
for several kinds of settings (see subclasses of Tools.SettingType).
Once the new framework was written, work remained to port old settings
to the new framework.  He/we didn't have the time/interest to port all
of them, so there are still some that use the old UISettings framework.
  In fact, because we may not be aware of all customer uses of
UISettings, it is important to make the new framework backward
compatable with UISettings.  Such is the case here.  The #onUISetting:
keyword shows that we are creating a wrapper around an old-style
setting.  The argument to #onUISetting: provides us our next clue.
Searching for references to (senders of) #messagesList brings up the
method we were just examining, plus three others.  The first,
#addBaseSectionTo:development:runtime:, highlights this line:

    at: #messagesList put: IndexedFileMessageCatalog directoriesModel;

And here is what we've been looking for:

     IndexedFileMessageCatalog directoriesModel
       -> a ValueHolder on: List (a
PortableFilename('$(VISUALWORKS)\messages\visualworks'))

This matches what we saw in the settings UI, and the class and method
names sound right, so we've got what we need.

Note that the value is a list of filenames, not just a filename.  Now,
put it all together, and we've got something like:

setMessagesDirectory

     IndexedFileMessageCatalog directoriesModel value
         add: ((ObjectMemory imagePrefix asFilename directory construct:
'messages')
                 construct: 'vwinstaller')

Reply | Threaded
Open this post in threaded view
|

Ugly circles

Carl Gundel
In reply to this post by Dennis smith-4
Why are circles so ugly when drawn with a line width of more than 1?  What
can be done about this?

-Carl Gundel, author of Liberty BASIC
http://www.libertybasic.com 


Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

Dennis smith-4
In reply to this post by Dave Stevenson-2
Thanks -- I missed that -- where was the discussion on vwnc or the
newsgroup or???


Dave Stevenson wrote:

> Dennis Smith wrote:
>> Is there a preferred way to change VW Settings from code?
>> one that works for any setting?
>>
>> Or do we have to hunt and peck to find out how to deal with each one?
>>
>
> Dennis,
>
> Below is a thorough excerpt from a recent discussion of how to track
> down code to change a given setting, starting from the settings tool.  
> I hope it will be helpful.
>
> Dave
>
>
> How do we figure out where to set the value [of the messages directory
> setting]?  We didn't immediately find the answer in the .pdf docs, so
> we looked at the settings tool as an example.  Start the settings tool
> from the launcher:
>
>     'System' -> 'Settings'
>
> and select the tree node labelled 'Message Catalogs'.  On the right
> appears a page for setting this value, and we see it contains a single
> value set to:
>
>     a PortableFilename('$(VISUALWORKS)/messages/visualworks')
>
> Note that the $/ separator is just a display artifact, the internal
> representation contains no separators, because it is portable.  Now,
> how to set the value programmatically?  Right click on the tree node
> labelled 'Message Catalogs' and select 'Browse Page and Settings'.  
> This opens a method browser on VisualWorksSettings
> class>>messageCatalogsPage, whose contents are:
>
> messageCatalogsPage
>
>     <settingsPage: #(system messageCatalogs)>
>
>     ^SequenceSettingPage new
>         label: #MessageCatalogs << #labels >> 'Message Catalogs';
>         icon: (ListIconLibrary visualFor: #bubble);
>         setting: (self settingWithId: #(files messageDirectories))
>
> This is not immediately helpful, since it shows us how to specify a
> settings page, and not how the setting itself may be accessed.  We see
> a pragma and messages to create the page with certain identifying keys
> (symbols).  On the last line we see something that sounds like it
> might be referencing an actual setting (#settingWithId:), rather than
> just referencing the UI/presentation/display of that setting.  We need
> to dig a bit deeper to find something useful.  If we look at the
> argument to #settingWithId: we find a symbol that looks promising:
>     #messageDirectories
>
> So now lets look at references (senders) of #messageDirectories, which
> answers two hits.  One is the method we were just looking at, so that
> is not very interesting.  The other is VisualWorksSettings
> class>>files20MessageDirectories, which reads
>
> files20MessageDirectories
>
>     <setting: #(files messageDirectories)>
>
>     ^((SequenceSetting of: FilenameSetting mustExist) onUISetting:
> #messagesList)
>         label: #UserMessageDirectories << #labels >> 'User Message
> Directories';
>         helpText: #UserMessageDirectoriesHelpText << #dialogs >>
> 'Message Cata...<snip>'
>
> Again, nothing directly useful, but more clues.  The historical
> context regarding the old settings framework and the new is important
> to understand at this point.
>
> The old framework is called UISettings, which had several drawbacks.
> First, the name suggests settings that apply only to the UI classes,
> whereas the settings actually affect all areas of the product.  
> Second, the old framework served as the storage location of many of
> the settings, which breaks encapsulation.  The settings need to be
> stored in the classes that need them, and not in some orthogonal
> settings framework.  If there are settings affecting parcels, for
> example, class Parcel is the logical place to keep those settings.  
> The settings framework should only expose a UI for easy access to the
> various settings, not store the actual values.  Third, the old
> framework was not easily extensible.  Conflicts with overrides made
> the system brittle and decidedly un-scalable.
>
> The new framework overcomes these issues.  It is called
> VisualWorksSettings, a more appropriate name.  It does not store any
> setting values, but merely provides a central UI to access the
> settings that are scattered throughout the system.  And because it
> uses pragmas, it is far more scalable, eliminating the need for
> conflicting overrides.
>
> When Vassili wrote VisualWorksSettings, he tried to make it possible
> to create a page with the least amount of coding.  He made template
> pages for several kinds of settings (see subclasses of
> Tools.SettingType). Once the new framework was written, work remained
> to port old settings to the new framework.  He/we didn't have the
> time/interest to port all of them, so there are still some that use
> the old UISettings framework.  In fact, because we may not be aware of
> all customer uses of UISettings, it is important to make the new
> framework backward compatable with UISettings.  Such is the case
> here.  The #onUISetting: keyword shows that we are creating a wrapper
> around an old-style setting.  The argument to #onUISetting: provides
> us our next clue. Searching for references to (senders of)
> #messagesList brings up the method we were just examining, plus three
> others.  The first, #addBaseSectionTo:development:runtime:, highlights
> this line:
>
>    at: #messagesList put: IndexedFileMessageCatalog directoriesModel;
>
> And here is what we've been looking for:
>
>     IndexedFileMessageCatalog directoriesModel
>       -> a ValueHolder on: List (a
> PortableFilename('$(VISUALWORKS)\messages\visualworks'))
>
> This matches what we saw in the settings UI, and the class and method
> names sound right, so we've got what we need.
>
> Note that the value is a list of filenames, not just a filename.  Now,
> put it all together, and we've got something like:
>
> setMessagesDirectory
>
>     IndexedFileMessageCatalog directoriesModel value
>         add: ((ObjectMemory imagePrefix asFilename directory
> construct: 'messages')
>                 construct: 'vwinstaller')

--
Dennis Smith                        [hidden email]
Cherniak Software Development Corporation       +1 905.771.7011
400-10 Commerce Valley Dr E                Fax: +1 905.771.6288
Thornhill, ON Canada L3T 7N7    http://www.CherniakSoftware.com

Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

kobetic
In reply to this post by Dave Stevenson-2
I'd be inclined to use the new settings abstractions to hide the details
of individual settings. So maybe something along the lines:

(VisualWorksSettings settingWithId: #(tools browser showToolbar))
        value: false

You still have to dig the ID array out somehow, either you find the
corresponding method on VisualWorksSettings class or you can just save
the page you're interested in and look for the <id> node in the
generated XML.

HTH,

Martin

Dave Stevenson wrote:

> Dennis Smith wrote:
>
>> Is there a preferred way to change VW Settings from code?
>> one that works for any setting?
>>
>> Or do we have to hunt and peck to find out how to deal with each one?
>>
>
> Dennis,
>
> Below is a thorough excerpt from a recent discussion of how to track
> down code to change a given setting, starting from the settings tool.  I
> hope it will be helpful.
>
> Dave
>
>
> How do we figure out where to set the value [of the messages directory
> setting]?  We didn't immediately find the answer in the .pdf docs, so we
> looked at the settings tool as an example.  Start the settings tool from
> the launcher:
>
>     'System' -> 'Settings'
>
> and select the tree node labelled 'Message Catalogs'.  On the right
> appears a page for setting this value, and we see it contains a single
> value set to:
>
>     a PortableFilename('$(VISUALWORKS)/messages/visualworks')
>
> Note that the $/ separator is just a display artifact, the internal
> representation contains no separators, because it is portable.  Now, how
> to set the value programmatically?  Right click on the tree node
> labelled 'Message Catalogs' and select 'Browse Page and Settings'.  This
> opens a method browser on VisualWorksSettings
> class>>messageCatalogsPage, whose contents are:
>
> messageCatalogsPage
>
>     <settingsPage: #(system messageCatalogs)>
>
>     ^SequenceSettingPage new
>         label: #MessageCatalogs << #labels >> 'Message Catalogs';
>         icon: (ListIconLibrary visualFor: #bubble);
>         setting: (self settingWithId: #(files messageDirectories))
>
> This is not immediately helpful, since it shows us how to specify a
> settings page, and not how the setting itself may be accessed.  We see a
> pragma and messages to create the page with certain identifying keys
> (symbols).  On the last line we see something that sounds like it might
> be referencing an actual setting (#settingWithId:), rather than just
> referencing the UI/presentation/display of that setting.  We need to dig
> a bit deeper to find something useful.  If we look at the argument to
> #settingWithId: we find a symbol that looks promising:
>     #messageDirectories
>
> So now lets look at references (senders) of #messageDirectories, which
> answers two hits.  One is the method we were just looking at, so that is
> not very interesting.  The other is VisualWorksSettings
> class>>files20MessageDirectories, which reads
>
> files20MessageDirectories
>
>     <setting: #(files messageDirectories)>
>
>     ^((SequenceSetting of: FilenameSetting mustExist) onUISetting:
> #messagesList)
>         label: #UserMessageDirectories << #labels >> 'User Message
> Directories';
>         helpText: #UserMessageDirectoriesHelpText << #dialogs >>
> 'Message Cata...<snip>'
>
> Again, nothing directly useful, but more clues.  The historical context
> regarding the old settings framework and the new is important to
> understand at this point.
>
> The old framework is called UISettings, which had several drawbacks.
> First, the name suggests settings that apply only to the UI classes,
> whereas the settings actually affect all areas of the product.  Second,
> the old framework served as the storage location of many of the
> settings, which breaks encapsulation.  The settings need to be stored in
> the classes that need them, and not in some orthogonal settings
> framework.  If there are settings affecting parcels, for example, class
> Parcel is the logical place to keep those settings.  The settings
> framework should only expose a UI for easy access to the various
> settings, not store the actual values.  Third, the old framework was not
> easily extensible.  Conflicts with overrides made the system brittle and
> decidedly un-scalable.
>
> The new framework overcomes these issues.  It is called
> VisualWorksSettings, a more appropriate name.  It does not store any
> setting values, but merely provides a central UI to access the settings
> that are scattered throughout the system.  And because it uses pragmas,
> it is far more scalable, eliminating the need for conflicting overrides.
>
> When Vassili wrote VisualWorksSettings, he tried to make it possible to
> create a page with the least amount of coding.  He made template pages
> for several kinds of settings (see subclasses of Tools.SettingType).
> Once the new framework was written, work remained to port old settings
> to the new framework.  He/we didn't have the time/interest to port all
> of them, so there are still some that use the old UISettings framework.
>  In fact, because we may not be aware of all customer uses of
> UISettings, it is important to make the new framework backward
> compatable with UISettings.  Such is the case here.  The #onUISetting:
> keyword shows that we are creating a wrapper around an old-style
> setting.  The argument to #onUISetting: provides us our next clue.
> Searching for references to (senders of) #messagesList brings up the
> method we were just examining, plus three others.  The first,
> #addBaseSectionTo:development:runtime:, highlights this line:
>
>    at: #messagesList put: IndexedFileMessageCatalog directoriesModel;
>
> And here is what we've been looking for:
>
>     IndexedFileMessageCatalog directoriesModel
>       -> a ValueHolder on: List (a
> PortableFilename('$(VISUALWORKS)\messages\visualworks'))
>
> This matches what we saw in the settings UI, and the class and method
> names sound right, so we've got what we need.
>
> Note that the value is a list of filenames, not just a filename.  Now,
> put it all together, and we've got something like:
>
> setMessagesDirectory
>
>     IndexedFileMessageCatalog directoriesModel value
>         add: ((ObjectMemory imagePrefix asFilename directory construct:
> 'messages')
>                 construct: 'vwinstaller')
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

Dave Stevenson-2
In reply to this post by Dennis smith-4
internal...

Dennis Smith wrote:

> Thanks -- I missed that -- where was the discussion on vwnc or the
> newsgroup or???
>
>
> Dave Stevenson wrote:
>> Dennis Smith wrote:
>>> Is there a preferred way to change VW Settings from code?
>>> one that works for any setting?
>>>
>>> Or do we have to hunt and peck to find out how to deal with each one?
>>>
>>
>> Dennis,
>>
>> Below is a thorough excerpt from a recent discussion of how to track
>> down code to change a given setting, starting from the settings tool.  
>> I hope it will be helpful.
>>
>> Dave
>>
>>
>> How do we figure out where to set the value [of the messages directory
>> setting]?  We didn't immediately find the answer in the .pdf docs, so
>> we looked at the settings tool as an example.  Start the settings tool
>> from the launcher:
>>
>>     'System' -> 'Settings'
>>
>> and select the tree node labelled 'Message Catalogs'.  On the right
>> appears a page for setting this value, and we see it contains a single
>> value set to:
>>
>>     a PortableFilename('$(VISUALWORKS)/messages/visualworks')
>>
>> Note that the $/ separator is just a display artifact, the internal
>> representation contains no separators, because it is portable.  Now,
>> how to set the value programmatically?  Right click on the tree node
>> labelled 'Message Catalogs' and select 'Browse Page and Settings'.  
>> This opens a method browser on VisualWorksSettings
>> class>>messageCatalogsPage, whose contents are:
>>
>> messageCatalogsPage
>>
>>     <settingsPage: #(system messageCatalogs)>
>>
>>     ^SequenceSettingPage new
>>         label: #MessageCatalogs << #labels >> 'Message Catalogs';
>>         icon: (ListIconLibrary visualFor: #bubble);
>>         setting: (self settingWithId: #(files messageDirectories))
>>
>> This is not immediately helpful, since it shows us how to specify a
>> settings page, and not how the setting itself may be accessed.  We see
>> a pragma and messages to create the page with certain identifying keys
>> (symbols).  On the last line we see something that sounds like it
>> might be referencing an actual setting (#settingWithId:), rather than
>> just referencing the UI/presentation/display of that setting.  We need
>> to dig a bit deeper to find something useful.  If we look at the
>> argument to #settingWithId: we find a symbol that looks promising:
>>     #messageDirectories
>>
>> So now lets look at references (senders) of #messageDirectories, which
>> answers two hits.  One is the method we were just looking at, so that
>> is not very interesting.  The other is VisualWorksSettings
>> class>>files20MessageDirectories, which reads
>>
>> files20MessageDirectories
>>
>>     <setting: #(files messageDirectories)>
>>
>>     ^((SequenceSetting of: FilenameSetting mustExist) onUISetting:
>> #messagesList)
>>         label: #UserMessageDirectories << #labels >> 'User Message
>> Directories';
>>         helpText: #UserMessageDirectoriesHelpText << #dialogs >>
>> 'Message Cata...<snip>'
>>
>> Again, nothing directly useful, but more clues.  The historical
>> context regarding the old settings framework and the new is important
>> to understand at this point.
>>
>> The old framework is called UISettings, which had several drawbacks.
>> First, the name suggests settings that apply only to the UI classes,
>> whereas the settings actually affect all areas of the product.  
>> Second, the old framework served as the storage location of many of
>> the settings, which breaks encapsulation.  The settings need to be
>> stored in the classes that need them, and not in some orthogonal
>> settings framework.  If there are settings affecting parcels, for
>> example, class Parcel is the logical place to keep those settings.  
>> The settings framework should only expose a UI for easy access to the
>> various settings, not store the actual values.  Third, the old
>> framework was not easily extensible.  Conflicts with overrides made
>> the system brittle and decidedly un-scalable.
>>
>> The new framework overcomes these issues.  It is called
>> VisualWorksSettings, a more appropriate name.  It does not store any
>> setting values, but merely provides a central UI to access the
>> settings that are scattered throughout the system.  And because it
>> uses pragmas, it is far more scalable, eliminating the need for
>> conflicting overrides.
>>
>> When Vassili wrote VisualWorksSettings, he tried to make it possible
>> to create a page with the least amount of coding.  He made template
>> pages for several kinds of settings (see subclasses of
>> Tools.SettingType). Once the new framework was written, work remained
>> to port old settings to the new framework.  He/we didn't have the
>> time/interest to port all of them, so there are still some that use
>> the old UISettings framework.  In fact, because we may not be aware of
>> all customer uses of UISettings, it is important to make the new
>> framework backward compatable with UISettings.  Such is the case
>> here.  The #onUISetting: keyword shows that we are creating a wrapper
>> around an old-style setting.  The argument to #onUISetting: provides
>> us our next clue. Searching for references to (senders of)
>> #messagesList brings up the method we were just examining, plus three
>> others.  The first, #addBaseSectionTo:development:runtime:, highlights
>> this line:
>>
>>    at: #messagesList put: IndexedFileMessageCatalog directoriesModel;
>>
>> And here is what we've been looking for:
>>
>>     IndexedFileMessageCatalog directoriesModel
>>       -> a ValueHolder on: List (a
>> PortableFilename('$(VISUALWORKS)\messages\visualworks'))
>>
>> This matches what we saw in the settings UI, and the class and method
>> names sound right, so we've got what we need.
>>
>> Note that the value is a list of filenames, not just a filename.  Now,
>> put it all together, and we've got something like:
>>
>> setMessagesDirectory
>>
>>     IndexedFileMessageCatalog directoriesModel value
>>         add: ((ObjectMemory imagePrefix asFilename directory
>> construct: 'messages')
>>                 construct: 'vwinstaller')
>

Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

Dave Stevenson-2
In reply to this post by kobetic
This is certainly a viable alternative.  But one reason we switched from
UISettings to the new framework was so that the framework could be
stripped from a runtime image.  If you don't mind keeping some of the
settings code in your runtime, this may suffice for you.  If you want
your runtime as small as possible, then dig deeper.

Dave

Martin Kobetic wrote:

> I'd be inclined to use the new settings abstractions to hide the details
> of individual settings. So maybe something along the lines:
>
> (VisualWorksSettings settingWithId: #(tools browser showToolbar))
>     value: false
>
> You still have to dig the ID array out somehow, either you find the
> corresponding method on VisualWorksSettings class or you can just save
> the page you're interested in and look for the <id> node in the
> generated XML.
>
> HTH,
>
> Martin
>
> Dave Stevenson wrote:
>
>> Dennis Smith wrote:
>>
>>> Is there a preferred way to change VW Settings from code?
>>> one that works for any setting?
>>>
>>> Or do we have to hunt and peck to find out how to deal with each one?
>>>
>>
>> Dennis,
>>
>> Below is a thorough excerpt from a recent discussion of how to track
>> down code to change a given setting, starting from the settings tool.  
>> I hope it will be helpful.
>>
>> Dave
>>
>>
>> How do we figure out where to set the value [of the messages directory
>> setting]?  We didn't immediately find the answer in the .pdf docs, so
>> we looked at the settings tool as an example.  Start the settings tool
>> from the launcher:
>>
>>     'System' -> 'Settings'
>>
>> and select the tree node labelled 'Message Catalogs'.  On the right
>> appears a page for setting this value, and we see it contains a single
>> value set to:
>>
>>     a PortableFilename('$(VISUALWORKS)/messages/visualworks')
>>
>> Note that the $/ separator is just a display artifact, the internal
>> representation contains no separators, because it is portable.  Now,
>> how to set the value programmatically?  Right click on the tree node
>> labelled 'Message Catalogs' and select 'Browse Page and Settings'.  
>> This opens a method browser on VisualWorksSettings
>> class>>messageCatalogsPage, whose contents are:
>>
>> messageCatalogsPage
>>
>>     <settingsPage: #(system messageCatalogs)>
>>
>>     ^SequenceSettingPage new
>>         label: #MessageCatalogs << #labels >> 'Message Catalogs';
>>         icon: (ListIconLibrary visualFor: #bubble);
>>         setting: (self settingWithId: #(files messageDirectories))
>>
>> This is not immediately helpful, since it shows us how to specify a
>> settings page, and not how the setting itself may be accessed.  We see
>> a pragma and messages to create the page with certain identifying keys
>> (symbols).  On the last line we see something that sounds like it
>> might be referencing an actual setting (#settingWithId:), rather than
>> just referencing the UI/presentation/display of that setting.  We need
>> to dig a bit deeper to find something useful.  If we look at the
>> argument to #settingWithId: we find a symbol that looks promising:
>>     #messageDirectories
>>
>> So now lets look at references (senders) of #messageDirectories, which
>> answers two hits.  One is the method we were just looking at, so that
>> is not very interesting.  The other is VisualWorksSettings
>> class>>files20MessageDirectories, which reads
>>
>> files20MessageDirectories
>>
>>     <setting: #(files messageDirectories)>
>>
>>     ^((SequenceSetting of: FilenameSetting mustExist) onUISetting:
>> #messagesList)
>>         label: #UserMessageDirectories << #labels >> 'User Message
>> Directories';
>>         helpText: #UserMessageDirectoriesHelpText << #dialogs >>
>> 'Message Cata...<snip>'
>>
>> Again, nothing directly useful, but more clues.  The historical
>> context regarding the old settings framework and the new is important
>> to understand at this point.
>>
>> The old framework is called UISettings, which had several drawbacks.
>> First, the name suggests settings that apply only to the UI classes,
>> whereas the settings actually affect all areas of the product.  
>> Second, the old framework served as the storage location of many of
>> the settings, which breaks encapsulation.  The settings need to be
>> stored in the classes that need them, and not in some orthogonal
>> settings framework.  If there are settings affecting parcels, for
>> example, class Parcel is the logical place to keep those settings.  
>> The settings framework should only expose a UI for easy access to the
>> various settings, not store the actual values.  Third, the old
>> framework was not easily extensible.  Conflicts with overrides made
>> the system brittle and decidedly un-scalable.
>>
>> The new framework overcomes these issues.  It is called
>> VisualWorksSettings, a more appropriate name.  It does not store any
>> setting values, but merely provides a central UI to access the
>> settings that are scattered throughout the system.  And because it
>> uses pragmas, it is far more scalable, eliminating the need for
>> conflicting overrides.
>>
>> When Vassili wrote VisualWorksSettings, he tried to make it possible
>> to create a page with the least amount of coding.  He made template
>> pages for several kinds of settings (see subclasses of
>> Tools.SettingType). Once the new framework was written, work remained
>> to port old settings to the new framework.  He/we didn't have the
>> time/interest to port all of them, so there are still some that use
>> the old UISettings framework.  In fact, because we may not be aware of
>> all customer uses of UISettings, it is important to make the new
>> framework backward compatable with UISettings.  Such is the case
>> here.  The #onUISetting: keyword shows that we are creating a wrapper
>> around an old-style setting.  The argument to #onUISetting: provides
>> us our next clue. Searching for references to (senders of)
>> #messagesList brings up the method we were just examining, plus three
>> others.  The first, #addBaseSectionTo:development:runtime:, highlights
>> this line:
>>
>>    at: #messagesList put: IndexedFileMessageCatalog directoriesModel;
>>
>> And here is what we've been looking for:
>>
>>     IndexedFileMessageCatalog directoriesModel
>>       -> a ValueHolder on: List (a
>> PortableFilename('$(VISUALWORKS)\messages\visualworks'))
>>
>> This matches what we saw in the settings UI, and the class and method
>> names sound right, so we've got what we need.
>>
>> Note that the value is a list of filenames, not just a filename.  Now,
>> put it all together, and we've got something like:
>>
>> setMessagesDirectory
>>
>>     IndexedFileMessageCatalog directoriesModel value
>>         add: ((ObjectMemory imagePrefix asFilename directory
>> construct: 'messages')
>>                 construct: 'vwinstaller')
>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Ugly circles

Ladislav Lenart
In reply to this post by Carl Gundel
Carl Gundel wrote:
> Why are circles so ugly when drawn with a line width of more than 1?  
> What can be done about this?

Hello,

the cause of this is in graphic primitives 990 and 991 (on Windows platform
only). To verify this, we made our own calls to GDI via DLLCC to replace
these primitives. This allowed us to draw on ScreenGraphicsContext of a
window and everything looked great.

However, you can only draw on a window this way. You can not draw on a pixmap,
because its handle that has to be passed to a GDI call is not accessible in
Smalltalk.

So your choice is to fix primitives 990 and 991 and compile your own VM, or
write new primitve that makes pixmap handle accessible to Smalltalk and write
GDI calls via DLLCC. None of which is easy-to-do from my point of view.

Therefore we canceled our own effort to fix this and currently have to
live with really awkward look on Windows.

But if you plan to address this issue, we would be VERY interesting in
your solution... :-)

I was reporting this problem on this list some time ago, but I was told
that it is a known issue (which means that it is there for some time now :-)

Hope this helps,

Ladislav Lenart

Reply | Threaded
Open this post in threaded view
|

Re: Ugly circles

Carl Gundel
> Carl Gundel wrote:
>> Why are circles so ugly when drawn with a line width of more than 1?
>> What can be done about this?
>
> the cause of this is in graphic primitives 990 and 991 (on Windows
> platform
> only). To verify this, we made our own calls to GDI via DLLCC to replace
<snip>
> Therefore we canceled our own effort to fix this and currently have to
> live with really awkward look on Windows.

I see.  Looks like I'm in the same boat.

> But if you plan to address this issue, we would be VERY interesting in
> your solution... :-)

I don't think so.  Sorry.  :-/

> I was reporting this problem on this list some time ago, but I was told
> that it is a known issue (which means that it is there for some time now
> :-)
>
> Hope this helps,

I wish it did.

-Carl


Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

Dennis smith-4
In reply to this post by kobetic
Now that works.  I wrote a utility class that lets me do a heuristic
find, so I can say
    CGvwSettings at: 'dialogs at cursor' put: true
If it does not find or if it finds multiple, or if the value you try and
put is not of the same class
as the current value it generates an error.

Makes life simple -- a bit "fuzzy" thought perhaps ;)



Martin Kobetic wrote:

> I'd be inclined to use the new settings abstractions to hide the
> details of individual settings. So maybe something along the lines:
>
> (VisualWorksSettings settingWithId: #(tools browser showToolbar))
>     value: false
>
> You still have to dig the ID array out somehow, either you find the
> corresponding method on VisualWorksSettings class or you can just save
> the page you're interested in and look for the <id> node in the
> generated XML.
>
> HTH,
>
> Martin
>
> Dave Stevenson wrote:
>
>> Dennis Smith wrote:
>>
>>> Is there a preferred way to change VW Settings from code?
>>> one that works for any setting?
>>>
>>> Or do we have to hunt and peck to find out how to deal with each one?
>>>
>>
>> Dennis,
>>
>> Below is a thorough excerpt from a recent discussion of how to track
>> down code to change a given setting, starting from the settings
>> tool.  I hope it will be helpful.
>>
>> Dave
>>
>>
>> How do we figure out where to set the value [of the messages
>> directory setting]?  We didn't immediately find the answer in the
>> .pdf docs, so we looked at the settings tool as an example.  Start
>> the settings tool from the launcher:
>>
>>     'System' -> 'Settings'
>>
>> and select the tree node labelled 'Message Catalogs'.  On the right
>> appears a page for setting this value, and we see it contains a
>> single value set to:
>>
>>     a PortableFilename('$(VISUALWORKS)/messages/visualworks')
>>
>> Note that the $/ separator is just a display artifact, the internal
>> representation contains no separators, because it is portable.  Now,
>> how to set the value programmatically?  Right click on the tree node
>> labelled 'Message Catalogs' and select 'Browse Page and Settings'.  
>> This opens a method browser on VisualWorksSettings
>> class>>messageCatalogsPage, whose contents are:
>>
>> messageCatalogsPage
>>
>>     <settingsPage: #(system messageCatalogs)>
>>
>>     ^SequenceSettingPage new
>>         label: #MessageCatalogs << #labels >> 'Message Catalogs';
>>         icon: (ListIconLibrary visualFor: #bubble);
>>         setting: (self settingWithId: #(files messageDirectories))
>>
>> This is not immediately helpful, since it shows us how to specify a
>> settings page, and not how the setting itself may be accessed.  We
>> see a pragma and messages to create the page with certain identifying
>> keys (symbols).  On the last line we see something that sounds like
>> it might be referencing an actual setting (#settingWithId:), rather
>> than just referencing the UI/presentation/display of that setting.  
>> We need to dig a bit deeper to find something useful.  If we look at
>> the argument to #settingWithId: we find a symbol that looks promising:
>>     #messageDirectories
>>
>> So now lets look at references (senders) of #messageDirectories,
>> which answers two hits.  One is the method we were just looking at,
>> so that is not very interesting.  The other is VisualWorksSettings
>> class>>files20MessageDirectories, which reads
>>
>> files20MessageDirectories
>>
>>     <setting: #(files messageDirectories)>
>>
>>     ^((SequenceSetting of: FilenameSetting mustExist) onUISetting:
>> #messagesList)
>>         label: #UserMessageDirectories << #labels >> 'User Message
>> Directories';
>>         helpText: #UserMessageDirectoriesHelpText << #dialogs >>
>> 'Message Cata...<snip>'
>>
>> Again, nothing directly useful, but more clues.  The historical
>> context regarding the old settings framework and the new is important
>> to understand at this point.
>>
>> The old framework is called UISettings, which had several drawbacks.
>> First, the name suggests settings that apply only to the UI classes,
>> whereas the settings actually affect all areas of the product.  
>> Second, the old framework served as the storage location of many of
>> the settings, which breaks encapsulation.  The settings need to be
>> stored in the classes that need them, and not in some orthogonal
>> settings framework.  If there are settings affecting parcels, for
>> example, class Parcel is the logical place to keep those settings.  
>> The settings framework should only expose a UI for easy access to the
>> various settings, not store the actual values.  Third, the old
>> framework was not easily extensible.  Conflicts with overrides made
>> the system brittle and decidedly un-scalable.
>>
>> The new framework overcomes these issues.  It is called
>> VisualWorksSettings, a more appropriate name.  It does not store any
>> setting values, but merely provides a central UI to access the
>> settings that are scattered throughout the system.  And because it
>> uses pragmas, it is far more scalable, eliminating the need for
>> conflicting overrides.
>>
>> When Vassili wrote VisualWorksSettings, he tried to make it possible
>> to create a page with the least amount of coding.  He made template
>> pages for several kinds of settings (see subclasses of
>> Tools.SettingType). Once the new framework was written, work remained
>> to port old settings to the new framework.  He/we didn't have the
>> time/interest to port all of them, so there are still some that use
>> the old UISettings framework.  In fact, because we may not be aware
>> of all customer uses of UISettings, it is important to make the new
>> framework backward compatable with UISettings.  Such is the case
>> here.  The #onUISetting: keyword shows that we are creating a wrapper
>> around an old-style setting.  The argument to #onUISetting: provides
>> us our next clue. Searching for references to (senders of)
>> #messagesList brings up the method we were just examining, plus three
>> others.  The first, #addBaseSectionTo:development:runtime:,
>> highlights this line:
>>
>>    at: #messagesList put: IndexedFileMessageCatalog directoriesModel;
>>
>> And here is what we've been looking for:
>>
>>     IndexedFileMessageCatalog directoriesModel
>>       -> a ValueHolder on: List (a
>> PortableFilename('$(VISUALWORKS)\messages\visualworks'))
>>
>> This matches what we saw in the settings UI, and the class and method
>> names sound right, so we've got what we need.
>>
>> Note that the value is a list of filenames, not just a filename.  
>> Now, put it all together, and we've got something like:
>>
>> setMessagesDirectory
>>
>>     IndexedFileMessageCatalog directoriesModel value
>>         add: ((ObjectMemory imagePrefix asFilename directory
>> construct: 'messages')
>>                 construct: 'vwinstaller')
>>
>>
>

--
Dennis Smith                        [hidden email]
Cherniak Software Development Corporation       +1 905.771.7011
400-10 Commerce Valley Dr E                Fax: +1 905.771.6288
Thornhill, ON Canada L3T 7N7    http://www.CherniakSoftware.com

Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

Dennis smith-4
In reply to this post by Dave Stevenson-2
Hm -- a valid comment -- but it would be nice to keep a small part of it
so that things could be set without
keeping all the UI stuff -- does not bother us, we don't have a size
problem.

Dave Stevenson wrote:

> This is certainly a viable alternative.  But one reason we switched
> from UISettings to the new framework was so that the framework could
> be stripped from a runtime image.  If you don't mind keeping some of
> the settings code in your runtime, this may suffice for you.  If you
> want your runtime as small as possible, then dig deeper.
>
> Dave
>
> Martin Kobetic wrote:
>> I'd be inclined to use the new settings abstractions to hide the
>> details of individual settings. So maybe something along the lines:
>>
>> (VisualWorksSettings settingWithId: #(tools browser showToolbar))
>>     value: false
>>
>> You still have to dig the ID array out somehow, either you find the
>> corresponding method on VisualWorksSettings class or you can just
>> save the page you're interested in and look for the <id> node in the
>> generated XML.
>>
>> HTH,
>>
>> Martin
>>
>> Dave Stevenson wrote:
>>
>>> Dennis Smith wrote:
>>>
>>>> Is there a preferred way to change VW Settings from code?
>>>> one that works for any setting?
>>>>
>>>> Or do we have to hunt and peck to find out how to deal with each one?
>>>>
>>>
>>> Dennis,
>>>
>>> Below is a thorough excerpt from a recent discussion of how to track
>>> down code to change a given setting, starting from the settings
>>> tool.  I hope it will be helpful.
>>>
>>> Dave
>>>
>>>
>>> How do we figure out where to set the value [of the messages
>>> directory setting]?  We didn't immediately find the answer in the
>>> .pdf docs, so we looked at the settings tool as an example.  Start
>>> the settings tool from the launcher:
>>>
>>>     'System' -> 'Settings'
>>>
>>> and select the tree node labelled 'Message Catalogs'.  On the right
>>> appears a page for setting this value, and we see it contains a
>>> single value set to:
>>>
>>>     a PortableFilename('$(VISUALWORKS)/messages/visualworks')
>>>
>>> Note that the $/ separator is just a display artifact, the internal
>>> representation contains no separators, because it is portable.  Now,
>>> how to set the value programmatically?  Right click on the tree node
>>> labelled 'Message Catalogs' and select 'Browse Page and Settings'.  
>>> This opens a method browser on VisualWorksSettings
>>> class>>messageCatalogsPage, whose contents are:
>>>
>>> messageCatalogsPage
>>>
>>>     <settingsPage: #(system messageCatalogs)>
>>>
>>>     ^SequenceSettingPage new
>>>         label: #MessageCatalogs << #labels >> 'Message Catalogs';
>>>         icon: (ListIconLibrary visualFor: #bubble);
>>>         setting: (self settingWithId: #(files messageDirectories))
>>>
>>> This is not immediately helpful, since it shows us how to specify a
>>> settings page, and not how the setting itself may be accessed.  We
>>> see a pragma and messages to create the page with certain
>>> identifying keys (symbols).  On the last line we see something that
>>> sounds like it might be referencing an actual setting
>>> (#settingWithId:), rather than just referencing the
>>> UI/presentation/display of that setting.  We need to dig a bit
>>> deeper to find something useful.  If we look at the argument to
>>> #settingWithId: we find a symbol that looks promising:
>>>     #messageDirectories
>>>
>>> So now lets look at references (senders) of #messageDirectories,
>>> which answers two hits.  One is the method we were just looking at,
>>> so that is not very interesting.  The other is VisualWorksSettings
>>> class>>files20MessageDirectories, which reads
>>>
>>> files20MessageDirectories
>>>
>>>     <setting: #(files messageDirectories)>
>>>
>>>     ^((SequenceSetting of: FilenameSetting mustExist) onUISetting:
>>> #messagesList)
>>>         label: #UserMessageDirectories << #labels >> 'User Message
>>> Directories';
>>>         helpText: #UserMessageDirectoriesHelpText << #dialogs >>
>>> 'Message Cata...<snip>'
>>>
>>> Again, nothing directly useful, but more clues.  The historical
>>> context regarding the old settings framework and the new is
>>> important to understand at this point.
>>>
>>> The old framework is called UISettings, which had several drawbacks.
>>> First, the name suggests settings that apply only to the UI classes,
>>> whereas the settings actually affect all areas of the product.  
>>> Second, the old framework served as the storage location of many of
>>> the settings, which breaks encapsulation.  The settings need to be
>>> stored in the classes that need them, and not in some orthogonal
>>> settings framework.  If there are settings affecting parcels, for
>>> example, class Parcel is the logical place to keep those settings.  
>>> The settings framework should only expose a UI for easy access to
>>> the various settings, not store the actual values.  Third, the old
>>> framework was not easily extensible.  Conflicts with overrides made
>>> the system brittle and decidedly un-scalable.
>>>
>>> The new framework overcomes these issues.  It is called
>>> VisualWorksSettings, a more appropriate name.  It does not store any
>>> setting values, but merely provides a central UI to access the
>>> settings that are scattered throughout the system.  And because it
>>> uses pragmas, it is far more scalable, eliminating the need for
>>> conflicting overrides.
>>>
>>> When Vassili wrote VisualWorksSettings, he tried to make it possible
>>> to create a page with the least amount of coding.  He made template
>>> pages for several kinds of settings (see subclasses of
>>> Tools.SettingType). Once the new framework was written, work
>>> remained to port old settings to the new framework.  He/we didn't
>>> have the time/interest to port all of them, so there are still some
>>> that use the old UISettings framework.  In fact, because we may not
>>> be aware of all customer uses of UISettings, it is important to make
>>> the new framework backward compatable with UISettings.  Such is the
>>> case here.  The #onUISetting: keyword shows that we are creating a
>>> wrapper around an old-style setting.  The argument to #onUISetting:
>>> provides us our next clue. Searching for references to (senders of)
>>> #messagesList brings up the method we were just examining, plus
>>> three others.  The first, #addBaseSectionTo:development:runtime:,
>>> highlights this line:
>>>
>>>    at: #messagesList put: IndexedFileMessageCatalog directoriesModel;
>>>
>>> And here is what we've been looking for:
>>>
>>>     IndexedFileMessageCatalog directoriesModel
>>>       -> a ValueHolder on: List (a
>>> PortableFilename('$(VISUALWORKS)\messages\visualworks'))
>>>
>>> This matches what we saw in the settings UI, and the class and
>>> method names sound right, so we've got what we need.
>>>
>>> Note that the value is a list of filenames, not just a filename.  
>>> Now, put it all together, and we've got something like:
>>>
>>> setMessagesDirectory
>>>
>>>     IndexedFileMessageCatalog directoriesModel value
>>>         add: ((ObjectMemory imagePrefix asFilename directory
>>> construct: 'messages')
>>>                 construct: 'vwinstaller')
>>>
>>>
>>
>>

--
Dennis Smith                        [hidden email]
Cherniak Software Development Corporation       +1 905.771.7011
400-10 Commerce Valley Dr E                Fax: +1 905.771.6288
Thornhill, ON Canada L3T 7N7    http://www.CherniakSoftware.com

Reply | Threaded
Open this post in threaded view
|

RE: Ugly circles

Steven Kelly
In reply to this post by Carl Gundel
From: Ladislav Lenart [mailto:[hidden email]]
> You can not draw on a pixmap, because its handle that has
> to be passed to a GDI call is not accessible in Smalltalk.

I think the handle is in the Pixmap:
  handle unsignedLongAt: 5
Check out WinGDIPlusInterface in the public Store.

BTW, if anyone knows how to create a GDI bitmap/image from a Windows
Pixmap/Image, I'd be really grateful. Currently I'm building them by
saving the Image to a PNG stream in memory, then passing that to the GDI
function that builds a GDI Bitmap from a PNG stream...

Going the other way is easier: with WinGDIPlusInterface you can display
a GDI Bitmap on a normal VW Pixmap.

Cheers,
Steve

Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

Vassili Bykov
In reply to this post by kobetic
Martin Kobetic wrote:
 > I'd be inclined to use the new settings abstractions to hide the details
 > of individual settings. So maybe something along the lines:
 >
 > (VisualWorksSettings settingWithId: #(tools browser showToolbar))
 >     value: false

This certainly is possible, but this wasn't the intention of my design.
This is very much like the old UISettings philosophy of the settings
framework also responsible for storing the setting values. The new
design is in fact exactly the opposite in that its philosophy is that
the Settings framework should be invisible to the code that uses the
settings.

Here is the politically correct view and usage.

Layer 1: Model level code

You have a parameter in your code that you want to make settable. For
example, you had a class-side method #defaultFoo which used to answer 42
and now you want to make Foo changeable. You add a shared variable or a
class instance variable or some other storage to the class, add a method
#defaultFoo: to set it, and change the #defaultFoo method to answer the
stored value instead of the hard-coded constant. This makes Foo a
"setting" in the Layer 1 sense.

IMPORTANT: This is the answer to the question in the subject. To change
a setting programmatically, use whatever facilities your (or someone
else's) application provides to set that value. The setting, in this
Layer 1 sense, is just a value in a shared variable somewhere. The
Settings framework does not and should not be in the picture.

Layer 2: The Settings framework

If you want not only to have a setting persistent in the current image,
but also to export its value into an external file and then import it
into another image, this is when the Settings framework comes into play.

In this case, you add a method marked with a <setting:...> pragma to a
settings domain class. This Setting declaration, apart from other
things, declares where the actual value of the Setting is stored in the
application.

IMPORTANT: Note that I use "Setting" with a capital S to refer to a
Setting in this Layer 2 sense, that is something declared to the
Settings framework, while a "setting" with a lowercase s is a setting in
Layer 1 sense, a shared variable or other shared storage holding a
parameter.

A Setting doesn't store the value of the setting, it only knows where to
get it and how to set it. You can point a Setting to a shared variable
using a literal binding reference, or you can point it to a class and a
pair of accessor methods. There are more exotic options as well. The
framework pulls that value out of wherever it's stored when exporting
the Settings and stores it there when importing.

Layer 3: The SettingsManager

SettingsManager is a tool that collects Settings of a domain and allows
the user to edit their values interactively in a central location. The
tool does not necessarily show all Settings of a domain--only those that
were included into pages declared by that domain. So, it is possible
that some Settings are not even visible in the tool. (For example, if
you don't want the setting to be directly user-editable, but still want
it to be exported to a settings file).

To sum up:

The Settings framework is designed to be an _add-on_ to support the
export and import of setting values, and let the user edit them
centrally through SettingsManager. Unlike the old VW UISettings, the
framework is not responsible for settings storage, or for managing
programmatic access to settings. That is assumed to be a responsibility
of the application that uses the settings. If an application uses
Settings correctly, it should be possible to strip the Settings out of
the image, while the application would keep working.

So, if you need to change a Setting programmatically, find where the
underlying setting is stored and change that. Coming back to Martin's
example, the correct way to change that setting is

        RefactoringBrowser showToolbar: false

(In SettingsManager, select "Show Page and Settings" from the list menu
to open a browser with definitions of all Settings on the current page).


--
Vassili Bykov <[hidden email]>

[:s | s, s printString] value: '[s: | s, s printString] value: '

Reply | Threaded
Open this post in threaded view
|

Re: Changing VW Settings programmatically ...

kobetic
Yes, that is certainly the right way for this particular setting. My
suggestion was mostly driven by the fact that the question was about VW
settings and many of those are still buried in the old settings, so to
do something similar for e.g. UI Feel you have to resort to something like

(UI.UISettings preferenceModelFor: #feelSelection)
        value: 'UI.CodingFeelPolicy' asQualifiedReference.
(UI.UISettings preferenceModelFor: #feelSelectionEditing)
        value: 'UI.CodingFeelPolicy' asQualifiedReference

And it took me a while to figure this out some time ago. So I figured
it's easier to rely on your abstraction layer at this point. Which will
keep working even if a setting gets moved. And I sure hope this one will
at some point :-).

Vassili Bykov wrote:

> So, if you need to change a Setting programmatically, find where the
> underlying setting is stored and change that. Coming back to Martin's
> example, the correct way to change that setting is
>
>     RefactoringBrowser showToolbar: false
>
> (In SettingsManager, select "Show Page and Settings" from the list menu
> to open a browser with definitions of all Settings on the current page).
>
>