Working with windows

The main goal of EWS (and any windowing system) is to abstract the display allowing you to split in independent rectangular regions called "windows". These windows can have an arbitrary position and size, overlap, and be nested inside each other. Every window defines a local coordinate system, so when the application draws inside a window, it doesn't have to take care of where the window is. The application may also draw outside the boundaries of its window, and the windowing system takes care of clipping.

Before going on, let's move to other example code:

Source: working_with_windows.e

class WORKING_WITH_WINDOWS

create
        make

feature {NONE} -- Creation

   make is
                local
                       d: DISPLAY
                       w1, w2, w3, w2_1, w3_1, w3_2: WINDOW
                       img: IMAGE
                do
                        create {SDL_DISPLAY}d.make (640, 480, 16, False)
                        -- Loading a background image
                        create {SDL_IMAGE}img.make_from_file ("window.png")
                        -- Let's create some windows now:
                        create {WINDOW_IMAGE}w1.make (d.root, 50, 50, img)
                        create {WINDOW_IMAGE}w2.make (d.root, 350, 100, img)
                        create {WINDOW_IMAGE}w2_1.make (w2, -125, 100, img)
                        create {WINDOW_IMAGE}w3.make (d.root, 300, 240, img)
                        create {WINDOW_IMAGE}w3_1.make (w3, -125, 100, img)
                        create {WINDOW_IMAGE}w3_2.make (w3, 100, 120, img)

                        d.do_event_loop
                        d.close
                rescue
                        if d /= Void then d.close end
                end

end -- class WORKING_WITH_WINDOWS

To compile this you should use:

compile working_with_windows -case_insensitive -o working-with-windows -lSDL_image $(sdl-config --libs --cflags) -lews-SDL

Which is almost the same that the command line used previously except for the -lSDL_image option. That option links the program with the SDL imaging library which is required by EWS when you need to load images from files.

Running this program will result in a display similar to this:

[screenshot]

This program creates several windows, all of them showing this image which is stored in a file window.png:

[window.png]

These windows are nested with the following tree structure:

After this overview, let's see how this is done in the code and go into the details; we'll also try to explain here what is seen on the screen.

The display is created as usual. The first line containing something new is:

create {SDL_IMAGE}img.make_from_file ("window.png")

This creates an object representing a bitmapped image. The instances of class IMAGE and its descendants represent objects that can be shown in a rectangular area of the screen. Note that img was declared as IMAGE. The class SDL_IMAGE is for SDL bitmaps, and its constructor make_from_file allows creating one and loading inside it the content of some file that can be in several supported formats (JPEG, GIF, PNG, TIFF, ...). We will see later other variants of IMAGEs.

Now, img is attached to an object which contains an in-memory representation of the "window.png" picture shown above. Perhaps now it's a good time to read the output of short IMAGE.

We will now start to create windows. A window is a rectangular surface of the screen where the application can draw and capture input, which is normally inside another window. The only window without a parent is the "Display root", which is a window covering the whole display. It is called that way because your windows will form a tree and this window will be the root. You can access to this window using the root feature of class DISPLAY.

There are several classes of windows. All those classes inherit from WINDOW. Each window class usually customizes its visual representation and the way it responds to user input. The class WINDOW itself is effective (your display root will probably be an instance of this class), but you can not do much with it: it's completely invisible (it has no graphical representation) and the only thing it does when it gets user input is to pass that input down to its children. It is normally used as a simple window container.

We will here use some instances of WINDOW_IMAGE. These windows have the same boring user response as window, but can display a fixed IMAGE, so at least you can see them. They will be useful as simple backgrounds. To create most windows, you will have to supply:

Let's see the creation call for our first window:

create {WINDOW_IMAGE}w1.make (d.root, 50, 50, img)

This creates a new WINDOW_IMAGE attached to w1. The first argument indicates that this new window will be a child of the root window. The second and third arguments indicate the coordinates of the upper left corner, in pixels. The fourth argument indicates the image to be used as a window background. WINDOW_IMAGEs have as size the same size as the image, in this case 250x200 pixels (this can change if you edit the window.png file).

The coordinates used in EWS are always relative to the container window. So this new window will have its corner in position (50,50) relative to its parent, the root window. The root window is always at position (0, 0), so the absolute_position of w1 will be (50, 50). You can see this window near the top left of the display in the screenshot above.

After w1, two other windows are created:

create {WINDOW_IMAGE}w2.make (d.root, 350, 100, img)
create {WINDOW_IMAGE}w2_1.make (w2, -125, 100, img)

The first line shown here is similar to the previous one, except that the coordinates are diferent, (350, 100). The second line is more interesting. Instead of creating another window contained by the root, this new window (attached to local variable w2_1) will be a child of w2. The coordinates passed to its creation routine, (-125, 100) are, as said before, relative to the parent, i.e. w2. So, the absolute coordinates of w2_1 will be (350, 100) + (-125,100) = (225, 200).

In the screenshot, you will be able to see w2 at the right of the display, a little lower than w1. You will see w2_1 "inside" w2, at its bottom left corner. One thing that you will note about the subwindow is that it can not be seen completely. Child windows are clipped when they escape the limits of their parents

After that, another window with two children is created:

create {WINDOW_IMAGE}w3.make (d.root, 300, 240, img)
create {WINDOW_IMAGE}w3_1.make (w3, -125, 100, img)
create {WINDOW_IMAGE}w3_2.make (w3, 100, 120, img)

After the previous example, it should be clear what this does (creating another toplevel window, and two childs inside it). It's easier here to see that the child windows are clipped inside the parent. Other thing that can be seen is that windows can overlap with their sister windows. You can see w3_2 overlapping and hiding behind it a part of w3_1. You can also see how w3 overlaps w2.

By default, newer children will be above older children. The stacking of sister windows can be altered dinamically during program execution.

Previous Table of contents Next