FileLocator, icons, and deployment

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

FileLocator, icons, and deployment

Keith Alcock
Although the topic has been addressed to some extent in the thread "Re:
3.05 Image class>>fromFile:", it still isn't clear to me and other
people probably don't understand it either, so here's asking...

I have an application that runs nicely in the development environment
(using the DevelopmentSessionManager).  It even does well when I use the
ADK (with a RuntimeSessionManager) to make an executable running on the
development machine.  Hovever, if I move the application to another
machine that doesn't have the same directory structure or change the
directory name on the development machine, I lose the icons.

I'm using Dolphin Smalltalk 3.05 running on Win2000 and Win95 for
testing, although that is probably not relevant.  The icons are
contained in views (push buttons within container views within container
views within a shell) where they were originally specified for the
images with values like:

    Icon fromFile: 'c:\keith\smalltalk\equationgame\up.ico'.

I have also tried values like 'up.ico' and '.\up.ico', but usually let
the file open dialog determine the path.  Whatever I type, the full path
name gets displayed in the workspace.  This is probably because Dolphin
itself is installed in 'e:\Dolphin305' and the Icon uses a default file
locator which checks with the DevelopmentSessionManager for the
installationDirectory.  Since there is no relative way to get from e: to
c: under Windows, the path has to start over at the top.

As stated, this works just fine as long as the icons stay in that
particular directory.  They won't be doing that when the application
gets deployed on another machine, however.  As a first step toward a
solution, I would like the icons to simply be found in the same
directory as the deployed executable.  To that end I have made a class
StartupDirectoryLocator and changed the icon specification to

    Icon fromFile: 'up.ico' usingLocator: StartupDirectoryLocator new.

StartupDirectoryLocator is a class with two instance methods

localFileSpecFor: aStringFilename

 | rc |
 Transcript show: 'localFileSpecFor: ' , aStringFilename; cr.
 rc := File fullPathOf: aStringFilename relativeTo: self class
startupDirectory.
 Transcript show: rc; cr.
 ^rc.

relativePathTo: aFilename

 | rc |
 Transcript show: 'relativePathTo: ' , aFilename; cr.
 rc := File relativePathOf: aFilename to: self class startupDirectory.
 Transcript show: rc; cr.
 ^rc.

which are almost the exact same as the parent class methods except that
a StartupDirectory is used instead of the installationDirectory.
StartupDirectory is set by hand during at development time or by an
EquationGameSessionManager at runtime and self class startupDirectory
accesses it..

With all this in place, the workspace shows

    Icon fromId: 'up.ICO'

and the graphic is available...at least until I try to embed the view
just created into another view.  Then I get some question mark icon that
always shows up when something in the lookup process fails.  This icon
also shows up in the deployed application.


So, does anyone know the right way to do this?  Am I even close?  It
seems like the graphics might be stored in some sort of dictionary where
they need to be accessed by the file name on the development computer,
but for file access need the name of the file on the deployment
computer.  Maybe the intent is that people do not create a new
FileLocator, but instead override SessionManager functions like
installationDirectory.  (It's not as if there was an abundence of
documentation here.)

Please help!


Reply | Threaded
Open this post in threaded view
|

Re: FileLocator, icons, and deployment

Steve Waring-2
Hi Keith,

I feel your pain :)

1/. I think that a general strategy of having the code that creates the Icon
evaluate in the current session avoids the problems you mentioned. So for
example instead of evaluating Icon from.... in your development image, and
saving the result in an aspect, find a way to do this at run time.

I found a way that worked for me in V3, and I stuck with it. That was to
assign any icons to my classes, and in fact I did have some classes whos
sole purpose in life was to bring a resource into my image.

So my classes had a class side methods;
defaultIconName
^FileLocator default localFileSpecFor: 'resources\' , super defaultIconName

and;
icon
^##(self) instanceClass defaultIcon

So either my class had the icon I needed, or I would access the icon with
code such as

