## Windows

### OBJECTS

      typedef struct Window  Window;

      typedef void (*WindowFunc)      (Window *w);
      typedef void (*WindowMouseFunc) (Window *w, int buttons, Point xy);
      typedef void (*WindowKeyFunc)   (Window *w, unsigned long key);
      typedef void (*WindowDrawFunc)  (Window *w, Graphics *g);

      struct Window  {
        App *           app;          /* system connection */
        char *          text;         /* title bar string */
        long            flags;        /* status flags */
        Rect            bounds;       /* drawable area */
        void *          data;         /* user-defined pointer */
        Palette *       pal;          /* private colour palette */
        int             num_children; /* list of child controls */
        Control **      children;
        WindowFunc      close;        /* the user closed the window */
        WindowFunc      resize;       /* the user resized the window */
        WindowDrawFunc  redraw;       /* some part(s) exposed */
        WindowMouseFunc mouse_down;   /* mouse button clicked */
        WindowMouseFunc mouse_up;     /* mouse button released */
        WindowMouseFunc mouse_drag;   /* mouse moved, button down */
        WindowMouseFunc mouse_move;   /* mouse moved, no buttons down */
        WindowKeyFunc   key_down;     /* Unicode key press */
        WindowKeyFunc   key_action;   /* arrow keys, function keys, etc */
      };

### FUNCTIONS

      Window *new_window(App *app, Rect bounds, char *name, long flags);
      void    del_window(Window *w);

      void    show_window(Window *w);
      void    hide_window(Window *w);

      void    move_window(Window *w, Rect r);
      void    size_window(Window *w, Rect r);
      void    redraw_rect(Window *w, Rect r);
      void    draw_window(Window *w);
      void    redraw_window(Window *w);
      Rect    get_window_bounds(Window *w);

      void    set_window_title(Window *w, char *title);
      char *  get_window_title(Window *w);
      void    set_window_icon(Window *win, Image *icon);

      void    on_window_close (Window *w, WindowFunc close);
      void    on_window_resize(Window *w, WindowFunc resize);
      void    on_window_redraw(Window *w, WindowDrawFunc redraw);

      void    on_window_mouse_down(Window *w, WindowMouseFunc mouse_down);
      void    on_window_mouse_up  (Window *w, WindowMouseFunc mouse_up);
      void    on_window_mouse_drag(Window *w, WindowMouseFunc mouse_drag);
      void    on_window_mouse_move(Window *w, WindowMouseFunc mouse_move);
      void    on_window_key_down  (Window *w, WindowKeyFunc key_down);
      void    on_window_key_action(Window *w, WindowKeyFunc key_action);

      void    set_window_background(Window *w, Colour bg);
      Colour  get_window_background(Window *w);

      void    set_window_data(Window *w, void *data);
      void *  get_window_data(Window *w);

      void    hide_all_windows(App *app);
      void    del_all_windows(App *app);

### CONSTANTS

      #define SIMPLE_WINDOW   0x00000000L

      #define MENUBAR         0x00000010L
      #define TITLEBAR        0x00000020L
      #define CLOSEBOX        0x00000040L
      #define RESIZE          0x00000080L
      #define MAXIMIZE        0x00000100L
      #define MINIMIZE        0x00000200L

      #define MODAL           0x00001000L
      #define FLOATING        0x00002000L
      #define CENTERED        0x00004000L
      #define CENTRED         0x00004000L

      #define STANDARD_WINDOW (TITLEBAR|CLOSEBOX|RESIZE|MAXIMIZE|MINIMIZE)

### NOTES

A Window is a rectangular area displayed on a screen. A window has a zero origin in its own co-ordinate system, but may have various structures built around its drawable area, such as title bars, borders and menu bars. A window can be drawn to by obtaining an appropriate Graphics object.

The new_window function creates an initially invisible window with the given name. The app parameter specifies the connection to the windowing system. The rectangle specifies where the window's drawable area should appear on the screen, with zero being the top-left point of the screen. The window manager is free to ignore the x and y components of this rectangle, depending on its window placement policies, but most window managers honour these values and try to place the window in the correct place. If the width and height values are too large, the window manager may reduce the size of the window. The flags parameter is usually the constant STANDARD_WINDOW. If an error occurs the function returns NULL.

The flags field supplied to new_window is a bit-field. Various constants can be combined using the plus or bitwise-or operators to specify how the window should look. Here is a list of those constants and their meanings:

