Difference between revisions of "Crash Course to Hollywood Programming/Example 3 - System-Friendly GUI"

From MorphOS Library

< Crash Course to Hollywood Programming

 
(6 intermediate revisions by the same user not shown)
Line 5: Line 5:
 
your own graphics and handle them in custom ways.
 
your own graphics and handle them in custom ways.
  
But luckily Hollywood has a powerful cross-platform plugin system, and there are many nice plugins [http://www.hollywood-mal.com/docs/html/hollywood/PluginsObtaining.html available] for it. Some of the
+
But luckily Hollywood has a powerful cross-platform plugin system, and there are many nice plugins [http://www.hollywood-mal.com/docs/html/hollywood/PluginsObtaining_.html available] for it. Some of the
 
most impressive ones are [http://forums.hollywood-mal.com/viewtopic.php?f=19&t=618 MUI Royale] and [http://forums.hollywood-mal.com/viewtopic.php?f=19&t=1381 RapaGUI] plugins, which can be used to create native system-friendly GUIs for applications.
 
most impressive ones are [http://forums.hollywood-mal.com/viewtopic.php?f=19&t=618 MUI Royale] and [http://forums.hollywood-mal.com/viewtopic.php?f=19&t=1381 RapaGUI] plugins, which can be used to create native system-friendly GUIs for applications.
 
Both are official plugins by the author of Hollywood, and thus well supported and [http://www.hollywood-mal.com/help.html documented].
 
Both are official plugins by the author of Hollywood, and thus well supported and [http://www.hollywood-mal.com/help.html documented].
Line 20: Line 20:
 
have learned one of these, it's easy to jump to the other too.
 
have learned one of these, it's easy to jump to the other too.
  
The most important thing to learn now is to look at information about [http://www.hollywood-mal.com/docs/html/muiroyale/Applicability.html applicability] in the [http://www.hollywood-mal.com/docs/html/muiroyale/ documentation]. Every available
+
The most important thing to learn now is to look at information about [http://www.hollywood-mal.com/docs/html/muiroyale/Applicability_.html applicability] in the [http://www.hollywood-mal.com/docs/html/muiroyale/ documentation]. Every available
 
object attribute has its applicability described on its documentation page. Applicability is simply marked with four letters: I, S, G,
 
object attribute has its applicability described on its documentation page. Applicability is simply marked with four letters: I, S, G,
 
and N. If there's '''I''', you can use the attribute at initialization, which means it can be used when writing the XML file.
 
and N. If there's '''I''', you can use the attribute at initialization, which means it can be used when writing the XML file.
Line 73: Line 73:
 
  <application base="HWEXAMPLE" id="app" dropobject="disp" icon="muiexample.info">
 
  <application base="HWEXAMPLE" id="app" dropobject="disp" icon="muiexample.info">
  
The application object is the master object, and all other definitions should be under it in the [http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationTree.html object tree].
+
The application object is the master object, and all other definitions should be under it in the [http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationTree_.html object tree].
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationBase.html base] attribute (applicability IG) is important here, because it defines what name is used when saving MUI preferences and it's also used when
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationBase_.html base] attribute (applicability IG) is important here, because it defines what name is used when saving MUI preferences and it's also used when
 
creating an ARexx port for the application. Don't use spaces or special characters, and try to pick a unique name that won't be
 
creating an ARexx port for the application. Don't use spaces or special characters, and try to pick a unique name that won't be
 
used by other programs.
 
used by other programs.
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/NotifyID.html id] attribute (I) is needed for every object you plan to access later from the Hollwood script. It's good to have it set for the
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/NotifyID_.html id] attribute (I) is needed for every object you plan to access later from the Hollwood script. It's good to have it set for the
 
application object too.
 
application object too.
  
 
The last two attributes are pretty much optional, but let's have them as examples, because they're quite useful in general. The
 
The last two attributes are pretty much optional, but let's have them as examples, because they're quite useful in general. The
[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationDropObject.html dropobject] attribute (IS) defines which object gets notified if you drag and drop a file onto its appicon. In this case the object
+
[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationDropObject_.html dropobject] attribute (IS) defines which object gets notified if you drag and drop a file onto its appicon. In this case the object
 
called "disp", which we'll define later, gets the notification.
 
called "disp", which we'll define later, gets the notification.
  
A program's application icon can be defined with the [http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationIcon.html icon] attribute (I). Without a path it takes the file from the directory the program
+
A program's application icon can be defined with the [http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationIcon_.html icon] attribute (I). Without a path it takes the file from the directory the program
 
was launched from.
 
was launched from.
  
Line 106: Line 106:
 
     </menustrip>
 
     </menustrip>
  
 +
[[File:HollywoodCourse-Example3-Menu.png|right]]
 
Every MUI application should contain a pull-down menu with items to open '''About MUI''' and '''About MUI Royale''' windows, and also an item
 
Every MUI application should contain a pull-down menu with items to open '''About MUI''' and '''About MUI Royale''' windows, and also an item
 
to open the '''MUI preferences''' program. We define a menu here and assign it later to the main window of our program. Remember to define
 
to open the '''MUI preferences''' program. We define a menu here and assign it later to the main window of our program. Remember to define
'''id''' attributes for all functional items as well as for the [http://www.hollywood-mal.com/docs/html/muiroyale/Menustrip.html menustrip] object itself. Let's also add our own about window as the first
+
'''id''' attributes for all functional items as well as for the [http://www.hollywood-mal.com/docs/html/muiroyale/Menustrip_.html menustrip] object itself. Let's also add our own about window as the first
 
item in the "Project" menu and a quit option as the last item. The '''<item/>''' line adds a separator bar to the menu.
 
item in the "Project" menu and a quit option as the last item. The '''<item/>''' line adds a separator bar to the menu.
  
 
If we want to get informed when the user has selected a menu item, we have to add notify tags to the items. Read more about the notification
 
If we want to get informed when the user has selected a menu item, we have to add notify tags to the items. Read more about the notification
mechanism [http://www.hollywood-mal.com/docs/html/muiroyale/Notifications.html here]. When we read the '''Menuitem class''' chapter from the [http://www.hollywood-mal.com/docs/html/muiroyale/ documentation], we can find out that the [http://www.hollywood-mal.com/docs/html/muiroyale/MenuitemSelected.html Selected] attribute has
+
mechanism [http://www.hollywood-mal.com/docs/html/muiroyale/Notifications_.html here]. When we read the '''Menuitem class''' chapter from the [http://www.hollywood-mal.com/docs/html/muiroyale/Menuitem_.html documentation], we can find out that the [http://www.hollywood-mal.com/docs/html/muiroyale/MenuitemSelected_.html Selected] attribute has
 
the applicability of N, and that means we can setup a notification for it. So, '''notify="selected"''' does the trick.
 
the applicability of N, and that means we can setup a notification for it. So, '''notify="selected"''' does the trick.
  
You can also define keyboard shortcuts for any of the menu items with the [http://www.hollywood-mal.com/docs/html/muiroyale/MenuitemShortcut.html Shortcut] attribute. In this example we can quit the program
+
You can also define keyboard shortcuts for any of the menu items with the [http://www.hollywood-mal.com/docs/html/muiroyale/MenuitemShortcut_.html Shortcut] attribute. In this example we can quit the program
 
by pressing the command-q key combination.
 
by pressing the command-q key combination.
  
Line 123: Line 124:
 
     <window id="win" muiid="MAIN" title="Hollywood MUI Example" screentitle="Hollywood MUI Example 1.0" notify="closerequest" menustrip="examplemenustrip" appwindow="true">
 
     <window id="win" muiid="MAIN" title="Hollywood MUI Example" screentitle="Hollywood MUI Example 1.0" notify="closerequest" menustrip="examplemenustrip" appwindow="true">
  
Then it's time to define our application [http://www.hollywood-mal.com/docs/html/muiroyale/Window.html window]. The most important attribute here is [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMuiID.html muiid], because without it users can't snapshot
+
Then it's time to define our application [http://www.hollywood-mal.com/docs/html/muiroyale/Window_.html window]. The most important attribute here is [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMuiID_.html muiid], because without it users can't snapshot
window size or position. [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMuiID.html muiid] has to be exactly four characters long, and each window in your program must have a different [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMuiID.html muiid] value.
+
window size or position. [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMuiID_.html muiid] has to be exactly four characters long, and each window in your program must have a different [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMuiID_.html muiid] value.
 
It doesn't matter if you use the same ID (like "MAIN") in different programs, because they save their settings to different files.
 
It doesn't matter if you use the same ID (like "MAIN") in different programs, because they save their settings to different files.
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/WindowTitle.html title] attribute sets the text in the window title bar of our program, and the [http://www.hollywood-mal.com/docs/html/muiroyale/WindowScreenTitle.html screentitle] attribute sets the text shown in the
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/WindowTitle_.html title] attribute sets the text in the window title bar of our program, and the [http://www.hollywood-mal.com/docs/html/muiroyale/WindowScreenTitle_.html screentitle] attribute sets the text shown in the
 
screen title bar when our window is active.
 
screen title bar when our window is active.
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/WindowCloseRequest.html closerequest] notify will tell us if the window's close gadget has been clicked, and we can react to it in our main Hollywood script.
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/WindowCloseRequest_.html closerequest] notify will tell us if the window's close gadget has been clicked, and we can react to it in our main Hollywood script.
  
The menu object we defined earlier can be specified for this window with the [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMenustrip.html menustrip] attribute. If you use multiple windows in
+
The menu object we defined earlier can be specified for this window with the [http://www.hollywood-mal.com/docs/html/muiroyale/WindowMenustrip_.html menustrip] attribute. If you use multiple windows in
 
an application and would like to see the same menu in all of them, move this attribute from the '''<window>''' definition to the '''<application>'''
 
an application and would like to see the same menu in all of them, move this attribute from the '''<window>''' definition to the '''<application>'''
 
definition.
 
definition.
  
The last [http://www.hollywood-mal.com/docs/html/muiroyale/WindowAppWindow.html appwindow] attribute lets us listen if an icon (a file) is dragged and dropped onto our program window. It can be left out
+
The last [http://www.hollywood-mal.com/docs/html/muiroyale/WindowAppWindow_.html appwindow] attribute lets us listen if an icon (a file) is dragged and dropped onto our program window. It can be left out
 
if you don't need it.
 
if you don't need it.
  
Line 146: Line 147:
 
             </hgroup>
 
             </hgroup>
  
The objects in our window can be organized in vertical or horizontal [http://www.hollywood-mal.com/docs/html/muiroyale/Groups.html groups]. Here we create a vertical group with smaller horizontal
+
[[File:HollywoodCourse-Example3.png|280px|thumb|Our MUI GUI example]]
 +
The objects in our window can be organized in vertical or horizontal [http://www.hollywood-mal.com/docs/html/muiroyale/Groups_.html groups]. Here we create a vertical group with smaller horizontal
 
groups inside it. On these lines we define that we get two buttons next to each other horizontally.
 
groups inside it. On these lines we define that we get two buttons next to each other horizontally.
  
If we read the '''Button class''' [http://www.hollywood-mal.com/docs/html/muiroyale/ documentation], we see that we can get notified by the [http://www.hollywood-mal.com/docs/html/muiroyale/ButtonPressed.html Pressed] attribute. We could also get notified
+
If we read the '''Button class''' [http://www.hollywood-mal.com/docs/html/muiroyale/Button_.html documentation], we see that we can get notified by the [http://www.hollywood-mal.com/docs/html/muiroyale/ButtonPressed_.html Pressed] attribute. We could also get notified
by the [http://www.hollywood-mal.com/docs/html/muiroyale/ButtonSelected.html Selected] attribute if we created a [http://www.hollywood-mal.com/docs/html/muiroyale/ButtonToggle.html toggle] button.
+
by the [http://www.hollywood-mal.com/docs/html/muiroyale/ButtonSelected_.html Selected] attribute if we created a [http://www.hollywood-mal.com/docs/html/muiroyale/ButtonToggle_.html toggle] button.
  
[http://www.hollywood-mal.com/docs/html/muiroyale/AreaCycleChain.html cyclechain] and [http://www.hollywood-mal.com/docs/html/muiroyale/AreaShortHelp.html shorthelp] attributes are interesting, because they aren't button specific. They are actually attributes
+
[http://www.hollywood-mal.com/docs/html/muiroyale/AreaCycleChain_.html cyclechain] and [http://www.hollywood-mal.com/docs/html/muiroyale/AreaShortHelp_.html shorthelp] attributes are interesting, because they aren't button specific. They are actually attributes
 
of the '''Area class''', which is a super class for almost everything else, and you can use its attributes with about all objects. When
 
of the '''Area class''', which is a super class for almost everything else, and you can use its attributes with about all objects. When
you are defining an object, you could also check the attributes from the '''Area class''' [http://www.hollywood-mal.com/docs/html/muiroyale/ documentation].
+
you are defining an object, you could also check the attributes from the '''Area class''' [http://www.hollywood-mal.com/docs/html/muiroyale/Area_.html documentation].
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/AreaCycleChain.html cyclechain] attribute defines if you can activate the object from the keyboard by using the '''tab''' key. You should usually allow this.
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/AreaCycleChain_.html cyclechain] attribute defines if you can activate the object from the keyboard by using the '''tab''' key. You should usually allow this.
  
The contents of the MUI bubble help text can be defined with the [http://www.hollywood-mal.com/docs/html/muiroyale/AreaShortHelp.html shorthelp] attribute. A bubble help window opens if you keep the mouse pointer
+
The contents of the MUI bubble help text can be defined with the [http://www.hollywood-mal.com/docs/html/muiroyale/AreaShortHelp_.html shorthelp] attribute. A bubble help window opens if you keep the mouse pointer
 
over an object for a while.
 
over an object for a while.
  
Line 178: Line 180:
 
resizing problems.
 
resizing problems.
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/Text.html text] object just displays some text, but we plan to update the text later with the current time. Let's put something as its initial
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/Text_.html text] object just displays some text, but we plan to update the text later with the current time. Let's put something as its initial
value anyway. The [http://www.hollywood-mal.com/docs/html/muiroyale/TextPreParse.html preparse] attribute contains a format code for the text, and we use it to right align the text now.
+
value anyway. The [http://www.hollywood-mal.com/docs/html/muiroyale/TextPreParse_.html preparse] attribute contains a format code for the text, and we use it to right align the text now.
  
  
Line 186: Line 188:
 
This object isn't inside of any horizonal group and takes the whole window width itself.
 
This object isn't inside of any horizonal group and takes the whole window width itself.
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/Hollywood.html hollywood] object embeds a complete Hollywood display inside the GUI. [http://www.hollywood-mal.com/docs/html/muiroyale/HollywoodDisplay.html display] defines the ID number of the Hollywood display you want
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/Hollywood_.html hollywood] object embeds a complete Hollywood display inside the GUI. [http://www.hollywood-mal.com/docs/html/muiroyale/HollywoodDisplay_.html display] defines the ID number of the Hollywood display you want
 
show in the object. Defining the sizes makes it resizeable too. If you want to make MUI programs without the graphical display of
 
show in the object. Defining the sizes makes it resizeable too. If you want to make MUI programs without the graphical display of
 
Hollywood, that's fine too.
 
Hollywood, that's fine too.
Line 201: Line 203:
 
==== Source Code ====
 
==== Source Code ====
 
  <nowiki>
 
  <nowiki>
 +
@VERSION 5,2
 
@APPTITLE "Hollywood MUI Example"
 
@APPTITLE "Hollywood MUI Example"
@APPVERSION "$VER: Hollywood MUI Example 1.0 (29.10.17)"
+
@APPVERSION "$VER: Hollywood MUI Example 1.0 (31.10.17)"
 
@APPDESCRIPTION "A Hollywood example program."
 
@APPDESCRIPTION "A Hollywood example program."
 
@REQUIRE "muiroyale", {Version=1, Revision=7}
 
@REQUIRE "muiroyale", {Version=1, Revision=7}
Line 246: Line 249:
 
         Case "menu_about":
 
         Case "menu_about":
 
             Local reqtext$ = "\27c\27bHollywood MUI Example\n\27nFor a tutorial at the MorphOS Library."
 
             Local reqtext$ = "\27c\27bHollywood MUI Example\n\27nFor a tutorial at the MorphOS Library."
             If mui.Request("About", reqtext$, "Open tutorial|*OK") Then OpenURL("http://www.google.fi")
+
             If mui.Request("About", reqtext$, "Open tutorial|*OK") Then OpenURL("http://library.morph.zone/Crash_Course_to_Hollywood_Programming")
 
         Case "menu_about_mui":
 
         Case "menu_about_mui":
             mui.DoMethod("app", "aboutmui")
+
             mui.DoMethod("app", "AboutMUI")
 
         Case "menu_about_muiroyale":
 
         Case "menu_about_muiroyale":
             mui.DoMethod("app", "aboutmuiroyale")
+
             mui.DoMethod("app", "AboutMUIRoyale")
 
         Case "menu_quit":
 
         Case "menu_quit":
 
             End
 
             End
 
         Case "menu_muisettings":
 
         Case "menu_muisettings":
             mui.DoMethod("app", "openconfigwindow")
+
             mui.DoMethod("app", "OpenConfigWindow")
 
         EndSwitch
 
         EndSwitch
 
     Case "Button":
 
     Case "Button":
Line 290: Line 293:
  
  
  [http://www.hollywood-mal.com/docs/html/hollywood/atREQUIRE.html @REQUIRE] "muiroyale", {Version=1, Revision=7}
+
  [http://www.hollywood-mal.com/docs/html/hollywood/atREQUIRE_.html @REQUIRE] "muiroyale", {Version=1, Revision=7}
  
With this [http://www.hollywood-mal.com/docs/html/hollywood/PrgPreproc.html preprocessor] statement we can ensure that we have new enough version of the MUI Royale plugin available. In this case we make sure that
+
With this [http://www.hollywood-mal.com/docs/html/hollywood/PrgPreproc_.html preprocessor] statement we can ensure that we have new enough version of the MUI Royale plugin available. In this case we make sure that
 
we have at least MUI Royale 1.7 in use.
 
we have at least MUI Royale 1.7 in use.
  
  
  [http://www.hollywood-mal.com/docs/html/hollywood/atDISPLAY.html @DISPLAY] {Hidden=True, Width=400, Height=300, Sizeable=True, Layers=True, ScaleMode=#SCALEMODE_LAYER, SmoothScale=True}
+
  [http://www.hollywood-mal.com/docs/html/hollywood/atDISPLAY_.html @DISPLAY] {Hidden=True, Width=400, Height=300, Sizeable=True, Layers=True, ScaleMode=#SCALEMODE_LAYER, SmoothScale=True}
  
 
Hollywood opens its initial display window automatically, but when we plan to open a separate MUI window with the Hollywood display
 
Hollywood opens its initial display window automatically, but when we plan to open a separate MUI window with the Hollywood display
inside it, we can tell Hollywood to keep its display hidden at startup. Let's add a '''Hidden=True''' item to the [http://www.hollywood-mal.com/docs/html/hollywood/atDISPLAY.html @DISPLAY] preprocessor table.
+
inside it, we can tell Hollywood to keep its display hidden at startup. Let's add a '''Hidden=True''' item to the [http://www.hollywood-mal.com/docs/html/hollywood/atDISPLAY_.html @DISPLAY] preprocessor table.
  
 
We can also remove the ''Title'' and ''ScreenTitle'' items, because we have defined them in the XML file for the MUI GUI already.
 
We can also remove the ''Title'' and ''ScreenTitle'' items, because we have defined them in the XML file for the MUI GUI already.
  
  
  [http://www.hollywood-mal.com/docs/html/hollywood/atFILE.html @FILE] 1, "muigui.xml"
+
  [http://www.hollywood-mal.com/docs/html/hollywood/atFILE_.html @FILE] 1, "muigui.xml"
  
 
This preprocessor command opens our GUI definition file for later use. We could open or load the file by other means later too, but when
 
This preprocessor command opens our GUI definition file for later use. We could open or load the file by other means later too, but when
Line 313: Line 316:
 
  Function p_DrawGfx(brush_number)
 
  Function p_DrawGfx(brush_number)
 
     If Not brush_number Then brush_number = Rnd(2) + 1
 
     If Not brush_number Then brush_number = Rnd(2) + 1
     If [http://www.hollywood-mal.com/docs/html/hollywood/LayerExists.html LayerExists]("gfx") Then [http://www.hollywood-mal.com/docs/html/hollywood/RemoveLayerFX.html RemoveLayerFX]("gfx")
+
     If [http://www.hollywood-mal.com/docs/html/hollywood/LayerExists_.html LayerExists]("gfx") Then [http://www.hollywood-mal.com/docs/html/hollywood/RemoveLayerFX_.html RemoveLayerFX]("gfx")
     [http://www.hollywood-mal.com/docs/html/muiroyale/muiSet.html mui.Set]("win", "title", "Brush " .. brush_number)
+
     [http://www.hollywood-mal.com/docs/html/muiroyale/muiSet_.html mui.Set]("win", "title", "Brush " .. brush_number)
     [http://www.hollywood-mal.com/docs/html/hollywood/DisplayBrushFX.html DisplayBrushFX](brush_number, #CENTER, #CENTER)
+
     [http://www.hollywood-mal.com/docs/html/hollywood/DisplayBrushFX_.html DisplayBrushFX](brush_number, #CENTER, #CENTER)
     [http://www.hollywood-mal.com/docs/html/hollywood/SetLayerName.html SetLayerName](0, "gfx")
+
     [http://www.hollywood-mal.com/docs/html/hollywood/SetLayerName_.html SetLayerName](0, "gfx")
 
  EndFunction
 
  EndFunction
  
Line 323: Line 326:
 
Now we accept a brush number as a parameter for it and assign a random value only if nothing was given.
 
Now we accept a brush number as a parameter for it and assign a random value only if nothing was given.
  
We'll also use MUI to change the window title text. The '''Window class''' section in the MUI Royale [http://www.hollywood-mal.com/docs/html/muiroyale/ documentation] reveals that there
+
We'll also use MUI to change the window title text. The '''Window class''' section in the MUI Royale [http://www.hollywood-mal.com/docs/html/muiroyale/Window_.html documentation] reveals that there
is a [http://www.hollywood-mal.com/docs/html/muiroyale/WindowTitle.html Title] attribute, which can be changed from our script, because it has '''S''' (set) marked in its applicability information.
+
is a [http://www.hollywood-mal.com/docs/html/muiroyale/WindowTitle_.html Title] attribute, which can be changed from our script, because it has '''S''' (set) marked in its applicability information.
The [http://www.hollywood-mal.com/docs/html/muiroyale/muiSet.html mui.Set] function can be used to set values of attributes, and we pass to it the ID of our MUI window, the name of the argument we want
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/muiSet_.html mui.Set] function can be used to set values of attributes, and we pass to it the ID of our MUI window, the name of the argument we want
 
to change, and a new value for it.
 
to change, and a new value for it.
  
  
 
  Function p_MUIEvent(msg)
 
  Function p_MUIEvent(msg)
     [http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint.html DebugPrint]("MUI event!", "  Class:", msg.Class, "  ID:", msg.ID, "  Attribute:", msg.Attribute)
+
     [http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint_.html DebugPrint]("MUI event!", "  Class:", msg.Class, "  ID:", msg.ID, "  Attribute:", msg.Attribute)
  
 
Here is a new function to handle MUI events. We could handle them in the same input event handler we made earlier, but let's keep them
 
Here is a new function to handle MUI events. We could handle them in the same input event handler we made earlier, but let's keep them
 
separated for clarity now.
 
separated for clarity now.
  
The [http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint.html DebugPrint]() line shows us the class that triggered the event, the ID of the object, and the attribute that changed.
+
The [http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint_.html DebugPrint]() line shows us the class that triggered the event, the ID of the object, and the attribute that changed.
  
  
Line 342: Line 345:
 
         Switch msg.Attribute
 
         Switch msg.Attribute
 
         Case "CloseRequest":
 
         Case "CloseRequest":
             [http://www.hollywood-mal.com/docs/html/hollywood/End.html End]
+
             [http://www.hollywood-mal.com/docs/html/hollywood/End_.html End]
 
         EndSwitch
 
         EndSwitch
  
If the class was '''Window''' and the attribute was [http://www.hollywood-mal.com/docs/html/muiroyale/WindowCloseRequest.html CloseRequest] (the close gadget was pressed), we quit the whole program with the [http://www.hollywood-mal.com/docs/html/hollywood/End.html End]()
+
If the class was '''Window''' and the attribute was [http://www.hollywood-mal.com/docs/html/muiroyale/WindowCloseRequest_.html CloseRequest] (the close gadget was pressed), we quit the whole program with the [http://www.hollywood-mal.com/docs/html/hollywood/End_.html End]()
 
function. Hollywood closes the MUI window and frees the resources automatically.
 
function. Hollywood closes the MUI window and frees the resources automatically.
  
Line 356: Line 359:
  
 
         Case "menu_about":
 
         Case "menu_about":
             [http://www.hollywood-mal.com/docs/html/hollywood/PrgLocals.html Local] reqtext$ = "\27c\27bHollywood MUI Example\27n\nFor a tutorial at the MorphOS Library."
+
             [http://www.hollywood-mal.com/docs/html/hollywood/PrgLocals_.html Local] reqtext$ = "\27c\27bHollywood MUI Example\27n\nFor a tutorial at the MorphOS Library."
             If [http://www.hollywood-mal.com/docs/html/muiroyale/muiRequest.html mui.Request]("About", reqtext$, "Open tutorial|*OK") Then [http://www.hollywood-mal.com/docs/html/hollywood/OpenURL.html OpenURL]("http://www.google.fi")
+
             If [http://www.hollywood-mal.com/docs/html/muiroyale/muiRequest_.html mui.Request]("About", reqtext$, "Open tutorial|*OK") Then [http://www.hollywood-mal.com/docs/html/hollywood/OpenURL_.html OpenURL]("http://library.morph.zone/Crash_Course_to_Hollywood_Programming")
  
This is our own about window for the program. We declare a [http://www.hollywood-mal.com/docs/html/hollywood/PrgLocals.html local variable] with a string in it, and because it's a '''string variable''' we use
+
[[File:HollywoodCourse-Example3-About.png|right|247px]]
a '''dollar sign''' as the last character of the variable name. It would work without the dollar sign too, but it's a [http://www.hollywood-mal.com/docs/html/hollywood/PrgStyleguideSuggestions.html style guide] suggestion
+
This is our own about window for the program. We declare a [http://www.hollywood-mal.com/docs/html/hollywood/PrgLocals_.html local variable] with a string in it, and because it's a '''string variable''' we use
 +
a '''dollar sign''' as the last character of the variable name. It would work without the dollar sign too, but it's a [http://www.hollywood-mal.com/docs/html/hollywood/PrgStyleguideSuggestions_.html style guide] suggestion
 
in Hollywood to separate '''strings ($)''' and '''floating point values (!)''' from integer values.
 
in Hollywood to separate '''strings ($)''' and '''floating point values (!)''' from integer values.
  
The string itself may look a bit cryptic, because we have used some [http://www.hollywood-mal.com/docs/html/muiroyale/TextFormat.html formatting codes] as an example here. '''\27c''' centers the text,
+
The string itself may look a bit cryptic, because we have used some [http://www.hollywood-mal.com/docs/html/muiroyale/TextFormat_.html formatting codes] as an example here. '''\27c''' centers the text,
 
'''\27b''' makes the text bold, '''\27n''' resets the text style back to normal, and '''\n''' starts a new line. Notice that we use '''\27''' here while
 
'''\27b''' makes the text bold, '''\27n''' resets the text style back to normal, and '''\n''' starts a new line. Notice that we use '''\27''' here while
 
we used '''\33''' in the XML file.
 
we used '''\33''' in the XML file.
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/muiRequest.html mui.Request]() function is an easy way to pop up a MUI system requester. We have only two buttons in it this time, so we can directly
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/muiRequest_.html mui.Request]() function is an easy way to pop up a MUI system requester. We have only two buttons in it this time, so we can directly
check the result with the [http://www.hollywood-mal.com/docs/html/hollywood/PrgIf.html If statement] on the same line. If the user selects the "Open tutorial" button, the result will be "1" and we open
+
check the result with the [http://www.hollywood-mal.com/docs/html/hollywood/PrgIf_.html If statement] on the same line. If the user selects the "Open tutorial" button, the result will be "1" and we open
the web page with the [http://www.hollywood-mal.com/docs/html/hollywood/OpenURL.html OpenURL]() function. The "OK" button will return 0 and nothing happens then. '''*''' can be used to mark which button
+
the web page with the [http://www.hollywood-mal.com/docs/html/hollywood/OpenURL_.html OpenURL]() function. The "OK" button will return 0 and nothing happens then. '''*''' can be used to mark which button
 
is pre-selected by default.
 
is pre-selected by default.
  
  
 
         Case "menu_about_mui":
 
         Case "menu_about_mui":
             [http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod.html mui.DoMethod]("app", "[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationAboutMUI.html aboutmui]")
+
             [http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod_.html mui.DoMethod]("app", "[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationAboutMUI_.html AboutMUI]")
 
         Case "menu_about_muiroyale":
 
         Case "menu_about_muiroyale":
             [http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod.html mui.DoMethod]("app", "[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationAboutMUIRoyale.html aboutmuiroyale]")
+
             [http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod_.html mui.DoMethod]("app", "[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationAboutMUIRoyale_.html AboutMUIRoyale]")
 
         Case "menu_quit":
 
         Case "menu_quit":
             [http://www.hollywood-mal.com/docs/html/hollywood/End.html End]
+
             [http://www.hollywood-mal.com/docs/html/hollywood/End_.html End]
 
         Case "menu_muisettings":
 
         Case "menu_muisettings":
             [http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod.html mui.DoMethod]("app", "[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationOpenConfigWindow.html openconfigwindow]")
+
             [http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod_.html mui.DoMethod]("app", "[http://www.hollywood-mal.com/docs/html/muiroyale/ApplicationOpenConfigWindow_.html OpenConfigWindow]")
 
         EndSwitch
 
         EndSwitch
  
 
Opening other about windows is pretty automatic with the MUI methods provided by the Application class. The methods can be run using the
 
Opening other about windows is pretty automatic with the MUI methods provided by the Application class. The methods can be run using the
[http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod.html mui.DoMethod]() function.
+
[http://www.hollywood-mal.com/docs/html/muiroyale/muiDoMethod_.html mui.DoMethod]() function.
  
  
Line 404: Line 408:
  
 
  Function p_UpdateClock()
 
  Function p_UpdateClock()
     [http://www.hollywood-mal.com/docs/html/muiroyale/muiSet.html mui.Set]("clock", "contents", GetTime(True))
+
     [http://www.hollywood-mal.com/docs/html/muiroyale/muiSet_.html mui.Set]("clock", "contents", GetTime(True))
 
  EndFunction
 
  EndFunction
  
 
We also created a text object to our GUI with the ID "clock". Here is a short function to set its contents to the result we get
 
We also created a text object to our GUI with the ID "clock". Here is a short function to set its contents to the result we get
from the [http://www.hollywood-mal.com/docs/html/hollywood/GetTime.html GetTime]() function. [http://www.hollywood-mal.com/docs/html/hollywood/GetTime.html GetTime]() is found in the Time library, and if you set its optional argument to '''True''', it will return
+
from the [http://www.hollywood-mal.com/docs/html/hollywood/GetTime_.html GetTime]() function. [http://www.hollywood-mal.com/docs/html/hollywood/GetTime_.html GetTime]() is found in the Time library, and if you set its optional argument to '''True''', it will return
 
the time in the '''hh:mm:ss''' format instead of the '''hh:mm''' format.
 
the time in the '''hh:mm:ss''' format instead of the '''hh:mm''' format.
  
  
  [http://www.hollywood-mal.com/docs/html/muiroyale/muiCreateGUI.html mui.CreateGUI]([http://www.hollywood-mal.com/docs/html/hollywood/ReadString.html ReadString](1))
+
  [http://www.hollywood-mal.com/docs/html/muiroyale/muiCreateGUI_.html mui.CreateGUI]([http://www.hollywood-mal.com/docs/html/hollywood/ReadString_.html ReadString](1))
  
The [http://www.hollywood-mal.com/docs/html/muiroyale/muiCreateGUI.html mui.CreateGUI]() function creates the actual GUI from an XML source code string. You could put the string into a Hollywood script too,
+
The [http://www.hollywood-mal.com/docs/html/muiroyale/muiCreateGUI_.html mui.CreateGUI]() function creates the actual GUI from an XML source code string. You could put the string into a Hollywood script too,
 
but it's more comfortable to have the XML source in a separate file for any bigger projects.
 
but it's more comfortable to have the XML source in a separate file for any bigger projects.
  
As we already opened the file with the [http://www.hollywood-mal.com/docs/html/hollywood/atFILE.html @FILE] preprocessor command, we can just use the [http://www.hollywood-mal.com/docs/html/hollywood/ReadString.html ReadString]() function with the file ID number as an
+
As we already opened the file with the [http://www.hollywood-mal.com/docs/html/hollywood/atFILE_.html @FILE] preprocessor command, we can just use the [http://www.hollywood-mal.com/docs/html/hollywood/ReadString_.html ReadString]() function with the file ID number as an
 
argument to get the file returned as a string.
 
argument to get the file returned as a string.
  
  
  [http://www.hollywood-mal.com/docs/html/hollywood/InstallEventHandler.html InstallEventHandler]({OnKeyDown = p_Input, OnMouseDown = p_Input, MUIRoyale = p_MUIEvent})
+
  [http://www.hollywood-mal.com/docs/html/hollywood/InstallEventHandler_.html InstallEventHandler]({OnKeyDown = p_Input, OnMouseDown = p_Input, MUIRoyale = p_MUIEvent})
  
 
We'll have to install the '''MUIRoyale''' event handler to get MUI related notifications to our '''p_MUIEvent()''' function.
 
We'll have to install the '''MUIRoyale''' event handler to get MUI related notifications to our '''p_MUIEvent()''' function.
  
  
  [http://www.hollywood-mal.com/docs/html/hollywood/SetInterval.html SetInterval](1, p_UpdateClock, 1000)
+
  [http://www.hollywood-mal.com/docs/html/hollywood/SetInterval_.html SetInterval](1, p_UpdateClock, 1000)
  
The [http://www.hollywood-mal.com/docs/html/hollywood/SetInterval.html SetInterval]() function can be used to trigger events periodically. Here we create a new '''interval''' function which calls our '''p_UpdateClock()'''
+
The [http://www.hollywood-mal.com/docs/html/hollywood/SetInterval_.html SetInterval]() function can be used to trigger events periodically. Here we create a new '''interval''' function which calls our '''p_UpdateClock()'''
 
function repeatedly at 1000 ms intervals. Our clock gets updated once per second now.
 
function repeatedly at 1000 ms intervals. Our clock gets updated once per second now.
  

Latest revision as of 17:34, 2 November 2017

System-Friendly GUI Example

Preface

Standard Hollywood applications are somewhat limited when implementing GUI functionality into them. System menus and all kinds of requesters can be made, but if you want buttons or other GUI elements inside the Hollywood display, you have to draw them with your own graphics and handle them in custom ways.

But luckily Hollywood has a powerful cross-platform plugin system, and there are many nice plugins available for it. Some of the most impressive ones are MUI Royale and RapaGUI plugins, which can be used to create native system-friendly GUIs for applications. Both are official plugins by the author of Hollywood, and thus well supported and documented.

MUI Royale, as its name suggests, allows you to create MUI GUIs for Amiga compatible platforms. RapaGUI, on the other hand, is a beast at its own level, because it allows you to create GUIs that work on several completely different platforms using the underlying GUI toolkit on each platform. Be it Windows, Linux, Mac, or Amiga compatible, you just write one GUI definition and it'll work on every OS without modifications. When you run a RapaGUI application, it will look and feel just like other programs on each platform, because it uses MUI on Amiga compatibles, GTK on Linux, and so on.

Both MUI Royale and RapaGUI are very similar - the definition of a GUI is created by writing an XML file, which is then included into your Hollywood program. The following example is made with MUI Royale, because we are now focusing on Hollywood programming under MorphOS, and MUI Royale offers a bit more operating system specific features than the more generic RapaGUI. In any case, when you have learned one of these, it's easy to jump to the other too.

The most important thing to learn now is to look at information about applicability in the documentation. Every available object attribute has its applicability described on its documentation page. Applicability is simply marked with four letters: I, S, G, and N. If there's I, you can use the attribute at initialization, which means it can be used when writing the XML file. S (set value of a MUI object attribute) and G (get value of a MUI object attribute) can be used from the actual Hollywood script at runtime. N can be used in both to handle notifications of attributes.


XML File

Source Code

<?xml version="1.0" encoding="iso-8859-1"?>
<application base="HWEXAMPLE" id="app" dropobject="disp" icon="muiexample.info">
    <menustrip id="examplemenustrip">
        <menu title="Project">
            <item id="menu_about" notify="selected">About...</item>
            <item id="menu_about_mui" notify="selected">About MUI...</item>
            <item id="menu_about_muiroyale" notify="selected">About MUI Royale...</item>
            <item/>
            <item id="menu_quit" notify="selected" shortcut="Q">Quit</item>
        </menu>
        <menu title="Settings">
            <item id="menu_muisettings" notify="selected">MUI...</item>
        </menu>
    </menustrip>
    <window id="win" muiid="MAIN" title="Hollywood MUI Example" screentitle="Hollywood MUI Example 1.0" notify="closerequest" menustrip="examplemenustrip" appwindow="true">
        <vgroup>
            <hgroup>
                <button id="button1" notify="pressed" cyclechain="true" shorthelp="Displays brush 1">Brush _1</button>
                <button id="button2" notify="pressed" cyclechain="true" shorthelp="Displays brush 2">Brush _2</button>
            </hgroup>
            <hgroup>
                <button id="button_random" notify="pressed" cyclechain="false" shorthelp="Displays a random brush">_Random</button>
                <rectangle/>
                <text id="clock" preparse="\33r">00:00:00</text>
            </hgroup>
            <hollywood id="disp" display="1" minwidth="32" minheight="32" maxwidth="16384" maxheight="16384" notify="appmessage"/>
        </vgroup>
    </window>
</application>

Description

Let's have a look at the XML file first. Create a text file and save it as muigui.xml.


<?xml version="1.0" encoding="iso-8859-1"?>

This is a standard XML prologue line, and the file should start with it. ISO-8859-1 might be a safer bet than UTF-8 in our case. Version means the version of the XML markup language, not the application version. Just copy and paste this line as is.


<application base="HWEXAMPLE" id="app" dropobject="disp" icon="muiexample.info">

The application object is the master object, and all other definitions should be under it in the object tree.

The base attribute (applicability IG) is important here, because it defines what name is used when saving MUI preferences and it's also used when creating an ARexx port for the application. Don't use spaces or special characters, and try to pick a unique name that won't be used by other programs.

The id attribute (I) is needed for every object you plan to access later from the Hollwood script. It's good to have it set for the application object too.

The last two attributes are pretty much optional, but let's have them as examples, because they're quite useful in general. The dropobject attribute (IS) defines which object gets notified if you drag and drop a file onto its appicon. In this case the object called "disp", which we'll define later, gets the notification.

A program's application icon can be defined with the icon attribute (I). Without a path it takes the file from the directory the program was launched from.

As you can see, all of these attributes have I in their applicability information. When you browse the documentation and look for new attributes or how to do things, applicability tells if you can use them in the XML file or during the program execution.


    <menustrip id="examplemenustrip">
        <menu title="Project">
            <item id="menu_about" notify="selected">About...</item>
            <item id="menu_about_mui" notify="selected">About MUI...</item>
            <item id="menu_about_muiroyale" notify="selected">About MUI Royale...</item>
            <item/>
            <item id="menu_quit" notify="selected" shortcut="Q">Quit</item>
        </menu>
        <menu title="Settings">
            <item id="menu_muisettings" notify="selected">MUI...</item>
        </menu> 
    </menustrip>
HollywoodCourse-Example3-Menu.png

Every MUI application should contain a pull-down menu with items to open About MUI and About MUI Royale windows, and also an item to open the MUI preferences program. We define a menu here and assign it later to the main window of our program. Remember to define id attributes for all functional items as well as for the menustrip object itself. Let's also add our own about window as the first item in the "Project" menu and a quit option as the last item. The <item/> line adds a separator bar to the menu.

If we want to get informed when the user has selected a menu item, we have to add notify tags to the items. Read more about the notification mechanism here. When we read the Menuitem class chapter from the documentation, we can find out that the Selected attribute has the applicability of N, and that means we can setup a notification for it. So, notify="selected" does the trick.

You can also define keyboard shortcuts for any of the menu items with the Shortcut attribute. In this example we can quit the program by pressing the command-q key combination.

Remember the traditional Amiga style guide too. If an item opens a new interactive window or requester, add ... at the end of it.


    <window id="win" muiid="MAIN" title="Hollywood MUI Example" screentitle="Hollywood MUI Example 1.0" notify="closerequest" menustrip="examplemenustrip" appwindow="true">

Then it's time to define our application window. The most important attribute here is muiid, because without it users can't snapshot window size or position. muiid has to be exactly four characters long, and each window in your program must have a different muiid value. It doesn't matter if you use the same ID (like "MAIN") in different programs, because they save their settings to different files.

The title attribute sets the text in the window title bar of our program, and the screentitle attribute sets the text shown in the screen title bar when our window is active.

The closerequest notify will tell us if the window's close gadget has been clicked, and we can react to it in our main Hollywood script.

The menu object we defined earlier can be specified for this window with the menustrip attribute. If you use multiple windows in an application and would like to see the same menu in all of them, move this attribute from the <window> definition to the <application> definition.

The last appwindow attribute lets us listen if an icon (a file) is dragged and dropped onto our program window. It can be left out if you don't need it.


        <vgroup>
            <hgroup>
                <button id="button1" notify="pressed" cyclechain="true" shorthelp="Displays brush 1">Brush _1</button>
                <button id="button2" notify="pressed" cyclechain="true" shorthelp="Displays brush 2">Brush _2</button>
            </hgroup>
Our MUI GUI example

The objects in our window can be organized in vertical or horizontal groups. Here we create a vertical group with smaller horizontal groups inside it. On these lines we define that we get two buttons next to each other horizontally.

If we read the Button class documentation, we see that we can get notified by the Pressed attribute. We could also get notified by the Selected attribute if we created a toggle button.

cyclechain and shorthelp attributes are interesting, because they aren't button specific. They are actually attributes of the Area class, which is a super class for almost everything else, and you can use its attributes with about all objects. When you are defining an object, you could also check the attributes from the Area class documentation.

The cyclechain attribute defines if you can activate the object from the keyboard by using the tab key. You should usually allow this.

The contents of the MUI bubble help text can be defined with the shorthelp attribute. A bubble help window opens if you keep the mouse pointer over an object for a while.

An underscore in the button label makes the following character a keyboard shortcut. We can press "1" or "2" from the keyboard to make a button press now.


            <hgroup>
                <button id="button_random" notify="pressed" cyclechain="false" shorthelp="Displays a random brush">_Random</button>
                <rectangle/>
                <text id="clock" preparse="\33r">00:00:00</text>
            </hgroup>

Here we define another horizontal group whose objects are shown below the previous group.

The new button here is removed from the cyclechain as an example; you can't activate it with the tab key.

<rectangle/> adds some dynamic space between two objects. This can be quite useful when designing a GUI, and especially if you have some resizing problems.

The text object just displays some text, but we plan to update the text later with the current time. Let's put something as its initial value anyway. The preparse attribute contains a format code for the text, and we use it to right align the text now.


            <hollywood id="disp" display="1" minwidth="32" minheight="32" maxwidth="16384" maxheight="16384" notify="appmessage"/>

This object isn't inside of any horizonal group and takes the whole window width itself.

The hollywood object embeds a complete Hollywood display inside the GUI. display defines the ID number of the Hollywood display you want show in the object. Defining the sizes makes it resizeable too. If you want to make MUI programs without the graphical display of Hollywood, that's fine too.


        </vgroup>
    </window>
</application> 

After finishing our definitions we have working code for the GUI part of our program!


Hollywood Script

Source Code

@VERSION 5,2
@APPTITLE "Hollywood MUI Example"
@APPVERSION "$VER: Hollywood MUI Example 1.0 (31.10.17)"
@APPDESCRIPTION "A Hollywood example program."
@REQUIRE "muiroyale", {Version=1, Revision=7}
@DISPLAY {Hidden=True, Width=400, Height=300, Sizeable=True, Layers=True, ScaleMode=#SCALEMODE_LAYER, SmoothScale=True}
@BRUSH 1, "MOSSYS:Data/Jalapeno/ReadMode.png", {LoadAlpha=True}
@FILE 1, "muigui.xml"

Function p_DrawGfx(brush_number)
    If Not brush_number Then brush_number = Rnd(2) + 1
    If LayerExists("gfx") Then RemoveLayerFX("gfx")
    mui.Set("win", "title", "Brush " .. brush_number)
    DisplayBrushFX(brush_number, #CENTER, #CENTER)
    SetLayerName(0, "gfx")
EndFunction

Function p_Input(msg)
    DebugPrint("Input event!", msg.Action)
    Switch(msg.Action)
    Case "OnKeyDown":
        DebugPrint(msg.Key, "key was pressed.")
        Switch(msg.Key)
        Case " ":
            p_DrawGfx()
        Case "ESC":
            DebugPrint("Quitting...")
            End
        EndSwitch
    Case "OnMouseDown":
        p_DrawGfx()
    EndSwitch
EndFunction

Function p_MUIEvent(msg)
    DebugPrint("MUI event!", "  Class:", msg.Class, "  ID:", msg.ID, "  Attribute:", msg.Attribute)
    Switch msg.Class
    Case "Window":
        Switch msg.Attribute
        Case "CloseRequest":
            End
        EndSwitch
    Case "Menuitem":
        Switch msg.ID
        Case "menu_about":
            Local reqtext$ = "\27c\27bHollywood MUI Example\n\27nFor a tutorial at the MorphOS Library."
            If mui.Request("About", reqtext$, "Open tutorial|*OK") Then OpenURL("http://library.morph.zone/Crash_Course_to_Hollywood_Programming")
        Case "menu_about_mui":
            mui.DoMethod("app", "AboutMUI")
        Case "menu_about_muiroyale":
            mui.DoMethod("app", "AboutMUIRoyale")
        Case "menu_quit":
            End
        Case "menu_muisettings":
            mui.DoMethod("app", "OpenConfigWindow")
        EndSwitch
    Case "Button":
        Switch msg.ID
        Case "button1":
            p_DrawGfx(1)
        Case "button2":
            p_DrawGfx(2)
        Case "button_random":
            p_DrawGfx()
        EndSwitch
    EndSwitch
EndFunction

Function p_UpdateClock()
    mui.Set("clock", "contents", GetTime(True))
EndFunction

mui.CreateGUI(ReadString(1))

InstallEventHandler({OnKeyDown = p_Input, OnMouseDown = p_Input, MUIRoyale = p_MUIEvent})
SetInterval(1, p_UpdateClock, 1000)

LoadBrush(2, "MOSSYS:Data/Jalapeno/TrackMode.png", {LoadAlpha = True})
p_DrawGfx()

Repeat
   WaitEvent
Forever

Description

Let's modify our previous example (Example 2: Hollywood Programming) script to work with the MUI GUI now, and add some fancy new features as well.


@REQUIRE "muiroyale", {Version=1, Revision=7}

With this preprocessor statement we can ensure that we have new enough version of the MUI Royale plugin available. In this case we make sure that we have at least MUI Royale 1.7 in use.


@DISPLAY {Hidden=True, Width=400, Height=300, Sizeable=True, Layers=True, ScaleMode=#SCALEMODE_LAYER, SmoothScale=True}

Hollywood opens its initial display window automatically, but when we plan to open a separate MUI window with the Hollywood display inside it, we can tell Hollywood to keep its display hidden at startup. Let's add a Hidden=True item to the @DISPLAY preprocessor table.

We can also remove the Title and ScreenTitle items, because we have defined them in the XML file for the MUI GUI already.


@FILE 1, "muigui.xml"

This preprocessor command opens our GUI definition file for later use. We could open or load the file by other means later too, but when it's opened with the preprocessor command the file gets linked into the executable when we compile the program. This way we don't have to have a plaintext GUI definition file distributed with our compiled software.


Function p_DrawGfx(brush_number)
    If Not brush_number Then brush_number = Rnd(2) + 1
    If LayerExists("gfx") Then RemoveLayerFX("gfx")
    mui.Set("win", "title", "Brush " .. brush_number)
    DisplayBrushFX(brush_number, #CENTER, #CENTER)
    SetLayerName(0, "gfx")
EndFunction

Let's change our drawing function a bit as well.

Now we accept a brush number as a parameter for it and assign a random value only if nothing was given.

We'll also use MUI to change the window title text. The Window class section in the MUI Royale documentation reveals that there is a Title attribute, which can be changed from our script, because it has S (set) marked in its applicability information. The mui.Set function can be used to set values of attributes, and we pass to it the ID of our MUI window, the name of the argument we want to change, and a new value for it.


Function p_MUIEvent(msg)
    DebugPrint("MUI event!", "  Class:", msg.Class, "  ID:", msg.ID, "  Attribute:", msg.Attribute)

Here is a new function to handle MUI events. We could handle them in the same input event handler we made earlier, but let's keep them separated for clarity now.

The DebugPrint() line shows us the class that triggered the event, the ID of the object, and the attribute that changed.


    Switch msg.Class
    Case "Window":
        Switch msg.Attribute
        Case "CloseRequest":
            End
        EndSwitch

If the class was Window and the attribute was CloseRequest (the close gadget was pressed), we quit the whole program with the End() function. Hollywood closes the MUI window and frees the resources automatically.


    Case "Menuitem":
        Switch msg.ID

If the event came from the Menuitem class, it's enough to check which object triggered it. The IDs are the same we defined in the XML file.


        Case "menu_about":
            Local reqtext$ = "\27c\27bHollywood MUI Example\27n\nFor a tutorial at the MorphOS Library."
            If mui.Request("About", reqtext$, "Open tutorial|*OK") Then OpenURL("http://library.morph.zone/Crash_Course_to_Hollywood_Programming")
HollywoodCourse-Example3-About.png

This is our own about window for the program. We declare a local variable with a string in it, and because it's a string variable we use a dollar sign as the last character of the variable name. It would work without the dollar sign too, but it's a style guide suggestion in Hollywood to separate strings ($) and floating point values (!) from integer values.

The string itself may look a bit cryptic, because we have used some formatting codes as an example here. \27c centers the text, \27b makes the text bold, \27n resets the text style back to normal, and \n starts a new line. Notice that we use \27 here while we used \33 in the XML file.

The mui.Request() function is an easy way to pop up a MUI system requester. We have only two buttons in it this time, so we can directly check the result with the If statement on the same line. If the user selects the "Open tutorial" button, the result will be "1" and we open the web page with the OpenURL() function. The "OK" button will return 0 and nothing happens then. * can be used to mark which button is pre-selected by default.


        Case "menu_about_mui":
            mui.DoMethod("app", "AboutMUI")
        Case "menu_about_muiroyale":
            mui.DoMethod("app", "AboutMUIRoyale")
        Case "menu_quit":
            End
        Case "menu_muisettings":
            mui.DoMethod("app", "OpenConfigWindow")
        EndSwitch

Opening other about windows is pretty automatic with the MUI methods provided by the Application class. The methods can be run using the mui.DoMethod() function.


    Case "Button":
        Switch msg.ID
        Case "button1":
            p_DrawGfx(1)
        Case "button2":
            p_DrawGfx(2)
        Case "button_random":
            p_DrawGfx()
        EndSwitch
    EndSwitch
EndFunction

Finally we handle button presses. We can now select which brush to show, or press the random button to call our drawing function without a defined brush number.


Function p_UpdateClock()
    mui.Set("clock", "contents", GetTime(True))
EndFunction

We also created a text object to our GUI with the ID "clock". Here is a short function to set its contents to the result we get from the GetTime() function. GetTime() is found in the Time library, and if you set its optional argument to True, it will return the time in the hh:mm:ss format instead of the hh:mm format.


mui.CreateGUI(ReadString(1))

The mui.CreateGUI() function creates the actual GUI from an XML source code string. You could put the string into a Hollywood script too, but it's more comfortable to have the XML source in a separate file for any bigger projects.

As we already opened the file with the @FILE preprocessor command, we can just use the ReadString() function with the file ID number as an argument to get the file returned as a string.


InstallEventHandler({OnKeyDown = p_Input, OnMouseDown = p_Input, MUIRoyale = p_MUIEvent})

We'll have to install the MUIRoyale event handler to get MUI related notifications to our p_MUIEvent() function.


SetInterval(1, p_UpdateClock, 1000)

The SetInterval() function can be used to trigger events periodically. Here we create a new interval function which calls our p_UpdateClock() function repeatedly at 1000 ms intervals. Our clock gets updated once per second now.


And there it is! Our first MUI program made with Hollywood. If you have saved the Hollwood script as, for example, muiexample.hws, and you have muigui.xml and muiroyale.hwp files in the same directory, you can run the program with the Hollywood muiexample.hws -quiet command from the shell or with the F4 key in Cubic IDE. And if you compile the program, you don't need the muigui.xml file in the same directory any more.

The muiroyale.hwp plugin file can be installed into the SYS:Libs/Hollywood/ directory to be always available for your programs, but when distributing them I'd advice to have a copy of it in the same directory with the executable. That way users don't need to install anything and it doesn't matter if they don't have the correct version in their Libs directory.


< Proceed to the summary chapter