Up icon, or Up icon imageIndex etc.

(Note: I have had to modify this strategy in V4.0 to allow me to seemlessly
deploy projects as Applets, I had to create my own Locator class, which
answers FileLocator default in the development image, but gets set to the
"classLocator" if it finds itself running in a plug-in. However the
principle is the same)

2/. I think another thing that would make your life simplier, is if
possible, either develop in the directory;
SessionManager current installationDirectory, or at least store your
resources in;

"SessionManager current installationDirectory"/resources.

For me, if I copy an image over to another drive, and evaluate Icon
fromFile: 'resources\down.ico' usingLocator: FileLocator default, it will
point to;

'C:\Program Files\Dolphin Smalltalk 3.0\resources\down.ico', where my
SessionManager current installationDirectory = 'C:\Program Files\Dolphin
Smalltalk 3.0\'


If you look in Image(class)>>fromId: and fromId:in:, you can see that if
Dolphin doesnt find the resource in its resource library, it defaults to
using FileLocator default to find it. If you set your directory structure up
so that in your development image, the resources can be found relative to
SessionManager current installationDirectory, then it will make your life
simplier in a deployed image, where you just keep the same directory
structure relative to the executables image.

For the above example, I would use 'c:\myDeployedApp\Resources\down.ico'

> FileLocator, but instead override SessionManager functions like
> installationDirectory.  (It's not as if there was an abundence of
> documentation here.)


I personally wouldnt go down this path. Dolphin v4.0 shows that OA are
moving strongly towards Locators for this kind of work.

I hope this gives you some ideas to work with.
Steve


"Keith Alcock" <[hidden email]> wrote in message
news:[hidden email]...

> Although the topic has been addressed to some extent in the thread "Re:
> 3.05 Image class>>fromFile:", it still isn't clear to me and other
> people probably don't understand it either, so here's asking...
>
> I have an application that runs nicely in the development environment
> (using the DevelopmentSessionManager).  It even does well when I use the
> ADK (with a RuntimeSessionManager) to make an executable running on the
> development machine.  Hovever, if I move the application to another
> machine that doesn't have the same directory structure or change the
> directory name on the development machine, I lose the icons.
>
> I'm using Dolphin Smalltalk 3.05 running on Win2000 and Win95 for
> testing, although that is probably not relevant.  The icons are
> contained in views (push buttons within container views within container
> views within a shell) where they were originally specified for the
> images with values like:
>
>     Icon fromFile: 'c:\keith\smalltalk\equationgame\up.ico'.
>
> I have also tried values like 'up.ico' and '.\up.ico', but usually let
> the file open dialog determine the path.  Whatever I type, the full path
> name gets displayed in the workspace.  This is probably because Dolphin
> itself is installed in 'e:\Dolphin305' and the Icon uses a default file
> locator which checks with the DevelopmentSessionManager for the
> installationDirectory.  Since there is no relative way to get from e: to
> c: under Windows, the path has to start over at the top.
>
> As stated, this works just fine as long as the icons stay in that
> particular directory.  They won't be doing that when the application
> gets deployed on another machine, however.  As a first step toward a
> solution, I would like the icons to simply be found in the same
> directory as the deployed executable.  To that end I have made a class
> StartupDirectoryLocator and changed the icon specification to
>
>     Icon fromFile: 'up.ico' usingLocator: StartupDirectoryLocator new.
>
> StartupDirectoryLocator is a class with two instance methods
>
> localFileSpecFor: aStringFilename
>
>  | rc |
>  Transcript show: 'localFileSpecFor: ' , aStringFilename; cr.
>  rc := File fullPathOf: aStringFilename relativeTo: self class
> startupDirectory.
>  Transcript show: rc; cr.
>  ^rc.
>
> relativePathTo: aFilename
>
>  | rc |
>  Transcript show: 'relativePathTo: ' , aFilename; cr.
>  rc := File relativePathOf: aFilename to: self class startupDirectory.
>  Transcript show: rc; cr.
>  ^rc.
>
> which are almost the exact same as the parent class methods except that
> a StartupDirectory is used instead of the installationDirectory.
> StartupDirectory is set by hand during at development time or by an
> EquationGameSessionManager at runtime and self class startupDirectory
> accesses it..
>
> With all this in place, the workspace shows
>
>     Icon fromId: 'up.ICO'
>
> and the graphic is available...at least until I try to embed the view
> just created into another view.  Then I get some question mark icon that
> always shows up when something in the lookup process fails.  This icon
> also shows up in the deployed application.
>
>
> So, does anyone know the right way to do this?  Am I even close?  It
> seems like the graphics might be stored in some sort of dictionary where
> they need to be accessed by the file name on the development computer,
> but for file access need the name of the file on the deployment
> computer.  Maybe the intent is that people do not create a new
> FileLocator, but instead override SessionManager functions like
> installationDirectory.  (It's not as if there was an abundence of
> documentation here.)
>
> Please help!
>
>


