/** * Apply an action value to a node property. If the tuple property/value allow it, the function * pre compute the value and update the action value to speed up the next call. * @param node Node to edit * @param property Property of the node to edit * @param value Action value containing the value to set to the node property * @param context Call context of the script * @todo refactoring it to remove "context", we should only call that function when the action * value is a leaf (then a value, and not an expression) */ static void UI_NodeSetPropertyFromActionValue (uiNode_t *node, const value_t *property, const uiCallContext_t *context, uiAction_t* value) { /* @todo we can use a new EA_VALUE type to flag already parsed values, we dont need to do it again and again */ /* pre compute value if possible */ if (value->type == EA_VALUE_STRING) { const char* string = value->d.terminal.d1.constString; if ((property->type & V_UI_MASK) == V_UI_CVAR && Q_strstart(string, "*cvar:")) { Com_GetValue<void*>(node, property) = value->d.terminal.d1.data; } else { /** @todo here we must catch error in a better way, and using cvar for error code to create unittest automations */ UI_InitRawActionValue(value, node, property, string); } } /* decode RAW value */ if (value->type == EA_VALUE_RAW) { const void *rawValue = value->d.terminal.d1.constData; const int rawType = value->d.terminal.d2.integer; UI_NodeSetPropertyFromRAW(node, property, rawValue, rawType); } /* else it is an expression */ else { /** @todo we should improve if when the prop is a boolean/int/float */ const char* string = UI_GetStringFromExpression(value, context); UI_NodeSetProperty(node, property, string); } }
/** * @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; }
/** * @brief Called at the end of the load from script */ void uiWindowNode::onLoaded (uiNode_t* node) { /* create a drag zone, if it is requested */ if (EXTRADATA(node).dragButton) { uiNode_t* control = UI_AllocNode("move_window_button", "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"); UI_AppendNode(node, control); } /* create a close button, if it is requested */ if (EXTRADATA(node).closeButton) { uiNode_t* button = UI_AllocNode("close_window_button", "button", node->dynamic); const int positionFromRight = CONTROLS_PADDING; static const char* closeCommand = "ui_close <path:root>;"; button->root = node; UI_NodeSetProperty(button, UI_GetPropertyFromBehaviour(button->behaviour, "icon"), "icons/system_close"); /** @todo Once @c image_t is known on the client, use @c image->width resp. @c image->height here */ button->box.size[0] = CONTROLS_IMAGE_DIMENSIONS; button->box.size[1] = CONTROLS_IMAGE_DIMENSIONS; button->box.pos[0] = node->box.size[0] - positionFromRight - button->box.size[0]; button->box.pos[1] = CONTROLS_PADDING; button->tooltip = _("Close the window"); button->onClick = UI_AllocStaticCommandAction(closeCommand); UI_AppendNode(node, button); } EXTRADATA(node).isFullScreen = node->box.size[0] == VID_NORM_WIDTH && node->box.size[1] == VID_NORM_HEIGHT; if (EXTRADATA(node).starLayout) UI_Invalidate(node); }
/** * @brief set a node property from the command line * @todo Unify path syntaxe to allow to create a common autocompletion */ static void UI_NodeSetProperty_f (void) { uiNode_t* node; const value_t* property; if (Cmd_Argc() != 4) { Com_Printf("Usage: %s <nodepath> <prop> <value>\n", Cmd_Argv(0)); return; } node = UI_GetNodeByPath(Cmd_Argv(1)); if (!node) { Com_Printf("UI_NodeSetProperty_f: Node '%s' not found\n", Cmd_Argv(1)); return; } property = UI_GetPropertyFromBehaviour(node->behaviour, Cmd_Argv(2)); if (!property) { Com_Printf("Property '%s@%s' doesn't exist\n", UI_GetPath(node), Cmd_Argv(2)); return; } UI_NodeSetProperty(node, property, Cmd_Argv(3)); }