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:
This program creates several windows, all of them showing this image which
is stored in a file window.png
:
These windows are nested with the following tree structure:
- Display root
- w1
- w2
- w2_1
- w3
- w3_1
- w3_2
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 IMAGE
s.
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:
- Which one is its parent window
- Where will be the new window (relative to its parents)
- Other arguments specific for the window kind
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_IMAGE
s 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 |