/** * @brief Handles CustomButton draw */ static void UI_CustomButtonNodeDraw (uiNode_t *node) { const char *text; int texY; const float *textColor; const char *image; vec2_t pos; static vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0}; uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL; const char *font = UI_GetFontFromNode(node); if (!node->onClick || node->disabled) { /** @todo need custom color when button is disabled */ textColor = disabledColor; texY = UI_CUSTOMBUTTON_TEX_HEIGHT * 2; iconStatus = SPRITE_STATUS_DISABLED; } else if (node->state) { textColor = node->selectedColor; texY = UI_CUSTOMBUTTON_TEX_HEIGHT; iconStatus = SPRITE_STATUS_HOVER; } else { textColor = node->color; texY = 0; } UI_GetNodeAbsPos(node, pos); image = UI_GetReferenceString(node, node->image); if (image) { const int texX = rint(EXTRADATA(node).texl[0]); texY += EXTRADATA(node).texl[1]; UI_DrawNormImageByName(qfalse, pos[0], pos[1], node->size[0], node->size[1], texX + node->size[0], texY + node->size[1], texX, texY, image); } if (EXTRADATA(node).background) { UI_DrawSpriteInBox(qfalse, EXTRADATA(node).background, iconStatus, pos[0], pos[1], node->size[0], node->size[1]); } if (EXTRADATA(node).super.icon) { UI_DrawSpriteInBox(EXTRADATA(node).super.flipIcon, EXTRADATA(node).super.icon, iconStatus, pos[0], pos[1], node->size[0], node->size[1]); } text = UI_GetReferenceString(node, node->text); if (text != NULL && *text != '\0') { R_Color(textColor); UI_DrawStringInBox(font, node->contentAlign, pos[0] + node->padding, pos[1] + node->padding, node->size[0] - node->padding - node->padding, node->size[1] - node->padding - node->padding, text, LONGLINES_PRETTYCHOP); R_Color(NULL); } }
/** * @brief Wrapper for UI tooltips */ void UI_Tooltip (const uiNode_t* node, int x, int y) { const char* string; const char* key = nullptr; const char* tooltip = nullptr; static const int maxWidth = 200; /* check values */ if (node->key) key = Key_KeynumToString(node->key->key); if (node->tooltip) tooltip = UI_GetReferenceString(node, node->tooltip); /* normalize */ if (tooltip && tooltip[0] == '\0') tooltip = nullptr; if (key && key[0] == '\0') key = nullptr; /* create tooltip */ if (key && tooltip) { char buf[MAX_VAR]; Com_sprintf(buf, sizeof(buf), _("Key: %s"), key); string = va("%s\n%s", tooltip, buf); } else if (tooltip) { string = tooltip; } else if (key) { string = va(_("Key: %s"), key); } else { return; } UI_DrawTooltip(string, x, y, maxWidth); }
/** * @brief Draw an item node */ void uiItemNode::draw (uiNode_t* node) { const objDef_t* od; const char* ref = UI_GetReferenceString(node, EXTRADATA(node).model); vec2_t pos; if (Q_strnull(ref)) return; UI_GetNodeAbsPos(node, pos); R_CleanupDepthBuffer(pos[0], pos[1], node->box.size[0], node->box.size[1]); od = INVSH_GetItemByIDSilent(ref); if (od) { Item item(od, nullptr, 1); /* 1 so it's not reddish; fake item anyway */ const char* model = GAME_GetModelForItem(item.def(), nullptr); if (EXTRADATA(node).containerLike || Q_strnull(model)) { const vec4_t color = {1, 1, 1, 1}; vec3_t itemNodePos; /* We position the model of the item ourself (in the middle of the item * node). See the "-1, -1" parameter of UI_DrawItem. */ UI_GetNodeAbsPos(node, itemNodePos); itemNodePos[0] += node->box.size[0] / 2.0; itemNodePos[1] += node->box.size[1] / 2.0; itemNodePos[2] = 0; /** @todo we should not use DrawItem but draw the image with render function (remove dependency with container) */ UI_DrawItem(node, itemNodePos, &item, -1, -1, EXTRADATA(node).scale, color); } else { UI_DrawModelNode(node, model); } } else { GAME_DisplayItemInfo(node, ref); } }
static void UI_TBarNodeDraw (uiNode_t *node) { /* dataImageOrModel is the texture name */ float shx; vec2_t nodepos; const char* ref = UI_GetReferenceString(node, node->image); float pointWidth; float width; if (Q_strnull(ref)) return; UI_GetNodeAbsPos(node, nodepos); pointWidth = TEXTURE_WIDTH / 100.0; /* relative to the texture */ { float ps; const float min = UI_GetReferenceFloat(node, EXTRADATA(node).super.min); const float max = UI_GetReferenceFloat(node, EXTRADATA(node).super.max); float value = UI_GetReferenceFloat(node, EXTRADATA(node).super.value); /* clamp the value */ if (value > max) value = max; if (value < min) value = min; ps = (value - min) / (max - min) * 100; shx = EXTRADATA(node).texl[0]; /* left gap to the texture */ shx += round(ps * pointWidth); /* add size from 0..TEXTURE_WIDTH */ } width = (shx * node->size[0]) / TEXTURE_WIDTH; UI_DrawNormImageByName(qfalse, nodepos[0], nodepos[1], width, node->size[1], shx, EXTRADATA(node).texh[1], EXTRADATA(node).texl[0], EXTRADATA(node).texl[1], ref); }
/** * @brief Return the font for a specific node or default font * @param[in] node Context node * @return char pointer with font name (default is f_small) */ const char* UI_GetFontFromNode (const uiNode_t* const node) { if (node && node->font) { return UI_GetReferenceString(node, node->font); } return "f_small"; }
/** * @brief Return a string from a node property * @param[in] node Requested node * @param[in] property Requested property * @return Return a string value of a property, else nullptr, if the type is not supported */ const char* UI_GetStringFromNodeProperty (const uiNode_t* node, const value_t* property) { const int baseType = property->type & V_UI_MASK; assert(node); assert(property); switch (baseType) { case V_NOT_UI: /* common type */ return Com_ValueToStr(node, property->type, property->ofs); case V_UI_CVAR: switch ((int)property->type) { case V_CVAR_OR_FLOAT: { const float f = UI_GetReferenceFloat(node, Com_GetValue<void*>(node, property)); const int i = f; if (f == i) return va("%i", i); else return va("%f", f); } case V_CVAR_OR_LONGSTRING: case V_CVAR_OR_STRING: case V_UI_CVAR: return UI_GetReferenceString(node, Com_GetValue<char*>(node, property)); } break; default: break; } Com_Printf("UI_GetStringFromNodeProperty: Unsupported string getter for property type 0x%X (%s@%s)\n", property->type, UI_GetPath(node), property->string); return nullptr; }
void uiTextEntryNode::draw (uiNode_t* node) { const float* textColor; vec2_t pos; const char* font = UI_GetFontFromNode(node); uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL; if (node->disabled) { textColor = node->disabledColor; iconStatus = SPRITE_STATUS_DISABLED; } else if (node->state) { textColor = node->color; iconStatus = SPRITE_STATUS_HOVER; } else { textColor = node->color; } if (UI_HasFocus(node)) { textColor = node->selectedColor; } UI_GetNodeAbsPos(node, pos); if (EXTRADATA(node).background) { UI_DrawSpriteInBox(false, EXTRADATA(node).background, iconStatus, pos[0], pos[1], node->box.size[0], node->box.size[1]); } if (char const* const text = UI_GetReferenceString(node, node->text)) { char buf[MAX_VAR]; if (EXTRADATA(node).isPassword) { size_t size = UTF8_strlen(text); if (size > MAX_VAR - 2) size = MAX_VAR - 2; memset(buf, HIDECHAR, size); buf[size] = '\0'; } else { /* leave one byte empty for the text-based cursor */ UTF8_strncpyz(buf, text, sizeof(buf) - 1); } /** @todo Make the cursor into a real graphical object instead of using a text character. */ if (UI_HasFocus(node)) { if (CL_Milliseconds() % 1000 < 500) { UTF8_insert_char_at(buf, sizeof(buf), EXTRADATA(node).cursorPosition, (int)CURSOR_ON); } else { UTF8_insert_char_at(buf, sizeof(buf), EXTRADATA(node).cursorPosition, (int)CURSOR_OFF); } } if (*buf != '\0') { R_Color(textColor); UI_DrawStringInBox(font, (align_t)node->contentAlign, pos[0] + node->padding, pos[1] + node->padding, node->box.size[0] - node->padding - node->padding, node->box.size[1] - node->padding - node->padding, buf); R_Color(nullptr); } } }
static void UI_CheckBoxNodeDraw (uiNode_t* node) { const float value = UI_GetReferenceFloat(node, EXTRADATA(node).value); vec2_t pos; const char *image = UI_GetReferenceString(node, node->image); int texx, texy; /* image set? */ if (Q_strnull(image)) return; /* outer status */ if (node->disabled) { texy = 96; } else if (node->state) { texy = 32; } else { texy = 0; } /* inner status */ if (value == 0) { texx = 0; } else if (value > 0) { texx = 32; } else { /* value < 0 */ texx = 64; } UI_GetNodeAbsPos(node, pos); UI_DrawNormImageByName(qfalse, pos[0], pos[1], node->size[0], node->size[1], texx + node->size[0], texy + node->size[1], texx, texy, image); }
/** * @brief Draw a text node */ void uiTextNode::draw (uiNode_t* node) { const uiSharedData_t* shared; if (EXTRADATA(node).dataID == TEXT_NULL && node->text != nullptr) { const char* t = CL_Translate(UI_GetReferenceString(node, node->text)); drawText(node, t, nullptr, false); return; } shared = &ui_global.sharedData[EXTRADATA(node).dataID]; switch (shared->type) { case UI_SHARED_TEXT: { const char* t = CL_Translate(shared->data.text); drawText(node, t, nullptr, false); break; } case UI_SHARED_LINKEDLISTTEXT: drawText(node, nullptr, shared->data.linkedListText, false); break; default: break; } EXTRADATA(node).versionId = shared->versionId; }
void uiSelectBoxNode::draw (uiNode_t* node) { uiNode_t* option; int selBoxX, selBoxY; const char* ref; const char* font; vec2_t nodepos; const char* imageName; const image_t* image; static vec4_t invisColor = {1.0, 1.0, 1.0, 0.7}; ref = UI_AbstractOptionGetCurrentValue(node); if (ref == nullptr) return; UI_GetNodeAbsPos(node, nodepos); imageName = UI_GetReferenceString(node, node->image); if (!imageName) imageName = "ui/selectbox"; image = UI_LoadImage(imageName); font = UI_GetFontFromNode(node); selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH; selBoxY = nodepos[1] + SELECTBOX_SPACER; /* left border */ UI_DrawNormImage(false, nodepos[0], nodepos[1], SELECTBOX_SIDE_WIDTH, node->box.size[1], SELECTBOX_SIDE_WIDTH, SELECTBOX_DEFAULT_HEIGHT, 0.0f, 0.0f, image); /* stretched middle bar */ UI_DrawNormImage(false, nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1], node->box.size[0]-SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, node->box.size[1], 12.0f, SELECTBOX_DEFAULT_HEIGHT, 7.0f, 0.0f, image); /* right border (arrow) */ UI_DrawNormImage(false, nodepos[0] + node->box.size[0] - SELECTBOX_RIGHT_WIDTH, nodepos[1], SELECTBOX_DEFAULT_HEIGHT, node->box.size[1], 12.0f + SELECTBOX_RIGHT_WIDTH, SELECTBOX_DEFAULT_HEIGHT, 12.0f, 0.0f, image); /* draw the label for the current selected option */ for (option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) { if (!Q_streq(OPTIONEXTRADATA(option).value, ref)) continue; if (option->invis) R_Color(invisColor); const char* label = CL_Translate(OPTIONEXTRADATA(option).label); UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY, selBoxX, node->box.size[0] - 4, 0, label, 0, 0, nullptr, false, LONGLINES_PRETTYCHOP); R_Color(nullptr); break; } /* must we draw the drop-down list */ if (UI_GetMouseCapture() == node) { UI_CaptureDrawOver(node); } }
static qboolean UI_RadioButtonNodeIsSelected (uiNode_t *node) { if (EXTRADATA(node).string == NULL) { const float current = UI_GetReferenceFloat(node, EXTRADATA(node).cvar); return current > EXTRADATA(node).value - EPSILON && current < EXTRADATA(node).value + EPSILON; } else { const char *current = UI_GetReferenceString(node, EXTRADATA(node).cvar); return Q_streq(current, EXTRADATA(node).string); } }
void uiModelNode::draw (uiNode_t* node) { const char* ref = UI_GetReferenceString(node, EXTRADATA(node).model); char source[MAX_VAR]; if (Q_strnull(ref)) source[0] = '\0'; else Q_strncpyz(source, ref, sizeof(source)); UI_DrawModelNode(node, source); }
/** * @brief Custom tooltip of todo node * @param[in] node Node we request to draw tooltip * @param[in] x,y Position of the mouse */ static void UI_TodoNodeDrawTooltip (uiNode_t* node, int x, int y) { const int tooltipWidth = 250; static char tooltiptext[1024]; const char* text = UI_GetReferenceString(node, node->text); if (!text) return; tooltiptext[0] = '\0'; Q_strcat(tooltiptext, sizeof(tooltiptext), "%s", text); UI_DrawTooltip(tooltiptext, x, y, tooltipWidth); }
const char *UI_AbstractOptionGetCurrentValue (uiNode_t * node) { /* no cvar given? */ if (!EXTRADATA(node).cvar || !*EXTRADATA(node).cvar) { Com_Printf("UI_AbstractOptionGetCurrentValue: node '%s' doesn't have a valid cvar assigned\n", UI_GetPath(node)); return NULL; } /* not a cvar? */ if (!Q_strstart(EXTRADATA(node).cvar, "*cvar:")) return NULL; return UI_GetReferenceString(node, EXTRADATA(node).cvar); }
static void UI_TextNodeGenerateLineSplit (uiNode_t* node) { const char* data; int bufferSize = 1024; char* buffer = Mem_AllocTypeN(char, bufferSize); LIST_Delete(&EXTRADATA(node).lineSplit); if (node->text != nullptr) data = UI_GetReferenceString(node, node->text); else if (EXTRADATA(node).super.dataID != TEXT_NULL) { const uiSharedData_t* shared; shared = &ui_global.sharedData[EXTRADATA(node).super.dataID]; switch (shared->type) { case UI_SHARED_TEXT: data = UI_GetText(EXTRADATA(node).super.dataID); break; case UI_SHARED_LINKEDLISTTEXT: return; default: return; } } else return; data = CL_Translate(data); while (data[0] != '\0') { const char* next = strchr(data, '\n'); int lineSize; if (next == nullptr) lineSize = strlen(data); else lineSize = next - data; if (lineSize + 1 > bufferSize) { bufferSize = lineSize + 1; Mem_Free(buffer); buffer = Mem_AllocTypeN(char, bufferSize); } Q_strncpyz(buffer, data, lineSize + 1); LIST_AddString(&EXTRADATA(node).lineSplit, buffer); if (next == nullptr) break; data = next + 1; }
const char* UI_AbstractOption_GetCurrentValue (uiNode_t* node) { /* no cvar given? */ if (!EXTRADATA(node).cvar || !*EXTRADATA(node).cvar) { Com_Printf("UI_AbstractOptionGetCurrentValue: node [%s] doesn't have a valid cvar assigned\n", UI_GetPath(node)); return nullptr; } /* not a cvar? */ if (!Q_strstart(EXTRADATA(node).cvar, "*cvar:")) { Com_Printf("UI_AbstractOptionGetCurrentValue: in node [%s], the name [%s] is not a value cvar\n", UI_GetPath(node), EXTRADATA(node).cvar); return nullptr; } return UI_GetReferenceString(node, EXTRADATA(node).cvar); }
/** * @brief Handles Button draw */ static void UI_PanelNodeDraw (uiNode_t *node) { static const int panelTemplate[] = { CORNER_SIZE, MID_SIZE, CORNER_SIZE, CORNER_SIZE, MID_SIZE, CORNER_SIZE, MARGE }; const char *image; vec2_t pos; UI_GetNodeAbsPos(node, pos); image = UI_GetReferenceString(node, node->image); if (image) UI_DrawPanel(pos, node->size, image, 0, 0, panelTemplate); }
void uiWindowNode::draw (uiNode_t* node) { const char* text; vec2_t pos; const char* font = UI_GetFontFromNode(node); UI_GetNodeAbsPos(node, pos); /* black border for anamorphic mode */ /** @todo it should be over the window */ /** @todo why not using glClear here with glClearColor set to black here? */ if (UI_WindowIsFullScreen(node)) { /* top */ if (pos[1] != 0) UI_DrawFill(0, 0, viddef.virtualWidth, pos[1], anamorphicBorder); /* left-right */ if (pos[0] != 0) UI_DrawFill(0, pos[1], pos[0], node->box.size[1], anamorphicBorder); if (pos[0] + node->box.size[0] < viddef.virtualWidth) { const int width = viddef.virtualWidth - (pos[0] + node->box.size[0]); UI_DrawFill(viddef.virtualWidth - width, pos[1], width, node->box.size[1], anamorphicBorder); } /* bottom */ if (pos[1] + node->box.size[1] < viddef.virtualHeight) { const int height = viddef.virtualHeight - (pos[1] + node->box.size[1]); UI_DrawFill(0, viddef.virtualHeight - height, viddef.virtualWidth, height, anamorphicBorder); } } /* hide background if window is modal */ if (EXTRADATA(node).modal && ui_global.windowStack[ui_global.windowStackPos - 1] == node) UI_DrawFill(0, 0, viddef.virtualWidth, viddef.virtualHeight, modalBackground); if (EXTRADATA(node).background) { UI_DrawSpriteInBox(false, EXTRADATA(node).background, SPRITE_STATUS_NORMAL, pos[0], pos[1], node->box.size[0], node->box.size[1]); } /* draw the title */ text = UI_GetReferenceString(node, node->text); if (text) UI_DrawStringInBox(font, ALIGN_CC, pos[0] + node->padding, pos[1] + node->padding, node->box.size[0] - node->padding - node->padding, TOP_HEIGHT + 10 - node->padding - node->padding, text); }
/** * @brief Draws the texture node * @param[in] node The UI node to draw */ void uiTextureNode::draw (uiNode_t* node) { vec2_t nodepos; const image_t* image; const char* imageName = UI_GetReferenceString(node, node->image); if (Q_strnull(imageName)) return; image = UI_LoadWrappedImage(imageName); if (!image) return; /* avoid potential infinit loop */ if (image->height == 0 || image->width == 0) return; UI_GetNodeAbsPos(node, nodepos); UI_DrawNormImage(false, nodepos[0], nodepos[1], node->box.size[0], node->box.size[1], node->box.size[0], node->box.size[1], 0, 0, image); }
/** * @brief Handles RadioButton draw * @todo need to implement image. We can't do everything with only one icon (or use another icon) */ static void UI_RadioButtonNodeDraw (uiNode_t *node) { vec2_t pos; uiSpriteStatus_t iconStatus; const qboolean disabled = node->disabled || node->parent->disabled; int texY; const char *image; const qboolean isSelected = UI_RadioButtonNodeIsSelected(node); if (disabled) { iconStatus = SPRITE_STATUS_DISABLED; texY = UI_4STATUS_TEX_HEIGHT * 2; } else if (isSelected) { iconStatus = SPRITE_STATUS_CLICKED; texY = UI_4STATUS_TEX_HEIGHT * 3; } else if (node->state) { iconStatus = SPRITE_STATUS_HOVER; texY = UI_4STATUS_TEX_HEIGHT; } else { iconStatus = SPRITE_STATUS_NORMAL; texY = 0; } UI_GetNodeAbsPos(node, pos); image = UI_GetReferenceString(node, node->image); if (image) { const int texX = 0; UI_DrawNormImageByName(qfalse, pos[0], pos[1], node->size[0], node->size[1], texX + node->size[0], texY + node->size[1], texX, texY, image); } if (EXTRADATA(node).background) { UI_DrawSpriteInBox(qfalse, EXTRADATA(node).background, iconStatus, pos[0], pos[1], node->size[0], node->size[1]); } if (EXTRADATA(node).icon) { UI_DrawSpriteInBox(EXTRADATA(node).flipIcon, EXTRADATA(node).icon, iconStatus, pos[0], pos[1], node->size[0], node->size[1]); } }
void uiTabNode::draw (uiNode_t *node) { ui_tabStatus_t lastStatus = UI_TAB_NOTHING; uiNode_t* option; uiNode_t* overMouseOption = NULL; const char *ref; const char *font; int currentX; int allowedWidth; vec2_t pos; const char* image = UI_GetReferenceString(node, node->image); if (!image) image = "ui/tab"; ref = UI_AbstractOptionGetCurrentValue(node); if (ref == NULL) return; font = UI_GetFontFromNode(node); if (node->state) { overMouseOption = UI_TabNodeTabAtPosition(node, mousePosX, mousePosY); } UI_GetNodeAbsPos(node, pos); currentX = pos[0]; option = node->firstChild; assert(option->behaviour == ui_optionBehaviour); /** @todo this dont work when an option is hidden */ allowedWidth = node->box.size[0] - TILE_WIDTH * (EXTRADATA(node).count + 1); while (option) { int fontHeight; int fontWidth; int tabWidth; int textPos; bool drawIcon = false; ui_tabStatus_t status = UI_TAB_NORMAL; assert(option->behaviour == ui_optionBehaviour); /* skip hidden options */ if (option->invis) { option = option->next; continue; } /* Check the status of the current tab */ if (Q_streq(OPTIONEXTRADATA(option).value, ref)) { status = UI_TAB_SELECTED; } else if (option->disabled || node->disabled) { status = UI_TAB_DISABLED; } else if (option == overMouseOption) { status = UI_TAB_HIGHLIGHTED; } /* Display */ UI_TabNodeDrawJunction(image, currentX, pos[1], lastStatus, status); currentX += TILE_WIDTH; const char *label = CL_Translate(OPTIONEXTRADATA(option).label); R_FontTextSize(font, label, 0, LONGLINES_PRETTYCHOP, &fontWidth, &fontHeight, NULL, NULL); tabWidth = fontWidth; if (OPTIONEXTRADATA(option).icon && OPTIONEXTRADATA(option).icon->size[0] < allowedWidth) { tabWidth += OPTIONEXTRADATA(option).icon->size[0]; drawIcon = true; } if (tabWidth > allowedWidth) { if (allowedWidth > 0) tabWidth = allowedWidth; else tabWidth = 0; } if (tabWidth > 0) { UI_TabNodeDrawPlain(image, currentX, pos[1], tabWidth, status); } textPos = currentX; if (drawIcon) { uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL; if (status == UI_TAB_DISABLED) { iconStatus = SPRITE_STATUS_DISABLED; } UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, OPTIONEXTRADATA(option).icon, iconStatus, currentX, pos[1], OPTIONEXTRADATA(option).icon->size[0], TILE_HEIGHT); textPos += OPTIONEXTRADATA(option).icon->size[0]; } /** @todo fontWidth can be =0, maybe a bug from the font cache */ OPTIONEXTRADATA(option).truncated = tabWidth < fontWidth || tabWidth == 0; UI_DrawString(font, ALIGN_UL, textPos, pos[1] + ((node->box.size[1] - fontHeight) / 2), textPos, tabWidth + 1, 0, label, 0, 0, NULL, false, LONGLINES_PRETTYCHOP); currentX += tabWidth; allowedWidth -= tabWidth; /* Next */ lastStatus = status; option = option->next; } /* Display last junction and end of header */ UI_TabNodeDrawJunction(image, currentX, pos[1], lastStatus, UI_TAB_NOTHING); currentX += TILE_WIDTH; if (currentX < pos[0] + node->box.size[0]) UI_TabNodeDrawPlain(image, currentX, pos[1], pos[0] + node->box.size[0] - currentX, UI_TAB_NOTHING); }
static void UI_OptionTreeNodeDraw (uiNode_t *node) { static const int panelTemplate[] = { CORNER_SIZE, MID_SIZE, CORNER_SIZE, CORNER_SIZE, MID_SIZE, CORNER_SIZE, MARGE }; uiNode_t* option; const char *ref; const char *font; vec2_t pos; const char* image; int fontHeight; int currentY; int currentDecY = 0; const float *textColor; vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0}; int count = 0; uiOptionIterator_t iterator; if (!systemExpand) systemExpand = UI_GetSpriteByName("icons/system_expand"); if (!systemCollapse) systemCollapse = UI_GetSpriteByName("icons/system_collapse"); ref = UI_AbstractOptionGetCurrentValue(node); if (ref == NULL) return; UI_GetNodeAbsPos(node, pos); image = UI_GetReferenceString(node, node->image); if (image) UI_DrawPanel(pos, node->size, image, 0, 0, panelTemplate); font = UI_GetFontFromNode(node); fontHeight = EXTRADATA(node).lineHeight; currentY = pos[1] + node->padding; if (fontHeight == 0) fontHeight = UI_FontGetHeight(font); else { const int height = UI_FontGetHeight(font); currentDecY = (fontHeight - height) / 2; } /* skip option over current position */ option = UI_OptionTreeNodeGetFirstOption(node); UI_OptionTreeNodeUpdateScroll(node); option = UI_InitOptionIteratorAtIndex(EXTRADATA(node).scrollY.viewPos, option, &iterator); /* draw all available options for this selectbox */ for (; option; option = UI_OptionIteratorNextOption(&iterator)) { int decX; const char *label; /* outside the node */ if (currentY + fontHeight > pos[1] + node->size[1] - node->padding) { count++; break; } /* draw the hover effect */ if (OPTIONEXTRADATA(option).hovered) UI_DrawFill(pos[0] + node->padding, currentY, node->size[0] - node->padding - node->padding, fontHeight, node->color); /* text color */ if (Q_streq(OPTIONEXTRADATA(option).value, ref)) { textColor = node->selectedColor; } else if (node->disabled || option->disabled) { textColor = disabledColor; } else if (option->color[3] == 0.0f) { textColor = node->color; } else { textColor = option->color; } /* print the option label */ decX = pos[0] + node->padding + iterator.depthPos * DEPTH_WIDTH; R_Color(NULL); if (option->firstChild) { uiSprite_t *icon = OPTIONEXTRADATA(option).collapsed ? systemExpand : systemCollapse; UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, icon, SPRITE_STATUS_NORMAL, decX, currentY, icon->size[0], fontHeight); } decX += COLLAPSEBUTTON_WIDTH; if (OPTIONEXTRADATA(option).icon) { uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL; if (option->disabled) iconStatus = SPRITE_STATUS_DISABLED; UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, OPTIONEXTRADATA(option).icon, iconStatus, decX, currentY, OPTIONEXTRADATA(option).icon->size[0], fontHeight); decX += OPTIONEXTRADATA(option).icon->size[0] + fontHeight / 4; } label = OPTIONEXTRADATA(option).label; if (label[0] == '_') label = _(label + 1); R_Color(textColor); UI_DrawString(font, ALIGN_UL, decX, currentY + currentDecY, pos[0], node->size[0] - node->padding - node->padding, 0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP); /* next entries' position */ currentY += fontHeight; count++; } R_Color(NULL); }
/** * @brief Call to draw the node */ static void UI_VScrollbarNodeDraw (uiNode_t *node) { vec2_t pos; int y = 0; int texX = 0; int texY = 0; const char *texture; const image_t *image; UI_GetNodeAbsPos(node, pos); y = pos[1]; texture = UI_GetReferenceString(node, node->image); if (!texture) return; image = UI_LoadImage(texture); if (EXTRADATA(node).fullsize == 0 || EXTRADATA(node).fullsize <= EXTRADATA(node).viewsize) { /* hide the scrollbar */ if (EXTRADATA(node).hideWhenUnused) return; texX = TILE_WIDTH * 3; /* top */ UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, ELEMENT_HEIGHT, texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); texY += TILE_HEIGHT; y += ELEMENT_HEIGHT; /* top to bottom */ UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, node->size[1] - (ELEMENT_HEIGHT * 2), texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); texY += TILE_HEIGHT * 5; y += node->size[1] - (ELEMENT_HEIGHT * 2); assert(y == pos[1] + node->size[1] - ELEMENT_HEIGHT); /* bottom */ UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, ELEMENT_HEIGHT, texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); } else { int houveredElement = -1; int description[5]; UI_VScrollbarNodeGetElementSize(node, description); if (UI_GetMouseCapture() == node) houveredElement = capturedElement; else if (node->state) houveredElement = UI_VScrollbarNodeGetElement(node, description, mousePosX, mousePosY); /* top */ texX = (houveredElement == 0)?TILE_WIDTH:0; UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, ELEMENT_HEIGHT, texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); texY += TILE_HEIGHT; y += ELEMENT_HEIGHT; /* top to slider */ if (description[1]) { texX = (houveredElement == 1)?TILE_WIDTH:0; UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, description[1], texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); y += description[1]; } texY += TILE_HEIGHT; /* slider */ texX = (houveredElement == 2)?TILE_WIDTH:0; /* top slider */ UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, ELEMENT_HEIGHT, texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); texY += TILE_HEIGHT; y += ELEMENT_HEIGHT; /* middle slider */ if (description[2]) { UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, description[2]-ELEMENT_HEIGHT-ELEMENT_HEIGHT, texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); y += description[2]-ELEMENT_HEIGHT-ELEMENT_HEIGHT; } texY += TILE_HEIGHT; /* bottom slider */ UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, ELEMENT_HEIGHT, texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); texY += TILE_HEIGHT; y += ELEMENT_HEIGHT; /* slider to bottom */ if (description[3]) { texX = (houveredElement == 3)?TILE_WIDTH:0; UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, description[3], texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); y += description[3]; } texY += TILE_HEIGHT; assert(y == pos[1] + node->size[1] - ELEMENT_HEIGHT); /* bottom */ texX = (houveredElement == 4)?TILE_WIDTH:0; UI_DrawNormImage(qfalse, pos[0], y, ELEMENT_WIDTH, ELEMENT_HEIGHT, texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image); } }
static void UI_TextEntryNodeDraw (uiNode_t *node) { static const int panelTemplate[] = { CORNER_SIZE, MID_SIZE, CORNER_SIZE, CORNER_SIZE, MID_SIZE, CORNER_SIZE, MARGE }; const char *text; int texX, texY; const float *textColor; const char *image; vec2_t pos; static vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0}; const char *font = UI_GetFontFromNode(node); if (node->disabled) { /** @todo need custom color when node is disabled */ textColor = disabledColor; texX = TILE_SIZE; texY = TILE_SIZE; } else if (node->state) { textColor = node->color; texX = TILE_SIZE; texY = 0; } else { textColor = node->color; texX = 0; texY = 0; } if (UI_HasFocus(node)) textColor = node->selectedColor; UI_GetNodeAbsPos(node, pos); image = UI_GetReferenceString(node, node->image); if (image) UI_DrawPanel(pos, node->size, image, texX, texY, panelTemplate); text = UI_GetReferenceString(node, node->text); if (text != NULL) { /** @todo we don't need to edit the text to draw the cursor */ if (UI_HasFocus(node)) { if (CL_Milliseconds() % 1000 < 500) { text = va("%s%c", text, CURSOR); } } if (EXTRADATA(node).isPassword) { char *c = va("%s", text); int size = UTF8_strlen(c); text = c; /* hide the text with a special char */ assert(strlen(c) >= size); /* trustable, but it can't be false */ while (size) { *c++ = HIDECHAR; size--; } /* readd the cursor */ if (UI_HasFocus(node)) { if (CL_Milliseconds() % 1000 < 500) { c--; *c++ = CURSOR; } } *c = '\0'; } if (*text != '\0') { R_Color(textColor); UI_DrawStringInBox(font, node->textalign, pos[0] + node->padding, pos[1] + node->padding, node->size[0] - node->padding - node->padding, node->size[1] - node->padding - node->padding, text, LONGLINES_PRETTYCHOP); R_Color(NULL); } } }
/** * @brief Draws the image node * @param[in] node The UI node to draw */ void uiImageNode::draw (uiNode_t* node) { vec2_t size; vec2_t nodepos; const image_t* image; vec2_t imagepos; vec2_t nodesize; const char* imageName = UI_GetReferenceString(node, node->image); if (Q_strnull(imageName)) return; image = UI_LoadImage(imageName); if (!image) return; /* mouse darken effect */ /** @todo convert all pic using mousefx into button. * @todo delete mousefx */ #if 0 if (node->mousefx && node->state) { vec4_t color; VectorScale(node->color, 0.8, color); color[3] = node->color[3]; R_Color(color); } #endif UI_GetNodeAbsPos(node, nodepos); Vector2Copy(node->box.size, nodesize); nodesize[0] -= node->padding + node->padding; if (nodesize[0] < 0) nodesize[0] = 0; nodesize[1] -= node->padding + node->padding; if (nodesize[1] < 0) nodesize[1] = 0; /** @todo code is duplicated in the ekg node code */ if (node->box.size[0] && !node->box.size[1]) { const float scale = image->width / node->box.size[0]; Vector2Set(size, node->box.size[0], image->height / scale); } else if (node->box.size[1] && !node->box.size[0]) { const float scale = image->height / node->box.size[1]; Vector2Set(size, image->width / scale, node->box.size[1]); } else { Vector2Copy(nodesize, size); if (EXTRADATA(node).preventRatio) { /* maximize the image into the bounding box */ const float ratio = (float) image->width / (float) image->height; if (size[1] * ratio > size[0]) { Vector2Set(size, size[0], size[0] / ratio); } else { Vector2Set(size, size[1] * ratio, size[1]); } } } UI_ImageAlignBoxInBox(nodepos, nodesize, size, (align_t) node->contentAlign, imagepos); UI_DrawNormImage(false, imagepos[0] + node->padding, imagepos[1] + node->padding, size[0], size[1], EXTRADATA(node).texh[0], EXTRADATA(node).texh[1], EXTRADATA(node).texl[0], EXTRADATA(node).texl[1], image); /** @todo convert all pic using mousefx into button. * @todo delete mousefx */ #if 0 if (node->mousefx && node->state) { R_Color(nullptr); } #endif }
static void UI_OptionListNodeDraw (uiNode_t *node) { static const int panelTemplate[] = { CORNER_SIZE, MID_SIZE, CORNER_SIZE, CORNER_SIZE, MID_SIZE, CORNER_SIZE, MARGE }; uiNode_t* option; const char *ref; const char *font; int lineHeight; vec2_t pos; const char* image; int currentY; const float *textColor; static vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0}; int count = 0; ref = UI_AbstractOptionGetCurrentValue(node); if (ref == NULL) return; UI_GetNodeAbsPos(node, pos); image = UI_GetReferenceString(node, node->image); if (image) UI_DrawPanel(pos, node->size, image, 0, 0, panelTemplate); font = UI_GetFontFromNode(node); lineHeight = EXTRADATA(node).lineHeight; if (lineHeight == 0) lineHeight = UI_FontGetHeight(font); currentY = pos[1] + node->padding; /* skip option over current position */ option = UI_AbstractOptionGetFirstOption(node); while (option && count < EXTRADATA(node).scrollY.viewPos) { option = option->next; count++; } /* draw all available options for this selectbox */ for (; option; option = option->next) { const char *label; int decX = pos[0] + node->padding; /* outside the node */ if (currentY + lineHeight > pos[1] + node->size[1] - node->padding) { count++; break; } /* draw the hover effect */ if (OPTIONEXTRADATA(option).hovered) UI_DrawFill(pos[0] + node->padding, currentY, node->size[0] - node->padding - node->padding, lineHeight, node->color); /* text color */ if (Q_streq(OPTIONEXTRADATA(option).value, ref)) { textColor = node->selectedColor; } else if (node->disabled || option->disabled) { textColor = disabledColor; } else if (option->color[3] == 0.0f) { textColor = node->color; } else { textColor = option->color; } if (OPTIONEXTRADATA(option).icon) { uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL; if (option->disabled) iconStatus = SPRITE_STATUS_DISABLED; R_Color(NULL); UI_DrawSpriteInBox(OPTIONEXTRADATA(option).flipIcon, OPTIONEXTRADATA(option).icon, iconStatus, decX, currentY, OPTIONEXTRADATA(option).icon->size[0], lineHeight); decX += OPTIONEXTRADATA(option).icon->size[0] + lineHeight / 4; } /* print the option label */ label = OPTIONEXTRADATA(option).label; if (label[0] == '_') label = _(label + 1); R_Color(textColor); UI_DrawString(font, ALIGN_UL, decX, currentY, pos[0], node->size[0] - node->padding - node->padding, 0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP); /* next entries' position */ currentY += lineHeight; count++; } R_Color(NULL); /* count number of options (current architecture doesn't allow to know if the data change) */ for (; option; option = option->next) { count++; } if (EXTRADATA(node).count != count) { EXTRADATA(node).count = count; } UI_OptionListNodeUpdateScroll(node); }
void uiEkgNode::draw (uiNode_t *node) { vec2_t size; vec2_t nodepos; const image_t *image; const char* imageName = UI_GetReferenceString(node, EXTRADATA(node).super.source); if (Q_strnull(imageName)) return; UI_GetNodeAbsPos(node, nodepos); image = UI_LoadWrappedImage(imageName); if (image) { const int ekgHeight = node->box.size[1]; const int ekgWidth = image->width; /* we have different ekg parts in each ekg image... */ const int ekgImageParts = image->height / node->box.size[1]; const int ekgMaxIndex = ekgImageParts - 1; /* we change the index of the image part in 20s steps */ /** @todo this magic number should be replaced with a sane calculation of the value */ const int ekgDivide = 20; /* If we are in the range of (ekgMaxValue + ekgDivide, ekgMaxValue) we are using the first image */ const int ekgMaxValue = ekgDivide * ekgMaxIndex; int ekgValue; float current; /** @todo these cvars should come from the script */ /* ekg_morale and ekg_hp are the node names */ if (node->name[0] == 'm') current = Cvar_GetValue("mn_morale") / EXTRADATA(node).scaleCvarValue; else current = Cvar_GetValue("mn_hp") / EXTRADATA(node).scaleCvarValue; ekgValue = std::min((int)current, ekgMaxValue); EXTRADATA(node).super.texl[1] = (ekgMaxIndex - (int)(ekgValue / ekgDivide)) * ekgHeight; EXTRADATA(node).super.texh[1] = EXTRADATA(node).super.texl[1] + ekgHeight; EXTRADATA(node).super.texl[0] = -(int) (EXTRADATA(node).scrollSpeed * CL_Milliseconds()) % ekgWidth; EXTRADATA(node).super.texh[0] = EXTRADATA(node).super.texl[0] + node->box.size[0]; /** @todo code is duplicated in the image node code */ if (node->box.size[0] && !node->box.size[1]) { const float scale = image->width / node->box.size[0]; Vector2Set(size, node->box.size[0], image->height / scale); } else if (node->box.size[1] && !node->box.size[0]) { const float scale = image->height / node->box.size[1]; Vector2Set(size, image->width / scale, node->box.size[1]); } else { if (EXTRADATA(node).super.preventRatio) { /* maximize the image into the bounding box */ const float ratio = (float) image->width / (float) image->height; if (node->box.size[1] * ratio > node->box.size[0]) { Vector2Set(size, node->box.size[0], node->box.size[0] / ratio); } else { Vector2Set(size, node->box.size[1] * ratio, node->box.size[1]); } } else { Vector2Copy(node->box.size, size); } } UI_DrawNormImage(false, nodepos[0], nodepos[1], size[0], size[1], EXTRADATA(node).super.texh[0], EXTRADATA(node).super.texh[1], EXTRADATA(node).super.texl[0], EXTRADATA(node).super.texl[1], image); } }
void uiSelectBoxNode::drawOverWindow (uiNode_t* node) { const char* ref = UI_AbstractOptionGetCurrentValue(node); if (ref == nullptr) return; vec2_t nodepos; UI_GetNodeAbsPos(node, nodepos); const char* imageName = UI_GetReferenceString(node, node->image); if (!imageName) imageName = "ui/selectbox"; const image_t* image = UI_LoadImage(imageName); const char* font = UI_GetFontFromNode(node); int selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH; int selBoxY = nodepos[1] + SELECTBOX_SPACER; selBoxY += node->box.size[1]; /* drop down list */ /* left side */ UI_DrawNormImage(false, nodepos[0], nodepos[1] + node->box.size[1], SELECTBOX_SIDE_WIDTH, node->box.size[1] * EXTRADATA(node).count, 7.0f, 28.0f, 0.0f, 21.0f, image); /* stretched middle bar */ UI_DrawNormImage(false, nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1] + node->box.size[1], node->box.size[0] -SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, node->box.size[1] * EXTRADATA(node).count, 16.0f, 28.0f, 7.0f, 21.0f, image); /* right side */ UI_DrawNormImage(false, nodepos[0] + node->box.size[0] -SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, nodepos[1] + node->box.size[1], SELECTBOX_SIDE_WIDTH, node->box.size[1] * EXTRADATA(node).count, 23.0f, 28.0f, 16.0f, 21.0f, image); /* now draw all available options for this selectbox */ int check = 0; for (uiNode_t* option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) { if (option->invis) continue; /* draw the hover effect */ if (OPTIONEXTRADATA(option).hovered) UI_DrawFill(selBoxX, selBoxY, node->box.size[0] -SELECTBOX_SIDE_WIDTH - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, SELECTBOX_DEFAULT_HEIGHT, node->color); /* print the option label */ const char* label = CL_Translate(OPTIONEXTRADATA(option).label); UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY, selBoxX, node->box.size[0] - 4, 0, label, 0, 0, nullptr, false, LONGLINES_PRETTYCHOP); /* next entries' position */ selBoxY += node->box.size[1]; check++; } /** detect inconsistency */ if (check != EXTRADATA(node).count) { /** force clean up cache */ Com_Printf("uiSelectBoxNode::drawOverWindow: Node '%s' contains unsynchronized option list. Fixed.\n", UI_GetPath(node)); EXTRADATA(node).versionId = 0; } /* left side */ UI_DrawNormImage(false, nodepos[0], selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 7.0f, 32.0f, 0.0f, 28.0f, image); /* stretched middle bar */ UI_DrawNormImage(false, nodepos[0] + SELECTBOX_SIDE_WIDTH, selBoxY - SELECTBOX_SPACER, node->box.size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 16.0f, 32.0f, 7.0f, 28.0f, image); /* right bottom side */ UI_DrawNormImage(false, nodepos[0] + node->box.size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 23.0f, 32.0f, 16.0f, 28.0f, image); }
static void UI_SelectBoxNodeDrawOverWindow (uiNode_t *node) { uiNode_t* option; int selBoxX, selBoxY; const char *ref; const char *font; vec2_t nodepos; const char* imageName; const image_t *image; ref = UI_AbstractOptionGetCurrentValue(node); if (ref == NULL) return; UI_GetNodeAbsPos(node, nodepos); imageName = UI_GetReferenceString(node, node->image); if (!imageName) imageName = "ui/selectbox"; image = UI_LoadImage(imageName); font = UI_GetFontFromNode(node); selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH; selBoxY = nodepos[1] + SELECTBOX_SPACER; selBoxY += node->size[1]; /* drop down list */ /* left side */ UI_DrawNormImage(nodepos[0], nodepos[1] + node->size[1], SELECTBOX_SIDE_WIDTH, node->size[1] * EXTRADATA(node).count, 7.0f, 28.0f, 0.0f, 21.0f, image); /* stretched middle bar */ UI_DrawNormImage(nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1] + node->size[1], node->size[0] -SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, node->size[1] * EXTRADATA(node).count, 16.0f, 28.0f, 7.0f, 21.0f, image); /* right side */ UI_DrawNormImage(nodepos[0] + node->size[0] -SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, nodepos[1] + node->size[1], SELECTBOX_SIDE_WIDTH, node->size[1] * EXTRADATA(node).count, 23.0f, 28.0f, 16.0f, 21.0f, image); /* now draw all available options for this selectbox */ for (option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) { const char *label; if (option->invis) continue; /* draw the hover effect */ if (OPTIONEXTRADATA(option).hovered) UI_DrawFill(selBoxX, selBoxY, node->size[0] -SELECTBOX_SIDE_WIDTH - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, SELECTBOX_DEFAULT_HEIGHT, node->color); /* print the option label */ label = OPTIONEXTRADATA(option).label; if (label[0] == '_') label = _(label + 1); UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY, selBoxX, node->size[0] - 4, 0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP); /* next entries' position */ selBoxY += node->size[1]; } /* left side */ UI_DrawNormImage(nodepos[0], selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 7.0f, 32.0f, 0.0f, 28.0f, image); /* stretched middle bar */ UI_DrawNormImage(nodepos[0] + SELECTBOX_SIDE_WIDTH, selBoxY - SELECTBOX_SPACER, node->size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 16.0f, 32.0f, 7.0f, 28.0f, image); /* right bottom side */ UI_DrawNormImage(nodepos[0] + node->size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 23.0f, 32.0f, 16.0f, 28.0f, image); }
static void UI_KeyBindingNodeDraw (uiNode_t *node) { static const int panelTemplate[] = { CORNER_SIZE, MID_SIZE, CORNER_SIZE, CORNER_SIZE, MID_SIZE, CORNER_SIZE, MARGE }; const char *binding, *description, *command; int texX, texY; const float *textColor; const char *image; vec2_t pos; const char *font = UI_GetFontFromNode(node); const int bindingWidth = EXTRADATA(node).bindingWidth; const int descriptionWidth = node->size[0] - bindingWidth; vec2_t descriptionPos, descriptionSize; vec2_t bindingPos, bindingSize; if (node->state) { textColor = node->color; texX = TILE_SIZE; texY = 0; } else { textColor = node->color; texX = 0; texY = 0; } if (UI_HasFocus(node)) textColor = node->selectedColor; UI_GetNodeAbsPos(node, pos); Vector2Set(descriptionSize, descriptionWidth, node->size[1]); Vector2Set(bindingSize, bindingWidth, node->size[1]); Vector2Set(descriptionPos, pos[0], pos[1]); Vector2Set(bindingPos, pos[0] + descriptionWidth + node->padding, pos[1]); image = UI_GetReferenceString(node, node->image); if (image) { UI_DrawPanel(descriptionPos, descriptionSize, image, texX, texY, panelTemplate); UI_DrawPanel(bindingPos, bindingSize, image, texX, texY, panelTemplate); } binding = UI_GetReferenceString(node, node->text); if (Q_strnull(binding)) binding = _("NONE"); /** @todo check that this is a keybinding value (with macro expansion) */ command = node->text + 9; description = Cmd_GetCommandDesc(command); if (description[0] == '\0') description = command; R_Color(textColor); UI_DrawStringInBox(font, node->contentAlign, descriptionPos[0] + node->padding, descriptionPos[1] + node->padding, descriptionSize[0] - node->padding - node->padding, descriptionSize[1] - node->padding - node->padding, description, LONGLINES_PRETTYCHOP); UI_DrawStringInBox(font, node->contentAlign, bindingPos[0] + node->padding, bindingPos[1] + node->padding, bindingSize[0] - node->padding - node->padding, bindingSize[1] - node->padding - node->padding, binding, LONGLINES_PRETTYCHOP); R_Color(NULL); }