/*! * \file * \ingroup elwindows * \brief EL window manager. */ #ifndef __EL_WINDOWS_H #define __EL_WINDOWS_H #include "keys.h" #include "widgets.h" #ifdef __cplusplus extern "C" { #endif /*! * \name Title bar & other constants */ /*! @{ */ #define ELW_TITLE_HEIGHT 16 #define ELW_BOX_SIZE 20 #define ELW_TITLE_SIZE 35 /*! @} */ /*! * A simple window handler setup to reduce the code needed to do windows * */ typedef struct { int window_id; /*!< the unique window id */ int order; /*!< the order the windows are to be displayed (layering) */ int pos_id; /*!< id of parent window, pos_id < 0 for normal windows */ int pos_loc; /*!< where is it compared to the pos id? NOT SUPPORTED YET */ int pos_x, pos_y; /*!< logical location on screen */ int len_x, len_y; /*!< the size of the window in pixels */ int min_len_x, min_len_y; /*!< for resizable windows, the minimum width and height */ int cur_x, cur_y; /*!< current location on screen */ Uint32 flags; /*!< window flags */ float back_color[4]; /*!< r,g,b,a for the background */ float border_color[4]; /*!< r,g,b,a for the border */ float line_color[4]; /*!< r,g,b,a for any internal lines */ char window_name[ELW_TITLE_SIZE]; /*!< should be a unique name suitable for display */ char displayed; /*!< is the window currently being displayed? */ //char collapsed; // is it collapsed or expanded? char dragged; /*!< are we dragging the window? */ char resized; /*!< are we resizing the window? */ char drag_in; /*!< are we dragging inside the window? */ char reinstate; /*!< reinstate this window if the parent is shown again */ /*! * \name the handlers */ /*! @{ */ int (*init_handler)(); /*!< init, scaling, etc */ int (*display_handler)(); /*!< display the window */ int (*click_handler)(); /*!< handle mouse clicks */ int (*drag_handler)(); /*!< handle dragging inside windows */ int (*mouseover_handler)(); /*!< handle mouseovers */ int (*resize_handler)(); /*!< handle window resize events */ int (*keypress_handler)(); /*!< handle key presses */ int (*close_handler)(); /*!< executed after window is closed */ int (*destroy_handler)(); /*!< executed upon window destruction */ int (*show_handler)(); /*!< executed before the window is shown */ int (*after_show_handler)(); /*!< executed after the window is shown */ int (*hide_handler)(); /*!< executed after the window is hidden */ /*! @} */ /* // and optional list/data storage - future expansion?? void *list; int list_size; // width of list items int num_list; // number of items usable in list int max_list; // amount of space allocated in list int data_value; // a simple data value associated with this window */ void * data; /*!< data for this window */ widget_list *widgetlist; /*!< list of widgets for this window */ } window_info; /*! * \name property flags in create */ /*! @{ */ #define ELW_TITLE_NONE 0x0000 #define ELW_TITLE_BAR 0x0001 #define ELW_TITLE_NAME 0x0002 #define ELW_CLOSE_BOX 0x0004 #define ELW_SHOW 0x0010 #define ELW_DRAGGABLE 0x0020 //#define ELW_COLLAPSABLE 0x0040 #define ELW_SHOW_LAST 0x0080 #define ELW_RESIZEABLE 0x0100 #define ELW_USE_BACKGROUND 0x0200 #define ELW_USE_BORDER 0x0400 //#define ELW_USE_LINES 0x0800 #define ELW_CLICK_TRANSPARENT 0x1000 #define ELW_ALPHA_BORDER 0x2000 /*! @} */ /*! * \name predefined window flags */ /*! @{ */ #define ELW_WIN_DEFAULT (ELW_TITLE_BAR|ELW_CLOSE_BOX|ELW_DRAGGABLE|ELW_USE_BACKGROUND|ELW_USE_BORDER|ELW_SHOW|ELW_TITLE_NAME|ELW_ALPHA_BORDER) #define ELW_WIN_INVISIBLE (ELW_TITLE_NONE|ELW_SHOW) /*! @} */ /*! * \name window position flags */ /*! @{ */ #define ELW_VUPPER 0x00 #define ELW_VCENTER 0x04 #define ELW_VLOWER 0x08 #define ELW_VAUTO 0x0C //reserved #define ELW_HLEFT 0x00 #define ELW_HCENTER 0x01 #define ELW_HRIGHT 0x02 #define ELW_HAUTO 0x03 //reserved #define ELW_POS_UL (ELW_VUPPER|ELW_HLEFT) #define ELW_POS_UC (ELW_VUPPER|ELW_HCENTER) #define ELW_POS_UR (ELW_VUPPER|ELW_HRIGHT) #define ELW_POS_CL (ELW_VCENTER|ELW_HLEFT) #define ELW_POS_CC (ELW_VCENTER|ELW_HCENTER) #define ELW_POS_CR (ELW_VCENTER|ELW_HRIGHT) #define ELW_POS_LL (ELW_VLOWER|ELW_HLEFT) #define ELW_POS_LC (ELW_VLOWER|ELW_HCENTER) #define ELW_POS_LR (ELW_VLOWER|ELW_HRIGHT) /*! @} */ /*! * \name window alignment flags */ /*! @{ */ #define ELW_ALIGN_UL ((ELW_VUPPER|ELW_HLEFT)<<8) #define ELW_ALIGN_UC ((ELW_VUPPER|ELW_HCENTER)<<8) #define ELW_ALIGN_UR ((ELW_VUPPER|ELW_RIGHT)<<8) #define ELW_ALIGN_CL ((ELW_VCENTER|ELW_HLEFT)<<8) #define ELW_ALIGN_CC ((ELW_VCENTER|ELW_HCENTER)<<8) #define ELW_ALIGN_CR ((ELW_VCENTER|ELW_HRIGHT)<<8) #define ELW_ALIGN_LL ((ELW_VLOWER|ELW_HLEFT)<<8) #define ELW_ALIGN_LC ((ELW_VLOWER|ELW_HCENTER)<<8) #define ELW_ALIGN_LR ((ELW_VLOWER|ELW_HRIGHT)<<8) /*! @} */ /*! * \name predefined flags */ /*! @{ */ #define ELW_POS ELW_POS_UL #define ELW_ALIGN ELW_ALIGN_UL #define ELW_RELATIVE (ELW_POS|ELW_ALIGN) /*! @} */ /*! * \name window color id's */ /*! @{ */ #define ELW_COLOR_BACK 0 #define ELW_COLOR_BORDER 1 #define ELW_COLOR_LINE 2 /*! @} */ /*! * \name window handler id's */ /*! @{ */ #define ELW_HANDLER_INIT 0 #define ELW_HANDLER_DISPLAY 1 #define ELW_HANDLER_CLICK 2 #define ELW_HANDLER_DRAG 3 #define ELW_HANDLER_MOUSEOVER 4 #define ELW_HANDLER_RESIZE 5 #define ELW_HANDLER_KEYPRESS 6 #define ELW_HANDLER_CLOSE 7 #define ELW_HANDLER_DESTROY 8 #define ELW_HANDLER_SHOW 9 #define ELW_HANDLER_HIDE 10 #define ELW_HANDLER_AFTER_SHOW 11 /*! @} */ /*! * \name mouse click flags - first ones from events */ /*! @{ */ #define ELW_SHIFT SHIFT #define ELW_CTRL CTRL #define ELW_ALT ALT #define ELW_RIGHT_MOUSE (1<<28) #define ELW_MID_MOUSE (1<<27) // future expansion #define ELW_LEFT_MOUSE (1<<26) #define ELW_MOUSE_BUTTON (ELW_RIGHT_MOUSE|ELW_MID_MOUSE|ELW_LEFT_MOUSE) #define ELW_DBL_CLICK (1<<25) // future expansion #define ELW_WHEEL_UP (1<<24) #define ELW_WHEEL_DOWN (1<<23) /*! @} */ /*! * structure containing data for all windows used. */ typedef struct { window_info *window; /*!< an array of \ref window_info windows */ int num_windows; /*!< highest item used */ int max_windows; /*!< number of windows allocated */ int display_level; } windows_info; extern windows_info windows_list; /*!< global variable defining the list of windows */ extern int windows_on_top; /*!< global variable for whether windows appear on top of the console */ // windows manager function /*! * \ingroup elwindows * \brief Displays all active windows * * Displays all active windows * * \param level the display level to display * \callgraph */ void display_windows(int level); /*! * \ingroup elwindows * \brief callback function used when a mouse click happens in a window. * * This event handler gets called when a mouse click is reported in a window. The coordinates \a mx and \a my denotes the (x,y) position of the mouse within the window. * * \param mx x coordinate of the mouse position where the click occurred * \param my y coordinate of the mouse position where the click occurred * \param flags mouseflags * \retval int * \callgraph */ int click_in_windows(int mx, int my, Uint32 flags); /*! * \ingroup elwindows * \brief callback function used when a drag event happens in a window. * * This drag event handler get called when a mouse drag event happens in a window. (\a mx, \a my) denotes the coordinates of the mouse, while \a dx and \a dy are the dragging distances in x- and y-direction. * * \param mx x coordinate of the mouse position where the drag started * \param my x coordinate of the mouse position where the drag started * \param flags mouseflags * \param dx dragging distance in x-direction * \param dy dragging distance in y-direction * \retval int * \callgraph */ int drag_in_windows(int mx, int my, Uint32 flags, int dx, int dy); /*! * \ingroup elwindows * \brief Handles dragging and resizing of a window * * Checks all the windows for one that is currently seletec and moves or resizes this one resp. * * \param mx x coordinate of the mouse position * \param my y coordinate of the mouse position * \param dx amount in x direction to drag or resize the window * \param dy amount in y direction to drag or resize the window * \retval int the id of the window being dragged or resized * \callgraph */ int drag_windows(int mx, int my, int dx, int dy); /*! * \ingroup elwindows * \brief callback function used when a key is pressed in a window. * * This event handler gets called when a keypress is reported in a window. The coordinates \a mx and \a my denotes the (x,y) position of the mouse within the window. * * \param x x coordinate of the mouse position where the click occurred * \param y y coordinate of the mouse position where the click occurred * \param key the key or key combination that is pressed * \param unikey the unicode value of \a key * \retval int * \callgraph */ int keypress_in_windows(int x, int y, Uint32 key, Uint32 unikey); /*! * \ingroup elwindows * \brief Resets the states of all windows which are related to dragging * * Resets the dragged, resized and drag_in states of all windows. * */ void end_drag_windows(); /*! * \ingroup elwindows * \brief Selects the window given by \a win_id. * * Selects the window given in \a win_id. The selected window and each of its childs, if applicable, is brought to front. * * \param win_id the id of the window to select * \retval int -1, if \a win_id is either <0 or greater than \ref windows_info::num_windows, or if \a win_id is not equal the \ref window_info::window_id stored for this \ref windows_info::window. * 0, if the \ref window_info::order of the \ref windows_info::window stored at this index is less than 0, * else 1. * * \pre The parameter \a win_id must be both, greater or equal to 0 and less than \ref windows_info::num_windows * \pre The parameter \a win_id must be equal the \ref window_info::window_id which is currently stored in \ref windows_list. * \pre The \ref window_info::order of the \ref windows_info::window stored at the index \a win_id, must be greater than 0. */ int select_window(int win_id); // individual functions /*! * \ingroup elwindows * \brief Creates a new window and calls \ref init_window to place it. * * Creates a new window with the given \a name and \a property_flags and then calls \ref init_window to place it accordingly. * * \param name name of the window * \param pos_id used to determine the visibility of this window, gets passed to \ref init_window * \param pos_loc passed to \ref init_window * \param pos_x passed to \ref init_window * \param pos_y passed to \ref init_window * \param size_x passed to \ref init_window * \param size_y passed to \ref init_window * \param property_flags the windows properties * \retval int returns the window id as an index into the \ref windows_info::window array. * \callgraph * * \post If this functions returns -1, it indicates an unhandled exception has occured. */ int create_window(const char *name, int pos_id, Uint32 pos_loc, int pos_x, int pos_y, int size_x, int size_y, Uint32 property_flags); /*! * \ingroup elwindows * \brief Destroys the window with the given \a win_id. * * Destroys the window with the given \a win_id and frees up memory. * * \param win_id the index into the \ref windows_info::window array * * \pre If \a win_id is \<0 or \>\ref windows_info::num_windows this function returns without performing any actions. * \pre If the \ref window_info::window_id of the window stored at the index \a win_id into the \ref windows_list variable is not equal to \a win_id, this function returns without performing any actions. */ void destroy_window(int win_id); /*! * \ingroup elwindows * \brief Initializes a new window. * * Initializes a new window with the given \a win_id, position and size. Calls \ref move_window to place the window accordingly. * * \param win_id the \ref window_info::window_id for the window * \param pos_id the id of the position * \param pos_loc * \param pos_x x coordinate of the upper left corner of the window * \param pos_y y coordinate of the upper left corner of the window * \param size_x width of the window * \param size_y height of the window * \retval int * \sa move_window */ int init_window(int win_id, int pos_id, Uint32 pos_loc, int pos_x, int pos_y, int size_x, int size_y); /*! * \ingroup elwindows * \brief Moves the window given by \a win_id * * Moves the given window to the new position given. * * \param win_id id for the window to move * \param pos_id id of the new posisiotn * \param pos_loc * \param pos_x x coordinate of the new position * \param pos_y y coordinate of the new position * \retval int -1, if \a win_id < 0 or \a win_id > \ref windows_info::num_windows, * or if the \ref window_info::window_id of the window at index \a win_id into \ref windows_list is not equal \a win_id, * else 1 is returned. * * \pre If \a win_id is less than 0, this functions returns -1 without performing any actions * \pre If \a win_id is greater than \ref windows_info::num_windows this function returns -1 without performing any actions * \pre If \a win_id is not equal \ref window_info::window_id of the window at the index \a win_id into \ref windows_list this functions returns -1, without performing any action. */ int move_window(int win_id, int pos_id, Uint32 pos_loc, int pos_x, int pos_y); /*! * \ingroup elwindows * \brief Draws the window given by \a win_id * * Draws the given window on the screen. Don't call this function directly, * use the window manager instead. This declaration is only here for the * loading window which bypasses the window manager since it cannot be * drawn in the normal event loop. * * \param win_id id for the window to move */ int display_window (int win_id); //int set_window_property(int win_id, Uint32 property_flag, int new_property); /*! * \ingroup elwindows * \brief Sets the window (background) color to the given values. * * Sets the background color of the window given by \a win_id to the values given in \a r, \a g, \a b and \a a. * \note This function is currently only used when displaying the options menu. * * \param win_id the id of the window * \param color_id an id for the color value * \param r red value of the color (0<=r<=1) * \param g green value of the color (0<=g<=1) * \param b blue value of the color (0<=b<=1) * \param a transparency of the color (0<=a<=1) * \retval int 0, if \a win_id is less than 0, or if \a win_id is greater than \ref windows_info::num_windows, * or if the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array is not equal to \a win_id, * or if no action was performed, else 1 is returned. * * \callgraph * * \pre If \a win_id < 0 this function returns 0 without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows, this functions returns 0 without performing any actions. * \pre If none of the above preconditions is true, but no action is performed else, this function returns 0. * \pre This functions only handles the \a color_id of \ref ELW_COLOR_BACK, \ref ELW_COLOR_BORDER and \ref ELW_COLOR_LINE. */ int set_window_color(int win_id, Uint32 color_id, float r, float g, float b, float a); /*! * \ingroup elwindows * \brief Uses the color of the window \a win_id that is referred to by \a color_id. * * The part of the window \a win_id given by \a color_id will be used further. * \note This function is only used by the quickbar (\ref display_quickbar_handler) * * \param win_id the id of the window to set the color * \param color_id the color id to use * \retval int 0, if \a win_id is less than 0, or if \a win_id is greater than \ref windows_info::num_windows, * or if the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array is not equal to \a win_id, * or if no action was performed, else 1 is returned. * * \sa display_quickbar_handler * * \pre If \a win_id < 0 this function returns 0 without performing any actions. * \pre If \a win_id is greater than the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns 0 without performing any actions. * \pre If none of the above preconditions is true, but no action is performed else, this function returns 0. * \pre This function only handles the \a color_id of \ref ELW_COLOR_BACK, \ref ELW_COLOR_BORDER and \ref ELW_COLOR_LINE. */ int use_window_color(int win_id, Uint32 color_id); /*! * \ingroup elwindows * \brief Sets the window's minimum size * * Sets the minimum \a width and \a height for the resizeable window given by \a win_id * * \param win_id the number of the window * \param width the new minimum width * \param height the new minimum height * \retval int 0 on failure, 1 on success * * \pre If \a win_id < 0 this function returns 0, without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows this function returns 0 without performing any actions. * \pre If either \a width or \a height is less than 0 this function returns 0 without performing any actions. */ int set_window_min_size (int win_id, int width, int height); /*! * \ingroup elwindows * \brief Sets one or more window flags * * Sets the window flags in \a flag * * \param win_id the number of the window * \param flag the flag(s) to set */ int set_window_flag (int win_id, Uint32 flag); /*! * \ingroup elwindows * \brief Sets a new window handler callback function to be used for the given window. * * The given \a handler will be set to be the callback function to handle \a handler_id callbacks for the \a win_id window. * * \param win_id the id of the window for which to set a callback function. * \param handler_id the type of handler that will be set. * \param handler a pointer to the callback function to use. * \retval void* a pointer to the old handler, or NULL. * * \pre If \a win_id < 0 this function returns NULL without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns NULL without performing any actions. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns NULL without performing any actions. * \pre If \a handler_id is not one of \ref ELW_HANDLER_INIT, \ref ELW_HANDLER_DISPLAY, \ref ELW_HANDLER_CLICK, \ref ELW_HANDLER_DRAG, \ref ELW_HANDLER_MOUSEOVER, \ref ELW_HANDLER_RESIZE, \ref ELW_HANDLER_KEYPRESS or \ref ELW_HANDLER_DESTROY, this function returns NULL. * */ void *set_window_handler(int win_id, int handler_id, int (*handler)() ); /*! * \ingroup elwindows * \brief Selects and shows the given window * * Selects and shows the window given by \a win_id and all it's child windows where applicable. * * \param win_id the id of the window to show * * \sa select_window * * \pre If \a win_id < 0 this function returns without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions. */ void show_window(int win_id); /*! * \ingroup elwindows * \brief Hides the given window. * * Hides the window given by \a win_id and all its child windows where applicable. * * \param win_id the id of the window to hide. * * \pre If \a win_id < 0 this function returns without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions. */ void hide_window(int win_id); /*! * \ingroup elwindows * \brief Toggles the visibility of the given window. * * Toggles the visibility of the window given by \a win_id, by either calling \ref hide_window or \ref show_window. * * \param win_id the id of the window to toggle. * * \callgraph * * \pre If \a win_id < 0 this function returns without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions. */ void toggle_window(int win_id); /*! * \ingroup elwindows * \brief Sets the new size of a resizable window. * * Resizes the window given by \a win_id to given \a new_width and \a new_height, if the window is resizable. Whether a window is resizable or not is determined by looking if the \ref window_info::resize_handler equals NULL or not. * * \param win_id the id of the window to resize * \param new_width the new width of the window * \param new_height the new height of the window * * \callgraph * * \pre If \a win_id < 0 this function returns without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions. * \pre If \a new_width is less than the minimum width (\ref window_info::min_len_x) it will be adjusted accordingly before applying. * \pre If \a new_height is less than the minimum height (\ref window_info::min_len_y) it will be adjusted acoordingly before applying. */ void resize_window (int win_id, int new_width, int new_height); /*! * \ingroup elwindows * \brief Checks whether a window is currently displayed and returns a proper boolean value. * * Returns the visibility status of the window given by \a win_id in a boolean value. * * \param win_id the id of the window to check * \retval int 0 (false) if the window is hidden, else 1 (true). * * \pre If \a win_id < 0, this function returns false (0), without performing any actions. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns false (0), without performing any actions. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns false (0), without performing any actions. */ int get_show_window(int win_id); //void collapse_window(int win_id); // future expansion //void expand_window(int win_id); // future expansion /*! * \ingroup elwindows * \brief Checks if the mouse coordinates are inside a window. * * Checks whether the given mouse coordinates \a x and \a y are within the window given by \a win_id and returns either a boolean value or an error. * * \param win_id the id of the window to check for the coordinates \a x and \a y * \param x the x location of the mouse cursor to check * \param y the y location of the mouse cursor to check * \retval int -1, if either \a win_id < 0, or \a win_id is greater than \ref windows_info::num_windows, * or if \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array. * 0 (false), if the coordinates \a x and \a y are outside the window given by \a win_id, * else 1 (true). * * \pre If \a win_id < 0, this function returns -1, without performing any actions, indicating an error. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns -1, without performing any actions, indicating an error. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns -1 without performing any actions, indicating an error. */ int mouse_in_window(int win_id, int x, int y); // is a coord in the window? /*! * \ingroup elwindows * \brief Checks if there is a click in a window at the given coordinates. * * Checks whether a click occured inside the window given by \a win_id, at the coordinates \a x and \a y and returns a boolean value or an error. * * \param win_id the id of the window to check * \param x the x coordinate of the cursor position where the click occured * \param y the y coordinate of the cursor position where the click occured * \param flags the window flags of the window. They will be given to the \ref window_info::click_handler that handles the actual click event. * \retval int -1, if either \a win_id < 0, or \a win_id is greater than \ref windows_info::num_windows, * of if \a win_id is not equal the \ref window_info::window_id of the given at index \a win_id into the \ref windows_list array. * 1 (true), if the cursor is actualy inside the window, * else 0 (false). * \callgraph * * \pre If \a win_id < 0, this function returns -1, without performing any actions, indicating an error. * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns -1, without performing any actions, indicating an error. * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns -1, without performing any actions, indicating an error. */ int click_in_window(int win_id, int x, int y, Uint32 flags); // click in a coord in the window // low level functions //window_info *get_window_info(int win_id); //window_info *get_window_by_name(const Uint8 *name); // default handlers - VERY basic //int init_handler(window_info *win); //int display_handler(window_info *win); //int click_handler(window_info *win); //int mouseover_handler(window_info *win); #ifdef __cplusplus } // extern "C" #endif #endif //__EL_WINDOWS_H