Reply | Threaded
Open this post in threaded view
|

Re: FileLocator, icons, and deployment

Keith Alcock
Steve,

Thanks for the empathy and for the help.

For the (DSDN) record let it be known that I worked around the problem by
temporarily copying the resources to a subdirectory of the Dolphin installation
directory.  The application then tries to find them again in a subdirectory of
the same name but relative to the deployed application instead of the
development system.

If there is an opportunity to do so in the future, I will work on a design that
allows the development-time and run-time locations of the icons to vary more
idependently.  If I'm lucky, OA will find a (simpler) way for the resources to
be "resource compiled" into the exe file before then.  In that case there might
not be any resource files to track down.

Keith


Steve Waring wrote:

> Hi Keith,
>
> I feel your pain :)
>
> 1/. I think that a general strategy of having the code that creates the Icon
> evaluate in the current session avoids the problems you mentioned. So for
> example instead of evaluating Icon from.... in your development image, and
> saving the result in an aspect, find a way to do this at run time.
>
> I found a way that worked for me in V3, and I stuck with it. That was to
> assign any icons to my classes, and in fact I did have some classes whos
> sole purpose in life was to bring a resource into my image.
>
> So my classes had a class side methods;
> defaultIconName
> ^FileLocator default localFileSpecFor: 'resources\' , super defaultIconName
>
> and;
> icon
> ^##(self) instanceClass defaultIcon
>
> So either my class had the icon I needed, or I would access the icon with
> code such as
>
> Up icon, or Up icon imageIndex etc.
>
> (Note: I have had to modify this strategy in V4.0 to allow me to seemlessly
> deploy projects as Applets, I had to create my own Locator class, which
> answers FileLocator default in the development image, but gets set to the
> "classLocator" if it finds itself running in a plug-in. However the
> principle is the same)
>
> 2/. I think another thing that would make your life simplier, is if
> possible, either develop in the directory;
> SessionManager current installationDirectory, or at least store your
> resources in;
>
> "SessionManager current installationDirectory"/resources.
>
> For me, if I copy an image over to another drive, and evaluate Icon
> fromFile: 'resources\down.ico' usingLocator: FileLocator default, it will
> point to;
>
> 'C:\Program Files\Dolphin Smalltalk 3.0\resources\down.ico', where my
> SessionManager current installationDirectory = 'C:\Program Files\Dolphin
> Smalltalk 3.0\'
>
> If you look in Image(class)>>fromId: and fromId:in:, you can see that if
> Dolphin doesnt find the resource in its resource library, it defaults to
> using FileLocator default to find it. If you set your directory structure up
> so that in your development image, the resources can be found relative to
> SessionManager current installationDirectory, then it will make your life
> simplier in a deployed image, where you just keep the same directory
> structure relative to the executables image.
>
> For the above example, I would use 'c:\myDeployedApp\Resources\down.ico'
>
> > FileLocator, but instead override SessionManager functions like
> > installationDirectory.  (It's not as if there was an abundence of
> > documentation here.)
>
> I personally wouldnt go down this path. Dolphin v4.0 shows that OA are
> moving strongly towards Locators for this kind of work.
>
> I hope this gives you some ideas to work with.
> Steve
>
> "Keith Alcock" <[hidden email]> wrote in message
> news:[hidden email]...
> > Although the topic has been addressed to some extent in the thread "Re:
> > 3.05 Image class>>fromFile:", it still isn't clear to me and other
> > people probably don't understand it either, so here's asking...
> >
> > I have an application that runs nicely in the development environment
> > (using the DevelopmentSessionManager).  It even does well when I use the
> > ADK (with a RuntimeSessionManager) to make an executable running on the
> > development machine.  Hovever, if I move the application to another
> > machine that doesn't have the same directory structure or change the
> > directory name on the development machine, I lose the icons.
> >
> > I'm using Dolphin Smalltalk 3.05 running on Win2000 and Win95 for
> > testing, although that is probably not relevant.  The icons are
> > contained in views (push buttons within container views within container
> > views within a shell) where they were originally specified for the
> > images with values like:
> >
> >     Icon fromFile: 'c:\keith\smalltalk\equationgame\up.ico'.
> >
> > I have also tried values like 'up.ico' and '.\up.ico', but usually let
> > the file open dialog determine the path.  Whatever I type, the full path
> > name gets displayed in the workspace.  This is probably because Dolphin
> > itself is installed in 'e:\Dolphin305' and the Icon uses a default file
> > locator which checks with the DevelopmentSessionManager for the
> > installationDirectory.  Since there is no relative way to get from e: to
> > c: under Windows, the path has to start over at the top.
> >
> > As stated, this works just fine as long as the icons stay in that
> > particular directory.  They won't be doing that when the application
> > gets deployed on another machine, however.  As a first step toward a
> > solution, I would like the icons to simply be found in the same
> > directory as the deployed executable.  To that end I have made a class
> > StartupDirectoryLocator and changed the icon specification to
> >
> >     Icon fromFile: 'up.ico' usingLocator: StartupDirectoryLocator new.
> >
> > StartupDirectoryLocator is a class with two instance methods
> >
> > localFileSpecFor: aStringFilename
> >
> >  | rc |
> >  Transcript show: 'localFileSpecFor: ' , aStringFilename; cr.
> >  rc := File fullPathOf: aStringFilename relativeTo: self class
> > startupDirectory.
> >  Transcript show: rc; cr.
> >  ^rc.
> >
> > relativePathTo: aFilename
> >
> >  | rc |
> >  Transcript show: 'relativePathTo: ' , aFilename; cr.
> >  rc := File relativePathOf: aFilename to: self class startupDirectory.
> >  Transcript show: rc; cr.
> >  ^rc.
> >
> > which are almost the exact same as the parent class methods except that
> > a StartupDirectory is used instead of the installationDirectory.
> > StartupDirectory is set by hand during at development time or by an
> > EquationGameSessionManager at runtime and self class startupDirectory
> > accesses it..
> >
> > With all this in place, the workspace shows
> >
> >     Icon fromId: 'up.ICO'
> >
> > and the graphic is available...at least until I try to embed the view
> > just created into another view.  Then I get some question mark icon that
> > always shows up when something in the lookup process fails.  This icon
> > also shows up in the deployed application.
> >
> >
> > So, does anyone know the right way to do this?  Am I even close?  It
> > seems like the graphics might be stored in some sort of dictionary where
> > they need to be accessed by the file name on the development computer,
> > but for file access need the name of the file on the deployment
> > computer.  Maybe the intent is that people do not create a new
> > FileLocator, but instead override SessionManager functions like
> > installationDirectory.  (It's not as if there was an abundence of
> > documentation here.)
> >
> > Please help!
> >
> >