/** * @brief Create/remove drag button. */ void UI_Window_SetDragButton (uiNode_t* node, bool value) { if (value) { // create the drag node uiNode_t* control = UI_AllocNode(WINDOW_DRAG_BUTTON_NAME, "controls", node->dynamic); control->root = node; control->box.size[0] = node->box.size[0]; control->box.size[1] = TOP_HEIGHT; control->box.pos[0] = 0; control->box.pos[1] = 0; control->tooltip = _("Drag to move window"); /* if there is a close button already on this windown, then insert the drag button before the close button; this is needed so the drag button is "below" the close button; if we don't do this, the drag button recieves input events for the close button first making the close button no longer working */ uiNode_t* close = UI_FindNode(node, WINDOW_CLOSE_BUTTON_NAME); if (close != nullptr) { // get the previous node of close close = UI_GetPrevNode(close); UI_InsertNode(node, close, control); } else { UI_AppendNode(node, control); } } else { // drop the drag node uiNode_t* control = UI_FindNode(node, WINDOW_DRAG_BUTTON_NAME); if (control) { UI_RemoveNode (node, control); } } EXTRADATA(node).dragButton = value; }
/** * @brief Create/remove close button on window. * @note Creates a onClick event handler, should be refactored. */ void UI_Window_SetCloseButton (uiNode_t* node, bool value) { if (value) { uiNode_t* control = UI_AllocNode(WINDOW_CLOSE_BUTTON_NAME, "button", node->dynamic); const int positionFromRight = CONTROLS_PADDING; static const char* closeCommand = "ui_close <path:root>;"; control->root = node; UI_NodeSetProperty(control, UI_GetPropertyFromBehaviour(control->behaviour, "icon"), "icons/system_close"); /** @todo Once @c image_t is known on the client, use @c image->width resp. @c image->height here */ control->box.size[0] = CONTROLS_IMAGE_DIMENSIONS; control->box.size[1] = CONTROLS_IMAGE_DIMENSIONS; control->box.pos[0] = node->box.size[0] - positionFromRight - control->box.size[0]; control->box.pos[1] = CONTROLS_PADDING; control->tooltip = _("Close the window"); control->onClick = UI_AllocStaticCommandAction(closeCommand); UI_AppendNode(node, control); } else { // drop the close node uiNode_t* control = UI_FindNode(node, WINDOW_CLOSE_BUTTON_NAME); if (control) { UI_RemoveNode (node, control); } } EXTRADATA(node).closeButton = value; }
void uiWindowNode::doLayout (uiNode_t* node) { if (!node->invalidated) return; /* use a the space */ if (EXTRADATA(node).fill) { if (node->box.size[0] != viddef.virtualWidth) { node->box.size[0] = viddef.virtualWidth; } if (node->box.size[1] != viddef.virtualHeight) { node->box.size[1] = viddef.virtualHeight; } } /* move fullscreen window on the center of the screen */ if (UI_WindowIsFullScreen(node)) { node->box.pos[0] = (int) ((viddef.virtualWidth - node->box.size[0]) / 2); node->box.pos[1] = (int) ((viddef.virtualHeight - node->box.size[1]) / 2); } /* reposition the close button */ if (EXTRADATA(node).closeButton) { uiNode_t* control = UI_FindNode(node, WINDOW_CLOSE_BUTTON_NAME); control->box.pos[0] = node->box.size[0] - CONTROLS_PADDING - control->box.size[0]; } /* resize the dragw button */ if (EXTRADATA(node).dragButton) { uiNode_t* control = UI_FindNode(node, WINDOW_DRAG_BUTTON_NAME); control->box.size[0] = node->box.size[0]; } /** @todo check and fix here window outside the screen */ if (EXTRADATA(node).starLayout) { UI_StarLayout(node); } /* super */ uiLocatedNode::doLayout(node); }
/** * @brief Recursive searches for a child node by name in the entire subtree. * @return A uiNode_t* or nullptr if not found. */ uiNode_t* UI_FindNode(const uiNode_t* node, const char* name) { /* search current level */ uiNode_t* result = UI_GetNode(node, name); if (!result) { /* iterate child nodes and search next level */ for(uiNode_t* current = node->firstChild; current; current = current->next) { result = UI_FindNode(current, name); if (result) break; } } return result; }