- The TITLEBAR flag gives the window a title bar which can be used for moving it around the screen and also for displaying the window's name.
- The MENUBAR flag can be used to reserve space for a menu bar on the window, if the platform allows this.
- CLOSEBOX gives the user a way of closing the window.
- MAXIMIZE gives the user a way of increasing the size of the window to its maximum, and
- MINIMIZE allows the window to be shrunk to an icon.
- RESIZE gives the user a method of changing the size of the window.
- The CENTERED or CENTRED flag causes the window to appear at the centre of the screen.
- Adding the MODAL flag means the window will be in front of all other application windows when it is displayed, and no mouse or keyboard events will be sent to the other windows until it is hidden.
- FLOATING windows will appear in front of all other application windows even when not active.
- A SIMPLE_WINDOW is a window with no 'decorations' at all.
- The STANDARD_WINDOW constant is defined as having the following flags set: TITLEBAR, RESIZE, CLOSEBOX, MINIMIZE, MAXIMIZE. It is provided as a convenience, and is sufficient for most uses of new_window.

The window manager might not be able to implement all of the above functionality, and some platforms have different policies regarding placement of menu bars, for instance. The flags should be treated as a request to the windowing system, but that request may be partially or completely ignored. For instance, a window manager might force all windows to have a title bar, whether one was requested or not.

The del_window function destroys the specified window, hiding it first if it is currently visible. If a window can be re-used, it is more efficient to hide it and then show it later on, rather than delete the window and recreate it every time the user needs the window.

The show_window function makes the specified window visible on the screen and ensures it is the frontmost application window. The hide_window function causes the specified window to vanish from the screen. These functions do not destroy the window, so the window can be shown and hidden many times. This is faster than deleting and recreating a window.

The set_window_title function changes the name of the window as shown in the window's title bar, and get_window_title returns the current title. Titles must currently be zero-terminated C strings, not UTF-8 encoded Unicode strings, since many window managers are not yet Unicode aware.

The set_window_icon function associates an icon image with a window. This icon may be visible when the window is minimised, or in other circumstances. An icon can use colour and transparent pixels, although some window managers, notably under X11, will only display the icon as monochrome. Icons should be at least 32 pixels tall and wide, and might be automatically scaled, cropped or centered to fit the window manager's expectations.

Use move_window to change the window's top-left location without changing the size of the window. The supplied rectangle's width and height parameters are ignore by this function.

Use size_window to change the window's size without changing the location of the window. The supplied rectangle's x and y parameters are ignore by this function.

The redraw_rect function just forces a redrawing of the given rectangle (in window co-ordinates), while the draw_window function forces the entire window to be drawn. The redraw_window function is the same as draw_window except that the existing window contents are first erased using the window's background colour.

The get_window_area function returns the window's drawable rectangle in window co-ordinates; hence the top-left point will be zero.

The on_window_close function sets the call-back to be used when the user tries to close the window using the window's close-box. If this call-back is not set, the window will simply be hidden. If the call-back is supplied, it will be called instead, and the window will not be hidden. It is then up to the programmer to achieve the desired effect.

The on_window_resize function sets the call-back to be used when a window is resized by the user. The window is always resized before being redrawn, in circumstances where both of these events must be occur.

The on_window_redraw function is used to attach a call-back function to a window, which will be called every time that window needs to be redrawn. There is no need for this call-back to clear the window since this will automatically be done by the window manager.

Mouse events are handled busing the various on_window_mouse functions to set call-back functions. A mouse_down occurs when a mouse button is clicked within the window; a mouse_up occurs when a mouse button is released. Mouse ups may occur outside the window since the event mechanism tracks the mouse even if it leaves the window where a mouse down first occurred. A mouse_drag occurs when a mouse button is held down and then the mouse is moved, while a mouse_move occurs when no buttons are held down.

Keyboard events are handled using call-back functions. The on_window_key_down function sets the handler to be used for most keyboard events, except for the arrow keys, function keys, home, end, page up, page down, insert and delete keys, or keys modified by holding down CONTROL, which are instead handled by on_window_key_action. Normal key events are mapped to Unicode values, where possible, and passed as unsigned long integers to the call-back function. Not all operating systems allow the input of Unicode values.

Note that mouse and keyboard events which are intercepted first by a Control may not be seen by the underlying window. A control is a separate area placed on a window's surface, which can have its own mouse and keyboard handler functions.

When a window is redrawn, empty areas are first filled with the colour white, by default. A different background colour can be used to fill empty areas, by using the set_window_background function. Which colour is currently selected for use as a background can be determined by using get_window_background.

A user-supplied pointer may be associated with a window using set_window_data. This pointer is converted to a pointer to void and stored in the window's data structure, for later use by the programmer. It can be retrieved using get_window_data.

The hide_all_windows function hides every window created using the given app parameter, while del_all_windows hides and then deletes all such windows. This can be used when terminating the application. The stop function automatically calls these when stopping the application anyway, so they may not be needed in many cases.

### EXAMPLES

- smiley.c
- scribble.c