GUI Creator for Ruby + Fox

Guide Contents


Layouts are crucial. We create a GUI as a set of nested boxes, called frames. Associated with frames is the issue of widget sizes - how big should a widget be, and how should it resize itself if the user re-sizes the screen?

Here is a classic example - a text editor. We shall create a GUI with the following features:

  • There is a column of buttons at the left of the screen
  • There is a large work area (the 'Text' widget) at the right.
  • If the user enlarges the window, we want the work area to expand, but the area allocated to the buttons does not need to expand.
Such a pattern is common,as can be seen from editors, word-processors, drawing packages.

Note that we can also use menus, but they are covered later. The main point here is layout.

Horizontal and Vertical Frames

These containers arrange their widgets in a horizontal row, or in a vertical column. Look at the figure below, which shows a schematic diagram of the frames and widgets in our editor. It may help you to start from the inside (most nested) widgets.

       |  +--------------------H.Frame--------------------------+    |
       |  |   +----V.Frame 1---+    +-----V.Frame 2------+      |    |
       |  |   | +---------+    |    |                    |      |    |
       |  |   | | button1 |    |    |   +----Text----+   |      |    |
       |  |   | +---------+    |    |   |            |   |      |    |
       |  |   |                |    |   |            |   |      |    |
       |  |   | +---------+    |    |   |            |   |      |    |
       |  |   | | button2 |    |    |   |            |   |      |    |
       |  |   | +---------+    |    |   |            |   |      |    |
       |  |   |                |    |   |            |   |      |    |
       |  |   | +---------+    |    |   |            |   |      |    |
       |  |   | | button3 |    |    |   +------------+   |      |    |
       |  |   | +---------+    |    |                    |      |    |
       |  |   +----------------+    +--------------------+      |    |
       |  +-----------------------------------------------------+    |

                    Fig - Schematic diagram of the frames

  • some buttons have been placed inside a vertical frame. foxGUIb provides suitable sizing properties for buttons, their size being initially determined by the text that they display. This can be modified in foxGUIb by checking LayoutHints= in the properties area, and opening up the layout properties. Note the LAYOUT_FILL_X and LAYOUT_FILL_Y items, which are initially unchecked. If we check LAYOUT_FILL_X, then the button will expand in the horizontal direction to take up as much width as it can.

    The main point is that they can be set up to keep their size, or to take up as much space as they are allowed. It is our choice.

  • Look at the two vertical frames - they are side-by side, but we do not want them to act in the same way. The one on the right (containing the text) must fill as much space as it can, whereas the one containing the buttons need not expand - we want it to clamp down on the buttons.

    Here are the layout hint settings for the two frames:

    • The leftmost (button) frame:
      LAYOUT_FILL_X    -   unchecked (we don't want it to expand across the screen.)
      LAYOUT_FILL_Y    -   checked  (the space below the buttons is not in use)
    • The rightmost (text) frame:
      LAYOUT_FILL_X    -   checked (to allow it to expand as much as possible)
      LAYOUT_FILL_Y    -   checked ( "               "                  "    )
  • The other crucial setting is for the text widget. As you might expect, we want it to fill as much space as it can, as constrained by the rightmost vertical frame. We should check both its FILL properties.
  • If things are expanding as much as they can, how do we control this?. The answer is that we fix a size for the outer window. This affects the initial window size when the program runs. The user can then resize as they wish.
  • Let us look as the same layout from the outermost widget. It is a MainWindow, which provides no sensible layout of its own. Because of this, we put a horizontal frame inside it. (Horizontal because it will hold two side-by-side vertical frames, described above).
Whether you were going to code the GUI in FXRuby or in foxGUIb, you would make a similar analysis to the above. However, we might have got it wrong. foxGUIb allows you to play around with layouts very easily.

Adding widgets with the selector.

The widget tree area of foxGUIb would display the above design as:


When you right-click on a widget in the widget selector area, these 3 choices are offered:
  • add before
  • add after
  • add inside
(left-clicking does an 'add after'.)

To understand this, look at these statements:

  • Button3 is after Button2
  • Button2 is before Button3
  • V.Frame2 is after V.Frame1
  • V.Frame1 is after V.Frame2
  • Button1 is insideV.Frame1, as are all the buttons (in the hierarchical sense.... contained in)
  • V.Frame1 and 2 are inside H.Frame
We will make use of the above when creating the editor.

If we make errors (or wish to prototype) we can delete the widgets and try again, or we could re-position them in the widget, by right-clicking on them.

The widget tree

We get these right-click options:
  • cut, copy and delete, with their usual meanings
  • jump up - moves the selected item up one place. This does not cut across the hierarchy. For example, in the above, we could move Button3 above Button2, but Button1 is as far up as it can go. If we wanted to move it to another frame, we could use copy, paste, delete.
  • jump down - does the opposite of jump up.

    Note that we can move frames and their contents. For example, doing a jump up on V.Frame2 puts it first inside H.Frame, thus moving the buttons to the right of the window. Anyone for prototyping?

  • paste before, paste after, paste inside which paste relative to the current selection. Note that you should not paste inside a non-container widget.
  • Edit Events... - shows the dialog editor for the selected widget.
Right-clicking on most widgets in the design window will also provide these options as well. However, if you want to select non-visible items such as frames, it is safer to do this in the tree.

Below we will create the text editor in foxGUIb. We assume that you have worked through the earlier (inches/cm) example, hence know about saving the layout and generated code.

Creating the editor

Create a new directory (e.g TextEd) and run foxGUIb. Do the following:
  1. Make a new MainWindow and drag it open to a suitable size for your design work
  2. Add a horizontal frame inside it, using the right mouse button. Accept the default name - we only have one such frame here
  3. Add a vertical frame inside the horizontal frame, name it e.g. vFrame1.
  4. Ensuring that you have selected the horizontal frame in the tree, another vertical frame inside the horizontal frame, name it e.g. vFrame2. At this stage, play around with the left and right parts of the window, by selecting them in the tree, or selecting them on the window itself. The window is split 50/50 at present.
  5. Now add three buttons inside the left frame - choose suitable names and text, such as Open, Save As, and Exit. Note that the first button must be added inside the frame, and it then becomes the selected item. The other two can simply be added below with a left-click if you wish.
  6. Add a text widget inside the right frame - note that its FILL settings are on, meaning that it will expand as far as it can. Currently, it fills half of the window.
  7. Select the left frame, and switch off its x-fill property. Note that it collapses to be just big enough for its buttons.
  8. The design is done. Do code generation, and run it!
  9. At this stage, you might like to play around with the tree - such as swapping over the right and left frames as mentioned above, with the JumpUp command.

    You can also try selecting the left frame and exploring the spacing and pad properties, to space out the buttons. A particularly useful setting is to check the PACK_UNIFORM_WIDTH property in the packing hints, which makes every button have the same width.

  10. we have not provided the code, but (following our approach in the first program we could extend the class, and add event-handling code for the buttons.


Guide Contents