Difference between revisions of "Crash Course to Hollywood Programming"

From MorphOS Library

(6 intermediate revisions by the same user not shown)
Line 36: Line 36:
 
(Windows-only APK Compiler is required for the Android support).
 
(Windows-only APK Compiler is required for the Android support).
  
 +
[[File:HollywoodCourse-CubicIDE.gif|frame|240px|Cubic IDE with the Hollywood add-on]]
 
[http://www.hollywood-mal.com/designer.html Hollywood Designer] is an Amiga-only add-on to create multimedia presentations in a WYSIWYG GUI. It works
 
[http://www.hollywood-mal.com/designer.html Hollywood Designer] is an Amiga-only add-on to create multimedia presentations in a WYSIWYG GUI. It works
 
on Amiga compatible platforms including MorphOS, but the resulting presentations can be compiled for any
 
on Amiga compatible platforms including MorphOS, but the resulting presentations can be compiled for any
Line 57: Line 58:
  
 
=== Running a Script ===
 
=== Running a Script ===
+
 
 
Hollywood scripts can be run from the Hollywood main executable (the interpreter), and while the main executable
 
Hollywood scripts can be run from the Hollywood main executable (the interpreter), and while the main executable
 
accepts tens of command line [http://www.hollywood-mal.com/docs/html/hollywood/ManualUsage.html arguments], you don't usually need many of them.
 
accepts tens of command line [http://www.hollywood-mal.com/docs/html/hollywood/ManualUsage.html arguments], you don't usually need many of them.
Line 65: Line 66:
  
  
 +
[[File:HollywoodCourse-Run.png|thumb|240px|Running a script]]
 
To run a script from the shell:
 
To run a script from the shell:
 
  Hollywood MyProgram.hws
 
  Hollywood MyProgram.hws
Line 73: Line 75:
  
  
 +
[[File:HollywoodCourse-ResourceMonitor.png|thumb|116px|Resource monitor]]
 
Hollywood has a built-in resource monitor, which can be activated with the '''-resourcemonitor''' argument.
 
Hollywood has a built-in resource monitor, which can be activated with the '''-resourcemonitor''' argument.
 
You should check the resources your application uses and that you aren't increasing the memory usage
 
You should check the resources your application uses and that you aren't increasing the memory usage
Line 89: Line 92:
 
  Hollywood MyProgram.hws -compile MyProgram
 
  Hollywood MyProgram.hws -compile MyProgram
  
 +
[[File:HollywoodCourse-Compile.png|thumb|240px|Compiling a script]]
 
With the above command you get an executable called "MyProgram" that will run on the same archtecture it
 
With the above command you get an executable called "MyProgram" that will run on the same archtecture it
 
was compiled on.
 
was compiled on.
Line 98: Line 102:
  
 
Or for multiple platforms at once:
 
Or for multiple platforms at once:
  Hollywood MyProgram.hws -compile MyProgram.exe -exetype morphos|amigaos4|win32|applet
+
  Hollywood MyProgram.hws -compile MyProgram -exetype morphos|amigaos4|win32|applet
  
  
 
If you want to compress your own data (script and linked data files), add the '''-compress''' argument:
 
If you want to compress your own data (script and linked data files), add the '''-compress''' argument:
  Hollywood MyProgram.hws -compile MyProgram.exe -exetype morphos|amigaos4|win32|applet -compress
+
  Hollywood MyProgram.hws -compile MyProgram -exetype morphos|amigaos4|win32|applet -compress
  
 
Compressing can make executables smaller, but it also "hides" any plaintext data from the executables if
 
Compressing can make executables smaller, but it also "hides" any plaintext data from the executables if
Line 112: Line 116:
  
  
== First Test ==
+
== Examples ==
 
 
Let's type this into a text editor and save it as a file called '''RAM:firsttest.hws''':
 
[http://www.hollywood-mal.com/docs/html/hollywood/atBGPIC.html @BGPIC] 1, "SYS:MorphOS/Prefs/Wallpapers/1024x768/Arida.png"
 
[http://www.hollywood-mal.com/docs/html/hollywood/TextOut.html TextOut](100,10,"Hello World!")
 
[http://www.hollywood-mal.com/docs/html/hollywood/WaitLeftMouse.html WaitLeftMouse]()
 
; Program exits after the last line in a script, but you can also terminate it with the [http://www.hollywood-mal.com/docs/html/hollywood/End.html End]() command
 
 
 
The first line is a [http://www.hollywood-mal.com/docs/html/hollywood/PrgPreproc.html preprocessor command] which loads the given image file as a Hollywood background
 
picture. Objects in Hollywood are handled by their '''ID numbers''', and in this case we load the image as
 
a bgpic number 1. That bgpic is also loaded initially when the application opens its window.
 
 
 
All preprocessor commands are prefixed with the '''@''' character and processed before the actual
 
script execution. Data files loaded with the preprocessor commands are also '''linked''' into the executable when
 
compiling a program. If you don't want to link the files, you can load them separately later in the script.
 
 
 
The second line prints the "Hello World!" text at x=100, y=10 (in pixels) over the background image.
 
 
 
The third line waits for the user to press the left mouse button. Without this line, the program would just end
 
and close its window, and we wouldn't see much.
 
 
 
The last line is a [http://www.hollywood-mal.com/docs/html/hollywood/PrgComments.html comment] line, which is just a note inside the code. Comment lines can be inserted between
 
'''/*''' and '''*/''', or the rest of the line can be commented out with the ''';''' character.
 
 
 
 
 
Let's run the script to see the results. Hit the F4 key in Cubic IDE or type this in the shell:
 
Hollywood RAM:firsttest.hws -quiet
 
 
 
Hollywood opens a new window and takes its dimensions from the background picture. If we wouldn't preload any
 
background picture, then the display would be opened in the default 640x480 resolution, or you could define
 
its dimensions with the [http://www.hollywood-mal.com/docs/html/hollywood/atDISPLAY.html @DISPLAY] preprocessor command.
 
 
 
 
 
Next let's compile the program into a standalone executable. Hit the F2 key in Cubic IDE or use the shell (you don't
 
have to define the paths if you've already changed directory to RAM: in the shell):
 
Hollywood RAM:firsttest.hws -compile RAM:firsttest
 
 
 
Now we have a new executable file that also contains the preprocessed/linked background graphics in it. The program
 
works even if you don't have the ''Arida.png'' file in the system.
 
 
 
 
 
== Hollywood Programming Example ==
 
 
 
The previous example could be extended to have more commands to be executed in batch, which could be fine for
 
presentations or slideshows, but let's take a more practical approach and create an interactive script whose
 
structure looks like a real program.
 
 
 
 
 
[http://www.hollywood-mal.com/docs/html/hollywood/atAPPTITLE.html @APPTITLE] "Hollywood Example"
 
[http://www.hollywood-mal.com/docs/html/hollywood/atAPPVERSION.html @APPVERSION] "$VER: Hollywood Example 1.0 (26.10.17)"
 
[http://www.hollywood-mal.com/docs/html/hollywood/atAPPDESCRIPTION.html @APPDESCRIPTION] "A Hollywood example program."
 
 
 
There are several preprocessor commands for adding informative strings to an application. These three are especially
 
useful for Amiga and MorphOS programs, because Hollywood programs act like commodities and you'll see this information
 
in, for example, the Exchange program. The @APPVERSION format should respect the standard version string rules,
 
which means that the date should be given in the DD.MM.YY format etc.
 
 
 
 
 
 
 
[http://www.hollywood-mal.com/docs/html/hollywood/atDISPLAY.html @DISPLAY] {Title="Hollywood Example", ScreenTitle="Hollywood Example", Width=400, Height=300, Sizeable=True, Layers=True, ScaleMode=#SCALEMODE_LAYER, SmoothScale=True}
 
 
 
This time we don't use the [http://www.hollywood-mal.com/docs/html/hollywood/atBGPIC.html @BGPIC] preprocessor, but define the display size manually and add some extra
 
attributes too.
 
 
 
'''Title''' defines what will be shown in the window title bar, and '''ScreenTitle''' what is shown in the screen title bar
 
when our program window is active.
 
 
 
The '''Width''' and '''Height''' attributes define the actual drawing area (display) for our application. The application window
 
itself will be a bit larger with the standard OS window borders added around a Hollywood display. It is also
 
possible to open borderless and fullscreen windows without the standard window borders.
 
 
 
The '''Sizeable''' attribute defines if the application window is resizeable by the user.
 
 
 
'''Layers=True''' enables Hollywood's [http://www.hollywood-mal.com/docs/html/hollywood/LayersIntroduction.html layer system]. It depends on the program you're developing whether you want to enable
 
layers or not. With layers enabled all drawing operations get their own layer that can be moved, removed, and
 
otherwise processed. When they're disabled, all graphics are just painted over each other on the display and it's
 
harder to change or undo things. But if you're just drawing fullscreen graphics to the display or something like
 
that, it's better to keep layers disabled.
 
 
 
'''ScaleMode''' sets if display contents are scaled automatically when the display size changes. Many times
 
it's better to keep this disabled and recalculate your own graphics after a resize event to keep the aspect
 
ratio intact and to avoid slowdowns, but let's enable this now to get more functionality into our application without
 
extra lines of code.
 
 
 
'''SmoothScale''' makes the scaling output prettier at the expense of speed.
 
 
 
 
 
[http://www.hollywood-mal.com/docs/html/hollywood/atBRUSH.html @BRUSH] 1, "MOSSYS:Data/Jalapeno/ReadMode.png", {LoadAlpha=True}
 
 
 
Brushes are the most common way to load, process, and display graphics in Hollywood. This preprocessor line loads
 
a PNG image as a brush with ID number 1. All brush handling operations are done by referring to the ID number from
 
now on. The last argument is an optional table containing any extra options for loading. We are using graphics
 
with an alpha channel (transparency) now, so we tell Hollywood to load alpha channel values too.
 
 
 
 
 
Function p_DrawGfx()
 
    [http://www.hollywood-mal.com/docs/html/hollywood/PrgLocals.html Local] brush_number = [http://www.hollywood-mal.com/docs/html/hollywood/Rnd.html 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")
 
    [http://www.hollywood-mal.com/docs/html/hollywood/SetDisplayAttributes.html SetDisplayAttributes]({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/SetLayerName.html SetLayerName](0, "gfx")
 
EndFunction
 
 
 
This is how you create your own [http://www.hollywood-mal.com/docs/html/hollywood/PrgFunctions.html functions] in Hollywood. Our own function names should always start with the '''p_''' prefix
 
to distinguish them from Hollywood's internal functions. In this case the function doesn't take any parameters and
 
doesn't return any values, it can just be called from the program with p_DrawGfx() to run the lines inside it.
 
 
 
The purpose of this function is to show one of the two brushes we have in memory. The brush ID numbers are 1 and 2, and
 
we randomly pick one of them. Because we have the [http://www.hollywood-mal.com/docs/html/hollywood/LayersIntroduction.html layer system] enabled, we get a new layer every time we draw a brush
 
into the display. To avoid ending up with unlimited number of layers we remove an existing layer first. We also
 
change the window title bar text to show the number of the shown brush.
 
 
 
The first line of the function declares a new local variable called brush_number and assigns a random value (1 or 2)
 
to it. You should declare new variables as local whenever possible; read more about it [http://www.hollywood-mal.com/docs/html/hollywood/PrgLocals.html here].
 
 
 
The second line checks if we already have a specific layer created, and removes it with a fancy random effect if we do.
 
This line is just skipped when the function is called the first time, because we don't have the specific layer yet.
 
 
 
The third line changes the window title text to the brush number we got on the first line. Almost all display attributes
 
can be changed on the fly, and you aren't restricted to the ones you defined with the [http://www.hollywood-mal.com/docs/html/hollywood/atDISPLAY.html @DISPLAY] preprocessor command.
 
Here you can also see how you can combine a string from other strings or variables with the '''..''' operator, which is
 
familiar from Lua.
 
 
 
[http://www.hollywood-mal.com/docs/html/hollywood/DisplayBrushFX.html DisplayBrushFX]() shows the selected brush and creates a new layer on the layer stack. The position of the brush can be given
 
in pixels, but also using [http://www.hollywood-mal.com/docs/html/hollywood/PrgInbuiltCst.html inbuilt constants] like '''#CENTER'''. '''FX''' at the end of the function name indicates that there's a
 
transition effect displayed when the function is called. In most cases they are a bit over the top, and you probably
 
end up using [http://www.hollywood-mal.com/docs/html/hollywood/DisplayBrush.html DisplayBrush]() or other options to render the graphics.
 
 
 
Layers get ID numbers automatically and they are assigned dynamically, which means that removing a layer changes the ID
 
numbers of the layers on top of it. To make life easier we can name the layers and handle them by their names
 
instead of their ID numbers. [http://www.hollywood-mal.com/docs/html/hollywood/SetLayerName.html SetLayerName]() is one way to do that, and we use it to name the layer with the brush here.
 
The function accepts a layer ID number and name as parameters. Our displayed brush creates the first layer on the layer
 
stack and its ID number will thus be 1. [http://www.hollywood-mal.com/docs/html/hollywood/SetLayerName.html SetLayerName](1,"gfx") would work in this case, and our layer would get the name "gfx"
 
as intended. But to make life even easier we can give '''ID number 0''' as the first parameter, and the name will be given to the last
 
created layer. This way you don't have to keep count of layers at all.
 
 
 
 
 
Function p_Input(msg)
 
    [http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint.html DebugPrint]("Input event!", msg.Action)
 
    Switch(msg.Action)
 
    Case "OnKeyDown":
 
        [http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint.html DebugPrint](msg.Key, "key was pressed.")
 
        Switch(msg.Key)
 
        Case " ":
 
            p_DrawGfx()
 
        Case "ESC":
 
            [http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint.html DebugPrint]("Quitting...")
 
            End
 
        EndSwitch
 
    Case "OnMouseDown":
 
        p_DrawGfx()
 
    EndSwitch
 
EndFunction
 
 
 
Here's another function created by us. It is used to handle user input events. Event handling functions will get a
 
message table as their parameter, and we'll get it as a local variable called "msg".
 
 
 
[http://www.hollywood-mal.com/docs/html/hollywood/DebugPrint.html DebugPrint]() is a useful function for checking what values we have in certain variables during the program execution. Don't
 
hesitate to use it temporarily to learn what results you get from different functions and what values you have in variables.
 
Here it is used to print the '''Action''' field from the message table, which tells us the name of the event that occured.
 
 
 
If the user presses a key, we get an '''OnKeyDown''' event, and if the user presses the left mouse button, we get an '''OnMouseDown''' event.
 
A full list of standard events can be found [http://www.hollywood-mal.com/docs/html/hollywood/InstallEventHandler.html here].
 
 
 
We handle different events with a [http://www.hollywood-mal.com/docs/html/hollywood/PrgSwitch.html Switch-Case] statement in this example, but feel free to handle it in other ways if you please. It
 
is also possible to have a separate function for each event.
 
 
 
If we take a look at the [http://www.hollywood-mal.com/docs/html/hollywood/InstallEventHandler.html documentation], we see that the '''OnKeyDown''' event contains the exact key that was pressed in its '''Key'''
 
field. It can be accessed with the '''msg.Key''' table item in our function.
 
 
 
The inner [http://www.hollywood-mal.com/docs/html/hollywood/PrgSwitch.html Switch-Case] statement checks if the pressed key was space or escape. If it was '''space''', our previous drawing function
 
is called and you get new graphics on the display, whereas pressing the '''escape''' key quits the program with a message. Pressing any
 
other keys will just print the key without doing anything else.
 
 
 
Pressing the '''left mouse button''' also calls our previous drawing function, and the display gets refreshed.
 
 
 
 
 
[http://www.hollywood-mal.com/docs/html/hollywood/LoadBrush.html LoadBrush](2, "MOSSYS:Data/Jalapeno/TrackMode.png", {LoadAlpha=True})
 
 
 
The first image in our example program was loaded with the [http://www.hollywood-mal.com/docs/html/hollywood/atBRUSH.html @BRUSH] preprocessor command, but let's load the second image separately.
 
The difference between them is that by doing the latter the image doesn't get linked into our executable file when we compile the program. The image
 
is loaded from the filesystem every time you run the program, no matter if it's compiled or not.
 
 
 
 
 
p_DrawGfx()
 
 
 
Now that we have both images loaded as brushes, we can call the function we defined earlier, and we get some graphics shown in
 
the application window.
 
 
 
 
 
[http://www.hollywood-mal.com/docs/html/hollywood/InstallEventHandler.html InstallEventHandler]({OnKeyDown = p_Input, OnMouseDown = p_Input})
 
 
 
Our previously defined p_Input() function doesn't get any events unless we install event handlers. A table passed to the
 
[http://www.hollywood-mal.com/docs/html/hollywood/InstallEventHandler.html InstallEventHandler]() function defines which events are listened to and what functions they call when triggered. Here
 
we define both '''OnKeyDown''' and '''OnMouseDown''' events to call our own '''p_Input()''' function, and user input will work from now on.
 
As you can see, events can call the same function or they can be made to call other functions if necessary.
 
 
 
 
 
Repeat
 
    [http://www.hollywood-mal.com/docs/html/hollywood/WaitEvent.html WaitEvent]
 
Forever
 
 
 
This is the main loop of the program. The [http://www.hollywood-mal.com/docs/html/hollywood/WaitEvent.html WaitEvent] function is called repeatedly as long as our program is running and it only
 
waits for any event to happen. The program just sleeps and doesn't waste any CPU time when there aren't any events.
 
 
 
 
 
== System-Friendly GUI Example ==
 
 
 
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 [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.
 
Both are official plugins by the author of Hollywood, and thus well supported and [http://www.hollywood-mal.com/help.html 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.
 
 
 
So, let's start.
 
 
 
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,
 
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.
 
 
 
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 [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
 
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 [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.
 
 
 
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
 
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
 
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>
 
 
 
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 [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.
 
 
 
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
 
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
 
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 [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.
 
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
 
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 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>'''
 
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
 
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>
 
 
 
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.
 
 
 
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
 
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
 
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].
 
 
 
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
 
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 [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.
 
 
 
 
 
            <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 [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
 
Hollywood, that's fine too.
 
 
 
 
 
        </vgroup>
 
    </window>
 
</application>
 
 
 
After finishing our definitions we have working code for the GUI part of our program!
 
 
 
 
 
Let's modify our previous example script to work with the MUI GUI now, and add some fancy new features as well.
 
 
 
 
 
[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
 
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}
 
 
 
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.
 
 
 
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"
 
 
 
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 [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/hollywood/DisplayBrushFX.html DisplayBrushFX](brush_number, #CENTER, #CENTER)
 
    [http://www.hollywood-mal.com/docs/html/hollywood/SetLayerName.html 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 [http://www.hollywood-mal.com/docs/html/muiroyale/ 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.
 
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.
 
 
 
 
 
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)
 
 
 
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 [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.
 
 
 
 
 
    Switch msg.Class
 
    Case "Window":
 
        Switch msg.Attribute
 
        Case "CloseRequest":
 
            [http://www.hollywood-mal.com/docs/html/hollywood/End.html End]
 
        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]()
 
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":
 
            [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")
 
 
 
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.
 
 
 
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
 
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
 
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
 
is pre-selected by default.
 
 
 
 
 
        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]")
 
        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]")
 
        Case "menu_quit":
 
            [http://www.hollywood-mal.com/docs/html/hollywood/End.html End]
 
        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]")
 
        EndSwitch
 
 
 
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.
 
 
 
 
 
    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()
 
    [http://www.hollywood-mal.com/docs/html/muiroyale/muiSet.html 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 [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.
 
 
 
 
 
[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,
 
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
 
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})
 
 
 
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)
 
 
 
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.
 
  
 +
* [[Crash_Course_to_Hollywood_Programming/Example_1_-_The_First_Test|Example 1: The First Test]]
 +
* [[Crash_Course_to_Hollywood_Programming/Example_2_-_Hollywood_Programming|Example 2: Hollywood Programming]]
 +
* [[Crash_Course_to_Hollywood_Programming/Example_3_-_System-Friendly_GUI|Example 3: System-Friendly GUI]]
  
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 <code>Hollywood muiexample.hws -quiet</code> 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''' [http://www.hollywood-mal.com/download.html 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.
 
  
 +
== Summary ==
  
 
This tutorial has hopefully given you some understanding of Hollywood programming, and it should be easier to learn more about the language
 
This tutorial has hopefully given you some understanding of Hollywood programming, and it should be easier to learn more about the language
Line 649: Line 138:
 
* [http://forums.hollywood-mal.com/ Hollywood forums]
 
* [http://forums.hollywood-mal.com/ Hollywood forums]
 
* [https://www.softwareandcircuits.com/division/amiga/products/cubic/index.html Cubic IDE]
 
* [https://www.softwareandcircuits.com/division/amiga/products/cubic/index.html Cubic IDE]
* [https://morph.zone Discussion about this article and MorphOS programming]
+
* [http://jpv.wmhost.com/morphos/hollywood/ Files from this tutorial]
* [http://jpv.wmhost.com/ Files from this tutorial]
 

Revision as of 18:39, 30 October 2017

Author: jPV/RNO (Proofreading by Marq)

Preface

Hollywood - the cross-platform multimedia application layer - is an easy programming/scripting language that is designed for the creation of graphical or multimedia-oriented applications, but it can also be used to create other kinds of programs, especially with its comprehensive selection of plugins. Hollywood is loosely based on the popular Lua language.

Hollywood programs are created by writing script files, which are then run from the Hollywood main program, or they can be compiled into applets or standalone executables to be used without the Hollywood environment.

Applets are small platform-independent binary files which can be run using the free Hollywood player on any supported platform. Standalone executables contain the player, a script and optional data files linked into a single executable file. Linking the whole player binary into an executable makes the minimum size of Hollywood executables around 2 megabytes on MorphOS, but then the resulting programs are completely independent and can be run out of the box without any prior installation.

What makes Hollywood special is its ability to cross-compile programs between all supported platforms. Windows, Linux, OS X, or Amiga programs can be compiled just by using MorphOS, and so on. Cross-compiled programs don't usually need any modifications and the same source script will work on all platforms.

Hollywood is an easy, safe, and very well documented language, and thus also suitable for beginners. All Hollywood programs run inside a sandbox, and you can't break or crash the underlying operating system with your programming mistakes. If there's a bug causing an error in the script execution, Hollywood just closes the program and frees the resources with no further harm.


Getting Started

Requirements

Hollywood

Hollywood is a commercial product which can be bought here. The main package is enough for Hollywood programming and compiling for all other platforms except Android (Windows-only APK Compiler is required for the Android support).

Cubic IDE with the Hollywood add-on

Hollywood Designer is an Amiga-only add-on to create multimedia presentations in a WYSIWYG GUI. It works on Amiga compatible platforms including MorphOS, but the resulting presentations can be compiled for any other supported platform. Anyway, it isn't required for programming with Hollywood, but your own code can be inserted into presentation scripts too.


Text Editor

Hollywood features an IDE (integrated development environment) for Windows, but on other platforms a text editor or a 3rd party IDE is needed.

Cubic IDE offers the best development environment for Hollywood programming on MorphOS. With the Cubic IDE add-on you'll get syntax highlighting, automatic casing, online help, quick access to documentation, automatic indentation, bracket matching, auto completion of keywords, compile and run options, and a lot more.

MiniHollyEdit NG could also be a good freeware option, but it's broken in its current state and needs an update first.

An IDE with Hollywood support is the most comfortable solution of course, but any other text editor will also do.


Running a Script

Hollywood scripts can be run from the Hollywood main executable (the interpreter), and while the main executable accepts tens of command line arguments, you don't usually need many of them.

When you're developing and testing your application, it's enough to just run the script without compiling it. It's a good practise to save your scripts with the .hws extension.


Running a script

To run a script from the shell:

Hollywood MyProgram.hws


And without the information window:

Hollywood MyProgram.hws -quiet


Resource monitor

Hollywood has a built-in resource monitor, which can be activated with the -resourcemonitor argument. You should check the resources your application uses and that you aren't increasing the memory usage carelessly:

Hollywood MyProgram.hws -resourcemonitor


If you're using Cubic IDE, you don't need the shell at all. You can just press the F4 key to run the script or select other running options from Cubic IDE's menus.


Compiling a Script

When an application is ready for publishing, it should be compiled into a standalone executable, which is done with the -compile argument:

Hollywood MyProgram.hws -compile MyProgram
Compiling a script

With the above command you get an executable called "MyProgram" that will run on the same archtecture it was compiled on.


To compile an application for different platforms (OS4 in this example):

Hollywood MyProgram.hws -compile MyProgram -exetype amigaos4


Or for multiple platforms at once:

Hollywood MyProgram.hws -compile MyProgram -exetype morphos|amigaos4|win32|applet


If you want to compress your own data (script and linked data files), add the -compress argument:

Hollywood MyProgram.hws -compile MyProgram -exetype morphos|amigaos4|win32|applet -compress

Compressing can make executables smaller, but it also "hides" any plaintext data from the executables if you prefer that.


Compiling in Cubic IDE is simply done by pressing the F2 key or by selecting the platform for cross-compiling from the menus.


Examples


Summary

This tutorial has hopefully given you some understanding of Hollywood programming, and it should be easier to learn more about the language by yourself. Hollywood also has a quite active web forum where you can find help on any issues by using the search field or by starting new discussion threads. There are many example scripts included with Hollywood and its plugin packages too. Coding (and especially multiplatform coding) doesn't get easier than this ;)

Have fun with Hollywood and let's see some new products in the future!


Links