Added initial LBreakout2 sources, already slightly modified - it does not work yet!
This commit is contained in:
618
project/jni/application/lbreakout2/gui/gui_widget.c
Normal file
618
project/jni/application/lbreakout2/gui/gui_widget.c
Normal file
@@ -0,0 +1,618 @@
|
||||
/***************************************************************************
|
||||
gui_widget.c - description
|
||||
-------------------
|
||||
begin : Fri Oct 11 2002
|
||||
copyright : (C) 2002 by Michael Speck
|
||||
email : kulkanie@gmx.net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "gui_widget.h"
|
||||
|
||||
extern GuiTheme *gui_theme;
|
||||
extern SDL_Surface *stk_display;
|
||||
extern List *gui_root_stack;
|
||||
extern List *gui_visible_stack;
|
||||
extern List *gui_timed_stack;
|
||||
|
||||
GuiWidget *gui_key_widget = 0;
|
||||
/* is the last child widget of _all_ visible key grabbing
|
||||
widgets that was clicked on */
|
||||
GuiWidget *gui_clicked_widget = 0;
|
||||
/* is the last child widget of _all_ visible widgets
|
||||
that was clicked on (used to clear 'pressed' flag) */
|
||||
GuiWidget *gui_focused_widget = 0;
|
||||
/* the very toplevel widget of all visible widgets
|
||||
the mouse pointer hovers above */
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
LOCALS
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Free the memory of a widget and all its subwidgets.
|
||||
====================================================================
|
||||
*/
|
||||
static void gui_widget_delete_intern( GuiWidget *widget )
|
||||
{
|
||||
GuiWidget *child;
|
||||
if ( widget ) {
|
||||
/* go recursive */
|
||||
list_reset( widget->widgets );
|
||||
while ( ( child = list_next( widget->widgets ) ) )
|
||||
gui_widget_delete_intern( child );
|
||||
/* free common data */
|
||||
list_delete( widget->widgets );
|
||||
stk_surface_free( &widget->surface );
|
||||
/* free special data */
|
||||
widget->default_event_handler(
|
||||
widget, gui_event_get_simple( GUI_DESTROY ) );
|
||||
/* widget itself */
|
||||
free( widget );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Draw the widget and its children. gui_widget_draw() disabled
|
||||
the display monitoring and will add the widgets screen_region
|
||||
as update rectangle.
|
||||
====================================================================
|
||||
*/
|
||||
static void gui_widget_draw_intern( GuiWidget *widget )
|
||||
{
|
||||
GuiWidget *child = 0;
|
||||
/* draw widget */
|
||||
widget->default_event_handler(
|
||||
widget, gui_event_get_simple( GUI_DRAW ) );
|
||||
/* draw children */
|
||||
list_reset( widget->widgets );
|
||||
while ( ( child = list_next( widget->widgets ) ) )
|
||||
gui_widget_draw_intern( child );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Set visible flag to 'visible' for widget and all children
|
||||
recursively.
|
||||
====================================================================
|
||||
*/
|
||||
static void gui_widget_show_intern( GuiWidget *widget, int visible )
|
||||
{
|
||||
GuiWidget *child;
|
||||
widget->visible = visible;
|
||||
list_reset( widget->widgets );
|
||||
while ( ( child = list_next( widget->widgets ) ) )
|
||||
gui_widget_show_intern( child, visible );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
If there are any root windows above this widget in the stack that
|
||||
overlap this one they need to be redrawn. We clip to the widgets
|
||||
screen region and redraw all root widgets above.
|
||||
====================================================================
|
||||
*/
|
||||
static void gui_widget_redraw_overlapping_roots(
|
||||
GuiWidget *widget )
|
||||
{
|
||||
ListEntry *entry;
|
||||
if ( gui_visible_stack->count > 1 )
|
||||
if ( list_last( gui_visible_stack ) != widget->root ) {
|
||||
/* clip */
|
||||
stk_surface_clip( stk_display,
|
||||
widget->screen_region.x, widget->screen_region.y,
|
||||
widget->screen_region.w, widget->screen_region.h );
|
||||
/* get first root widget above */
|
||||
entry = list_entry(
|
||||
gui_visible_stack, widget->root );
|
||||
if ( !entry ) {
|
||||
fprintf( stderr,
|
||||
"'visible_stack' corrupted: root widget not found\n" );
|
||||
return;
|
||||
}
|
||||
entry = entry->next;
|
||||
/* redraw */
|
||||
while ( entry != gui_visible_stack->tail ) {
|
||||
gui_widget_draw_intern( (GuiWidget*)entry->item );
|
||||
entry = entry->next;
|
||||
}
|
||||
/* unclip */
|
||||
stk_surface_clip( stk_display, 0,0,-1,-1 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Move position by relative value for all widgets.
|
||||
====================================================================
|
||||
*/
|
||||
static void gui_widget_move_intern(
|
||||
GuiWidget *widget, int rel_x, int rel_y)
|
||||
{
|
||||
GuiWidget *child;
|
||||
widget->screen_region.x += rel_x;
|
||||
widget->screen_region.y += rel_y;
|
||||
widget->parent_region.x += rel_x;
|
||||
widget->parent_region.y += rel_y;
|
||||
list_reset( widget->widgets );
|
||||
while ( ( child = list_next( widget->widgets ) ) )
|
||||
gui_widget_move_intern( child, rel_x, rel_y );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
PUBLICS
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
GUI events
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Return pointer to simple event (one that doesn't need
|
||||
additional data)
|
||||
====================================================================
|
||||
*/
|
||||
static GuiEvent aux_event;
|
||||
GuiEvent *gui_event_get_simple( int type )
|
||||
{
|
||||
aux_event.type = type;
|
||||
return &aux_event;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Initiate a GUI event from an SDL event.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_event_init( GuiEvent *gui_event, SDL_Event *sdl_event )
|
||||
{
|
||||
int i;
|
||||
memset( gui_event, 0, sizeof( GuiEvent ) );
|
||||
switch ( sdl_event->type ) {
|
||||
case SDL_MOUSEMOTION:
|
||||
gui_event->type = GUI_MOTION;
|
||||
gui_event->motion.x = sdl_event->motion.x;
|
||||
gui_event->motion.y = sdl_event->motion.y;
|
||||
gui_event->motion.xrel = sdl_event->motion.xrel;
|
||||
gui_event->motion.yrel = sdl_event->motion.yrel;
|
||||
gui_event->motion.state = sdl_event->motion.state;
|
||||
for ( i = 1; i <= 3; i++ )
|
||||
if ( sdl_event->motion.state & SDL_BUTTON(i) ) {
|
||||
gui_event->motion.button = i;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if ( sdl_event->type == SDL_MOUSEBUTTONUP )
|
||||
gui_event->type = GUI_BUTTON_RELEASED;
|
||||
else
|
||||
gui_event->type = GUI_BUTTON_PRESSED;
|
||||
gui_event->button.x = sdl_event->button.x;
|
||||
gui_event->button.y = sdl_event->button.y;
|
||||
gui_event->button.button = sdl_event->button.button;
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
case SDL_KEYDOWN:
|
||||
if ( sdl_event->type == SDL_KEYUP )
|
||||
gui_event->type = GUI_KEY_RELEASED;
|
||||
else
|
||||
gui_event->type = GUI_KEY_PRESSED;
|
||||
gui_event->key.keysym = sdl_event->key.keysym.sym;
|
||||
gui_event->key.unicode = sdl_event->key.keysym.unicode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
GUI widget
|
||||
====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Create a basic widget and setup things all different widget types
|
||||
have in common. If a parent is specified this widget is added to
|
||||
it's 'widgets' list. Per default following events are enabled:
|
||||
GUI_ACTIVATED, GUI_DEACTIVATED, GUI_DRAW, GUI_DESTROY,
|
||||
GUI_FOCUS_IN, GUI_FOCUS_OUT. 'x' or 'y' -1 means to center the
|
||||
widget.
|
||||
====================================================================
|
||||
*/
|
||||
GuiWidget* gui_widget_create(
|
||||
GuiWidget *parent, int type,
|
||||
int x, int y, int width, int height,
|
||||
void (*default_event_handler)(GuiWidget*,GuiEvent*),
|
||||
void (*user_event_handler)(GuiWidget*,GuiEvent*) )
|
||||
{
|
||||
GuiWidget *widget = calloc( 1, sizeof( GuiWidget ) );
|
||||
if ( widget == 0 )
|
||||
GUI_ABORT( "Out Of Memory" )
|
||||
/* create empty children list */
|
||||
if ( ( widget->widgets =
|
||||
list_create( LIST_NO_AUTO_DELETE,
|
||||
LIST_NO_CALLBACK ) ) == 0 )
|
||||
GUI_ABORT( "Out Of Memory" )
|
||||
/* various assignments */
|
||||
if ( parent ) {
|
||||
widget->parent = parent;
|
||||
list_add( widget->parent->widgets, widget );
|
||||
}
|
||||
widget->type = type;
|
||||
widget->root = (parent==0)?widget:parent->root;
|
||||
widget->active = 1;
|
||||
widget->default_event_handler = default_event_handler;
|
||||
widget->user_event_handler = user_event_handler;
|
||||
/* adjust x,y */
|
||||
if ( x == -1 ) {
|
||||
if ( parent )
|
||||
x = ( parent->width - width ) / 2;
|
||||
else
|
||||
x = ( stk_display->w - width ) / 2;
|
||||
}
|
||||
if ( y == -1 ) {
|
||||
if ( parent )
|
||||
y = ( parent->height - height ) / 2;
|
||||
else
|
||||
y = ( stk_display->h - height ) / 2;
|
||||
}
|
||||
/* region in parent */
|
||||
if ( parent == 0 ) {
|
||||
widget->parent_region.x = x;
|
||||
widget->parent_region.y = y;
|
||||
}
|
||||
else {
|
||||
widget->parent_region.x = x + widget->parent->border;
|
||||
widget->parent_region.y = y + widget->parent->border;
|
||||
}
|
||||
widget->parent_region.w = width;
|
||||
widget->parent_region.h = height;
|
||||
/* screen region */
|
||||
if ( widget->parent == 0 )
|
||||
widget->screen_region = widget->parent_region;
|
||||
else {
|
||||
widget->screen_region.x =
|
||||
widget->parent_region.x + parent->screen_region.x;
|
||||
widget->screen_region.y =
|
||||
widget->parent_region.y + parent->screen_region.y;
|
||||
widget->screen_region.w = widget->parent_region.w;
|
||||
widget->screen_region.h = widget->parent_region.h;
|
||||
}
|
||||
/* children size */
|
||||
widget->width = width; widget->height = height;
|
||||
/* events */
|
||||
gui_widget_enable_event( widget, GUI_ACTIVATED );
|
||||
gui_widget_enable_event( widget, GUI_DEACTIVATED );
|
||||
gui_widget_enable_event( widget, GUI_DRAW );
|
||||
gui_widget_enable_event( widget, GUI_DESTROY );
|
||||
gui_widget_enable_event( widget, GUI_FOCUS_IN );
|
||||
gui_widget_enable_event( widget, GUI_FOCUS_OUT );
|
||||
/* if this is a root widget add it to root_stack */
|
||||
if ( widget->root == widget )
|
||||
list_add( gui_root_stack, widget );
|
||||
/* done */
|
||||
return widget;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
This function will delete a root widget including all subwidgets.
|
||||
Subwidgets can't be directly deleted. Resets the widget
|
||||
pointer to NULL.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_delete( GuiWidget **widget )
|
||||
{
|
||||
if ( *widget == 0 ) return;
|
||||
if ( (*widget)->root != *widget ) {
|
||||
fprintf( stderr, "You can only delete root widgets!\n" );
|
||||
return;
|
||||
}
|
||||
if ( (*widget)->visible )
|
||||
list_delete_item( gui_visible_stack, *widget );
|
||||
if ( (*widget)->event_mask & GUI_TIME_PASSED )
|
||||
list_delete_item( gui_timed_stack, *widget );
|
||||
list_delete_item( gui_root_stack, *widget );
|
||||
gui_widget_delete_intern( *widget );
|
||||
*widget = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
If button is deactivated no input events (key,button,motion)
|
||||
are handled.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_set_active( GuiWidget *widget, int active )
|
||||
{
|
||||
int type;
|
||||
if ( widget->active == active ) return;
|
||||
widget->active = active;
|
||||
type = (active)?GUI_ACTIVATED:GUI_DEACTIVATED;
|
||||
widget->default_event_handler(
|
||||
widget, gui_event_get_simple( type ) );
|
||||
gui_widget_call_user_event_handler(
|
||||
widget, gui_event_get_simple( type ) );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Draw the widget and its children if visible.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_draw( GuiWidget *widget )
|
||||
{
|
||||
/* update only if visible */
|
||||
if ( !widget->visible ) return;
|
||||
/* recursively draw widget */
|
||||
gui_widget_draw_intern( widget );
|
||||
/* redraw higher level roots that overlap this widget. */
|
||||
gui_widget_redraw_overlapping_roots( widget );
|
||||
/* store update rect */
|
||||
stk_display_store_rect( &widget->screen_region );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Set 'visible' flag and draw widget (store update rects)
|
||||
if either parent is visible or it has no parent.
|
||||
(thus is a root window). If it is a root window add it to the
|
||||
root window stack. This new window will handle incoming events
|
||||
first.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_show( GuiWidget *widget )
|
||||
{
|
||||
if ( widget->visible ) return;
|
||||
if ( widget->root == widget ) {
|
||||
list_add( gui_visible_stack, widget );
|
||||
if ( widget->event_mask & GUI_TIME_PASSED )
|
||||
list_add( gui_timed_stack, widget );
|
||||
#ifdef GUI_DEBUG
|
||||
printf( "show root widget: %i,%i,%i,%i\n",
|
||||
widget->screen_region.x, widget->screen_region.y,
|
||||
widget->screen_region.w, widget->screen_region.h );
|
||||
#endif
|
||||
/* if this root widget grabs the input the old
|
||||
gui_key_widget/gui_clicked_widget is obsolete */
|
||||
if ( widget->grab_input ) {
|
||||
if ( gui_key_widget ) {
|
||||
gui_key_widget->default_event_handler(
|
||||
gui_key_widget,
|
||||
gui_event_get_simple( GUI_FOCUS_OUT ) );
|
||||
gui_key_widget = 0;
|
||||
}
|
||||
gui_clicked_widget = 0;
|
||||
}
|
||||
/* maybe there is a default key grab widget? */
|
||||
if ( widget->default_key_widget )
|
||||
gui_key_widget = widget->default_key_widget;
|
||||
}
|
||||
gui_widget_show_intern( widget, 1 );
|
||||
if ( widget->parent == 0 || widget->parent->visible )
|
||||
gui_widget_draw( widget );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Clear 'visible' flag and restore widget if parent is visible.
|
||||
If there is no parent (thus is a root window) remove it from
|
||||
stack and redraw the underlying window (which regains control). If
|
||||
a root widget is hidden the background cannot be restored
|
||||
as it is unknown.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_hide( GuiWidget *widget )
|
||||
{
|
||||
ListEntry *entry;
|
||||
if ( !widget->visible ) return;
|
||||
gui_widget_show_intern( widget, 0 );
|
||||
if ( widget->root == widget ) {
|
||||
entry = list_entry( gui_visible_stack, widget );
|
||||
if ( entry ) {
|
||||
/* remove */
|
||||
entry = entry->next;
|
||||
list_delete_entry(
|
||||
gui_visible_stack, entry->prev );
|
||||
/* FIX ME! redraw all open roots */
|
||||
entry = gui_visible_stack->head->next;
|
||||
while ( entry != gui_visible_stack->tail ) {
|
||||
gui_widget_draw( (GuiWidget*)entry->item );
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
if ( widget->event_mask & GUI_TIME_PASSED )
|
||||
list_delete_item( gui_timed_stack, widget );
|
||||
}
|
||||
else {
|
||||
/* draw parent's background */
|
||||
stk_surface_blit( widget->parent->surface,
|
||||
widget->parent_region.x, widget->parent_region.y,
|
||||
widget->parent_region.w, widget->parent_region.h,
|
||||
stk_display,
|
||||
widget->screen_region.x, widget->screen_region.y );
|
||||
/* redraw higher level roots that overlap this widget. */
|
||||
gui_widget_redraw_overlapping_roots( widget );
|
||||
/* store update rect */
|
||||
stk_display_store_rect( &widget->screen_region );
|
||||
}
|
||||
/* check if gui_key_widget is still valid */
|
||||
if ( gui_key_widget )
|
||||
if ( widget == gui_key_widget ||
|
||||
widget == gui_key_widget->parent ||
|
||||
widget == gui_key_widget->root )
|
||||
gui_key_widget = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Modify the event mask of a widget to define which events will
|
||||
be passed to user_event_handler.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_enable_event( GuiWidget *widget, int event )
|
||||
{
|
||||
widget->event_mask |= (1L << event);
|
||||
}
|
||||
void gui_widget_disable_event( GuiWidget *widget, int event )
|
||||
{
|
||||
widget->event_mask &= ~(1L << event);
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Pass GuiEvent to user defined callback if it has been installed
|
||||
and the event mask flag is True for this event.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_call_user_event_handler(
|
||||
GuiWidget *widget, GuiEvent *event )
|
||||
{
|
||||
if ( widget->user_event_handler )
|
||||
if ( widget->event_mask & (1L << event->type) )
|
||||
widget->user_event_handler( widget, event );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Handle the GUI event by calling the default_event_handler()
|
||||
and the user_event_handler() if one has been installed.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_handle_event( GuiWidget *widget, GuiEvent *event )
|
||||
{
|
||||
widget->default_event_handler( widget, event );
|
||||
gui_widget_call_user_event_handler( widget, event );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Move widget within parent window by a relative value. If the
|
||||
widget is visible the changes will be drawn to screen.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_move( GuiWidget *widget, int rel_x, int rel_y )
|
||||
{
|
||||
if ( !widget->visible )
|
||||
gui_widget_move_intern( widget, rel_x, rel_y );
|
||||
else {
|
||||
gui_widget_hide( widget );
|
||||
gui_widget_move_intern( widget, rel_x, rel_y );
|
||||
gui_widget_show( widget );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Move widget within parent window by an absolute value. If the
|
||||
widget is visible the changes will be drawn to screen.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_warp( GuiWidget *widget, int abs_x, int abs_y )
|
||||
{
|
||||
if ( widget->parent )
|
||||
gui_widget_move( widget,
|
||||
abs_x - widget->parent_region.x +
|
||||
widget->parent->border,
|
||||
abs_y - widget->parent_region.y +
|
||||
widget->parent->border );
|
||||
else
|
||||
gui_widget_move( widget,
|
||||
abs_x - widget->parent_region.x,
|
||||
abs_y - widget->parent_region.y );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Apply parents background or wallpaper within the frame (if
|
||||
any) of the widget's surface keeping the frame.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_apply_wallpaper(
|
||||
GuiWidget *widget, SDL_Surface *wallpaper, int alpha )
|
||||
{
|
||||
if ( widget->parent )
|
||||
stk_surface_blit( widget->parent->surface,
|
||||
widget->parent_region.x +
|
||||
widget->border,
|
||||
widget->parent_region.y +
|
||||
widget->border,
|
||||
widget->parent_region.w -
|
||||
(widget->border<<1),
|
||||
widget->parent_region.h -
|
||||
(widget->border<<1),
|
||||
widget->surface,
|
||||
widget->border, widget->border );
|
||||
else
|
||||
stk_surface_apply_wallpaper(
|
||||
widget->surface, widget->border, widget->border,
|
||||
widget->parent_region.w - (widget->border<<1),
|
||||
widget->parent_region.h - (widget->border<<1),
|
||||
wallpaper, alpha );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Browse the widget tree and set 'focused' true for all widgets
|
||||
that have the mouse pointer above them. 'focused_widget'
|
||||
returns the deepest widget that is focused.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_update_focus(
|
||||
GuiWidget *widget, int mx, int my, GuiWidget **focused_widget )
|
||||
{
|
||||
GuiWidget *child;
|
||||
if ( !widget->active )
|
||||
return;
|
||||
if ( !STK_IN_RECT( widget->screen_region, mx, my ) )
|
||||
return;
|
||||
widget->focused = 1;
|
||||
*focused_widget = widget;
|
||||
/* handle children recursively */
|
||||
list_reset( widget->widgets );
|
||||
while ( ( child = list_next( widget->widgets ) ) )
|
||||
gui_widget_update_focus( child, mx, my, focused_widget );
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
Get direct access to widget's surface.
|
||||
====================================================================
|
||||
*/
|
||||
SDL_Surface *gui_widget_get_surface( GuiWidget *widget )
|
||||
{
|
||||
return widget->surface;
|
||||
}
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
That key grabbing child of a root widget.
|
||||
====================================================================
|
||||
*/
|
||||
void gui_widget_set_default_key_widget(
|
||||
GuiWidget *root, GuiWidget *key_widget )
|
||||
{
|
||||
if ( root->root != root ) return;
|
||||
root->default_key_widget = key_widget;
|
||||
}
|
||||
Reference in New Issue
Block a user