/******************************************************************************\ Popup widget event function. \******************************************************************************/ static int popup_event(i_widget_t *widget, i_event_t event) { c_vec2_t origin; float height; switch (event) { case I_EV_CONFIGURE: height = R_font_height(R_FONT_GUI) / r_scale_2d; if (height < 16.f) height = 16.f; widget->size = C_vec2(0.f, height + i_border.value.n * 2.f); I_widget_pack(widget, I_PACK_H, I_FIT_BOTTOM); origin = C_vec2(r_width_2d / 2.f - widget->size.x / 2.f, r_height_2d - widget->size.y - i_border.value.n); R_window_cleanup(&popup_window); R_window_init(&popup_window, decor_popup); I_widget_move(widget, origin); case I_EV_MOVED: popup_window.sprite.size = widget->size; popup_window.sprite.origin = widget->origin; return FALSE; case I_EV_MOUSE_IN: popup_wait = TRUE; i_key_focus = NULL; break; case I_EV_MOUSE_OUT: popup_wait = FALSE; break; case I_EV_MOUSE_DOWN: if (i_mouse_button == SDL_BUTTON_RIGHT) I_widget_event(&popup_widget, I_EV_HIDE); break; case I_EV_KEY_DOWN: if (i_key == SDLK_ESCAPE) I_widget_event(&popup_widget, I_EV_HIDE); break; case I_EV_CLEANUP: R_window_cleanup(&popup_window); break; case I_EV_RENDER: if (popup_wait) popup_time = c_time_msec; else if (c_time_msec - popup_time > POPUP_TIME) I_widget_event(&popup_widget, I_EV_HIDE); popup_window.sprite.modulate.a = widget->fade; R_window_render(&popup_window); break; default: break; } return TRUE; }
/******************************************************************************\ Positions a child window. \******************************************************************************/ void I_toolbar_position(i_toolbar_t *toolbar, int i) { i_widget_t *widget; c_vec2_t origin; widget = &toolbar->windows[i].widget; origin = toolbar->widget.origin; origin.y -= i_border.value.n + widget->size.y; if (toolbar->right) origin.x += toolbar->widget.size.x - widget->size.x; I_widget_move(widget, origin); }
/******************************************************************************\ Position a ring on its world origin. \******************************************************************************/ static void position_and_pack(void) { c_vec2_t origin, size; float angle; int i, j; /* Position the ring */ size = C_vec2_scalef(ring_widget.size, 0.5f); I_widget_move(&ring_widget, C_vec2_sub(screen_origin, size)); /* Pack the visible buttons */ for (j = i = 0; i < I_RING_ICONS; i++) { if (!button_widgets[i].widget.shown) continue; angle = 2.f * C_PI * ((float)j++ / buttons - 0.25f); origin = C_vec2_scalef(C_vec2(cosf(angle), sinf(angle)), RING_INNER_RADIUS + RING_ICON_SIZE / 2.f); origin = C_vec2_add(screen_origin, origin); origin = C_vec2(origin.x - RING_ICON_SIZE / 2.f, origin.y - RING_ICON_SIZE / 2.f); I_widget_move(&button_widgets[i].widget, origin); } }
/******************************************************************************\ Move a widget and all of its children. Will not generate move events if the origin did not change. \******************************************************************************/ void I_widget_move(i_widget_t *widget, c_vec2_t origin) { i_widget_t *child; c_vec2_t diff; diff = C_vec2_sub(origin, widget->origin); if (!diff.x && !diff.y) return; widget->origin = origin; child = widget->child; while (child) { I_widget_move(child, C_vec2_add(child->origin, diff)); child = child->next; } if (widget->event_func) widget->event_func(widget, I_EV_MOVED); }