Glimmr Canvas-Based Drawing

version 2/101030 by Erik Temple

  • Home page
  • Beginning
  • Previous
  • Next

  • Example: * Simple Buttons - In this example, we show how to create a simple set of buttons that the player can press to issue commands. (We use the most important meta-commands: undo, save, restore, and transcript.) The example requires the Glimmr Image Font extension, and you will need to copy the images associated with that extension to your project's Materials folder before building this example. The example also requires Glimmr Graphic Hyperlinks, which enables the buttons to accept mouse input.

    We make each button out of two g-elements: a stroked rectangle primitive creates the button's outline and color, while an image-rendered string provides the text of the button. This is convenient, since it doesn't require us to create our own images for each button. (Though using a single image for each button is in fact the most resource-efficient method.)

    Before we get to the buttons, we need to set up the window and canvas. For an example like this, Glimmr Simple Graphics Window would be an even easier way to set things up, but it's better if we show everything here.

        "Simple Buttons"

        Include Glimmr Canvas-Based Drawing by Erik Temple.
        Include Glimmr Graphic Hyperlinks by Erik Temple.
        Include Glimmr Image Font by Erik Temple.

        Hello is a room.

        The graphics-window is a graphlink g-window spawned by the main-window. The position is g-placebelow. The scale method is g-fixed-size. The measurement is 35. The back-colour is g-White.

        The back-colour of the main-window is g-White.

        The graphics-canvas is a g-canvas. The canvas-width is 248. The canvas-height is 35.
        The associated canvas of the graphics-window is the graphics-canvas.
        The associated canvas of a g-element is the graphics-canvas.

        When play begins:
            open up the graphics-window.
        [After printing the banner text:
        say "[line break]This is one of two very similar examples for the Glimmr Canvas-Based Drawing extension. It demonstrates a simple set of UI buttons. The buttons are not sprites. In other words, they are created without the need to make external PNG or JPEG images. Instead, we use Glimmr's functions for easily drawing rectangles and more complex elements. An image-rendered string provides the button's text, and this is superimposed on a stroked rectangle primitive that creates the body of the button. A simple animation allows the button to change color briefly when pressed, to provide visual feedback.[paragraph break]".]
        Table of Common Color Values (continued)
      glulx color value  assigned number  
      g-LightGray  15066597  
      g-MidGray  12829635  

    Now we create the buttons. We begin by setting up most of properties using subclasses of the stroked rectangle primitive and image-based string kinds--these are the "button" and "label" kinds. The buttons are primed to accept mouse input by making them graphlink-active. The labels merely float over the button; it is the latter which does all the work.

    Note that the image-based font is rather large, and we need to scale it down to a quarter of its actual size. Also note that the labels are center-aligned. This isn't necessary, but it does mean that if we change the text of the label slightly, we may be able to avoid changing the origin coordinate, since it will still attempt to center itself over the button background. Finally, we use display-layers to keep the label text, on layer 2, above the button background, on layer 1 (the default layer).
        A button is a kind of stroked rectangle primitive. The associated canvas of a button is the graphics-canvas. The tint of a button is g-LightGray. The background tint of a button is g-MidGray. The graphlink status of a button is g-active.

        A label is a kind of image-rendered string. The associated canvas of a label is the graphics-canvas. The scaling factor of a label is 0.2500. The display-layer of a label is 2. The alignment of a label is center-aligned.

        A button has a label called the associated label.

        Some labels are defined by the Table of Button Labels.

        Table of Button Labels
      label  origin  text-string  
      Label_1  {30, 10}  "Undo"  
      Label_2  {81, 10}  "Save"  
      Label_3  {138, 10}  "Restore"  
      Label_4  {204, 10}  "Transcript"  

        Some buttons are defined by the Table of Glimmr Buttons.

        Table of Glimmr Buttons
      button  origin  endpoint  associated label  linked replacement-command  
      Button_1  {10, 7}  {52, 28}  Label_1  "UNDO"  
      Button_2  {61, 7}  {103, 28}  Label_2  "SAVE"  
      Button_3  {111, 7}  {165, 28}  Label_3  "RESTORE"  
      Button_4  {173, 7}  {238, 28}  Label_4  "TRANSCRIPT"  

    We can include a little optional code to change the color of the button momentarily when it is pressed, then reverting back to the original color. We do this using Glulx's real-time capability: when the button is pressed, we change the button's color, and start a short timer (85 milliseconds). When the timer runs out, we stop the timer and change the button back to the original color. Note that the window must be redrawn after each of these to show the state change to the player.
        To revert the/-- button/-- after (T - a number) millisecond/milliseconds:
            (- glk_request_timer_events({T}); -)
        To stop the/-- timer:
            (- glk_request_timer_events(0); -)

        First graphlink processing rule for a button (called the depressed):
            change the tint of the depressed to g-MidGray;
            follow the window-drawing rules for the graphics-window;
            revert the button after 85 milliseconds.

        A glulx timed activity rule (this is the redraw button from timer rule):
            stop the timer;
            now the tint of the current graphlink is g-LightGray;
            follow the window-drawing rules for the graphics-window.

    This last part is even more optional, but it will ensure that the button acts correctly after UNDO. We set the timer to revert immediately after undoing the state of the last turn, to be sure that the buttons end in their resting state. To act after undoing, we either have to directly hack the template layer, or use an extension such as Undo Output Control, which is how we handle it here.
        Include Undo Output Control by Erik Temple.

        After undoing an action:
            revert the button after 0 milliseconds.