Esempio n. 1
0
/******************************************************************************\
 Ring widget event function.
\******************************************************************************/
static int ring_event(i_widget_t *widget, i_event_t event)
{
        float radius;

        /* Calculate mouse radius for mouse events */
        if (event == I_EV_MOUSE_MOVE || event == I_EV_MOUSE_DOWN)
                radius = C_vec2_len(C_vec2_sub(i_mouse, screen_origin));

        switch (event) {
        case I_EV_CONFIGURE:
                R_sprite_cleanup(&ring_sprite);
                R_sprite_init(&ring_sprite, ring_texture);
                ring_widget.size = ring_sprite.size;
                I_widget_propagate(widget, I_EV_CONFIGURE);
                position_and_pack();
                return FALSE;
        case I_EV_MOVED:
                ring_sprite.origin = ring_widget.origin;
                break;
        case I_EV_MOUSE_OUT:
                I_close_ring();
                break;
        case I_EV_MOUSE_MOVE:
                if (radius > RING_OUTER_RADIUS)
                        I_close_ring();
                else
                        detail_hover();
                break;
        case I_EV_MOUSE_DOWN:
                if (i_mouse_button != SDL_BUTTON_LEFT)
                        I_close_ring();
                if (radius <= RING_INNER_RADIUS) {
                        I_close_ring();
                        return FALSE;
                }
                break;
        case I_EV_CLEANUP:
                R_sprite_cleanup(&ring_sprite);
                break;
        case I_EV_RENDER:
                ring_sprite.modulate.a = ring_widget.fade;
                R_sprite_render(&ring_sprite);
                detail_update();
                break;
        default:
                break;
        }
        return TRUE;
}
Esempio n. 2
0
/******************************************************************************\
 Window widget event function.
\******************************************************************************/
int I_window_event(i_window_t *window, i_event_t event)
{
        switch (event) {
        case I_EV_CONFIGURE:
                R_window_cleanup(&window->window);
                I_widget_pack(&window->widget, window->pack_children,
                              window->fit);
                if (window->decorated) {
                        r_texture_t *decor;

                        decor = decor_window;
                        if (window->popup)
                                decor = decor_popup;
                        R_window_init(&window->window, decor);
                        window->window.sprite.origin = window->widget.origin;
                        window->window.sprite.size = window->widget.size;
                        R_sprite_cleanup(&window->hanger);
                        R_sprite_init(&window->hanger, hanger);
                        window->hanger.origin.y = window->widget.origin.y +
                                                  window->widget.size.y;
                        window->hanger.size.y = (float)i_border.value.n;
                }
                return FALSE;
        case I_EV_KEY_DOWN:
                if (i_key == SDLK_ESCAPE && window->auto_hide)
                        I_widget_event(&window->widget, I_EV_HIDE);
                break;
        case I_EV_MOUSE_IN:
                if (I_widget_child_of(&window->widget, i_key_focus))
                        break;
                i_key_focus = NULL;
                I_widget_propagate(&window->widget, I_EV_GRAB_FOCUS);
                break;
        case I_EV_MOVED:
                window->window.sprite.origin = window->widget.origin;
                window->hanger.origin.y = window->widget.origin.y +
                                          window->widget.size.y;
                break;
        case I_EV_MOUSE_DOWN:
                if (i_mouse_button == SDL_BUTTON_RIGHT && window->auto_hide)
                        I_widget_event(&window->widget, I_EV_HIDE);
                break;
        case I_EV_CLEANUP:
                R_window_cleanup(&window->window);
                R_sprite_cleanup(&window->hanger);
                break;
        case I_EV_RENDER:
                if (!window->decorated)
                        break;
                window->window.sprite.modulate.a = window->widget.fade;
                R_window_render(&window->window);
                if (!window->hanger_align)
                        break;
                window->hanger.origin.x = window->hanger_align->origin.x +
                                          window->hanger_align->size.x / 2 -
                                          window->hanger.size.x / 2;
                window->hanger.modulate.a = window->widget.fade;
                R_sprite_render(&window->hanger);
                break;
        default:
                break;
        }
        return TRUE;
}
Esempio n. 3
0
/******************************************************************************\
 Dispatches basic widget events and does some checks to see if the event
 applies to this widget. Cleans up resources on I_EV_CLEANUP and propagates
 the event to all child widgets.

 Key focus follows the mouse. Only one widget can have keyboard focus at any
 time and that is the last widget that the mouse cursor passed over that
 could take keyboard input.

 Events filter down through containers to child widgets. The ordering will call
 all of a widget's parent containers before calling the widget and will call
 all of the children of a widget before calling a sibling.

 Always call this function instead of a widget's class event function in order
 to ensure correct event filtering and propagation.
\******************************************************************************/
void I_widget_event(i_widget_t *widget, i_event_t event)
{
        if (!widget)
                return;
        if (!widget->name[0] || !widget->event_func) {
                if (event == I_EV_CLEANUP)
                        return;
                C_error("Propagated %s to uninitialized widget, parent is %s",
                        I_event_to_string(event),
                        widget->parent ? widget->parent->name : "NULL");
        }

        /* The only event an unconfigured widget can handle is I_EV_CONFIGURE */
        if (!widget->configured && event != I_EV_CONFIGURE) {
                if (widget->auto_configure)
                        I_widget_event(widget, I_EV_CONFIGURE);
                if (!widget->configured)
                        C_error("Propagated %s to unconfigured %s",
                                I_event_to_string(event), widget->name);
        }

        /* Print out the event in debug mode */
        if (i_debug.value.n >= 2)
                switch (event) {
                default:
                        C_trace("%s --> %s", I_event_to_string(event),
                                widget->name);
                case I_EV_RENDER:
                case I_EV_MOUSE_MOVE:
                case I_EV_MOUSE_FOCUS:
                case I_EV_GRAB_FOCUS:
                case I_EV_KEY_UP:
                case I_EV_MOUSE_UP:
                        break;
                }

        /* Before handling and propagating event to children */
        switch (event) {
        case I_EV_CLEANUP:
                if (c_mem_check.value.n)
                        C_trace("Freeing %s", widget->name);
                break;
        case I_EV_CONFIGURE:
                if (c_mem_check.value.n)
                        C_trace("Configuring %s", widget->name);
                break;
        case I_EV_GRAB_FOCUS:
                if (widget->entry && widget->shown &&
                    widget->state != I_WS_DISABLED)
                        key_focus = widget;
                break;
        case I_EV_HIDE:
                if (!widget->shown)
                        return;
                widget->shown = FALSE;
                widget->event_func(widget, event);
                focus_parent(widget);
                return;
        case I_EV_KEY_DOWN:
                if (widget->steal_keys &&
                    widget->state != I_WS_DISABLED && widget->shown &&
                    widget->state != I_WS_NO_FOCUS)
                        widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_IN:
                if (widget->state == I_WS_READY)
                        widget->state = I_WS_HOVER;
                widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_OUT:
                if (widget->state == I_WS_HOVER || widget->state == I_WS_ACTIVE)
                        widget->state = I_WS_READY;
                widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_DOWN:
                widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_FOCUS:
                if (!check_mouse_focus(widget))
                        return;
                break;
        case I_EV_MOUSE_MOVE:
                if (widget->state == I_WS_READY)
                        I_widget_event(widget, I_EV_MOUSE_IN);
                widget->event_func(widget, event);
                return;
        case I_EV_KEY_FOCUS:
                key_focus = mouse_focus;
                widget->event_func(widget, event);
                return;
        case I_EV_MOVED:
                C_error("I_EV_MOVED should only be generated by "
                        "I_widget_move()");
        case I_EV_RENDER:
                if (!i_debug.value.n && widget->parent &&
                    !C_rect_intersect(widget->origin, widget->size,
                                      widget->parent->origin,
                                      widget->parent->size))
                        return;
                if (i_fade.value.f > 0.f) {
                        float target, rate;

                        target = 0.f;

                        /* Widgets inherit the parent widget's fade */
                        if (widget->shown) {
                                target = 1.f;
                                if (widget->parent)
                                        target = widget->parent->fade;
                        }

                        rate = i_fade.value.f * c_frame_sec;
                        if (widget->state == I_WS_DISABLED) {
                                target *= 0.25f;
                                if (widget->fade <= 0.25f)
                                        rate *= 0.25f;
                        }
                        if (widget->fade < target) {
                                widget->fade += rate;
                                if (widget->fade > target)
                                        widget->fade = target;
                        } else if (widget->fade > target) {
                                widget->fade -= rate;
                                if (widget->fade < target)
                                        widget->fade = target;
                        }

                        /* Widget should never be less faded than its parent */
                        if (widget->parent &&
                            widget->parent->fade < widget->fade)
                                widget->fade = widget->parent->fade;

                        if (widget->fade <= 0.f)
                                return;
                } else if (!widget->shown)
                        return;
                break;
        case I_EV_SHOW:
                if (widget->shown)
                        return;
                widget->shown = TRUE;
                widget->event_func(widget, event);
                find_focus();
                return;
        default:
                break;
        }

        /* Call widget-specific event handler and propagate event down */
        if (widget->event_func(widget, event))
                I_widget_propagate(widget, event);

        /* After handling and propagation to children */
        switch (event) {
        case I_EV_CONFIGURE:
                widget->configured = TRUE;
                break;
        case I_EV_CLEANUP:
                focus_parent(widget);
                if (i_mouse_focus == widget)
                        i_mouse_focus = NULL;
                if (i_key_focus == widget)
                        i_key_focus = NULL;
                if (widget->heap)
                        C_free(widget);
                else
                        C_zero(widget);
                break;
        case I_EV_MOUSE_DOWN:
        case I_EV_MOUSE_UP:
                if (mouse_focus == widget && widget->state == I_WS_READY)
                        widget->state = I_WS_HOVER;
                break;
        default:
                break;
        }
}