/** * @brief Update the scrollable view */ static void UI_MaterialEditorNodeUpdateView (uiNode_t *node, qboolean reset) { const int imageCount = UI_MaterialEditorNodeGetImageCount(node); const int imagesPerLine = (node->size[0] - node->padding) / (IMAGE_WIDTH + node->padding); const int imagesPerColumn = (node->size[1] - node->padding) / (IMAGE_WIDTH + node->padding); /* update view */ if (imagesPerLine > 0 && imagesPerColumn > 0) { const int pos = reset ? 0 : -1; UI_AbstractScrollableNodeSetY(node, pos, imagesPerColumn, imageCount / imagesPerLine); } else UI_AbstractScrollableNodeSetY(node, 0, 0, 0); }
/** * @brief Scroll the Y scroll with a relative position, and call event if need * @return True, if something have change */ qboolean UI_AbstractScrollableNodeScrollY (uiNode_t *node, int offset) { assert(UI_NodeInstanceOf(node, "abstractscrollable")); return UI_AbstractScrollableNodeSetY(node, EXTRADATA(node).scrollY.viewPos + offset, -1, -1); }
/** * @note fullSize is bigger than the "end" position. But the function will clamp it right */ static void UI_AbstractScrollableNodeMoveEnd (uiNode_t *node, const uiCallContext_t *context) { UI_AbstractScrollableNodeSetY(node, EXTRADATA(node).scrollY.fullSize, -1, -1); }
static void UI_AbstractScrollableNodeMoveHome (uiNode_t *node, const uiCallContext_t *context) { UI_AbstractScrollableNodeSetY(node, 0, -1, -1); }
static void UI_AbstractScrollableNodeMoveDown (uiNode_t *node, const uiCallContext_t *context) { UI_AbstractScrollableNodeSetY(node, EXTRADATA(node).scrollY.viewPos + 1, -1, -1); }
/** * @note pos == -1 is a reserved value, that why we clamp the value */ static void UI_AbstractScrollableNodePageUp (uiNode_t *node, const uiCallContext_t *context) { const int pos = EXTRADATA(node).scrollY.viewPos - 10; UI_AbstractScrollableNodeSetY(node, (pos >= 0)?pos:0, -1, -1); }
/** * @brief Handles line breaks and drawing for shared data text * @param[in] node The context node * @param[in] list The text list to draw */ static void UI_TextLineNodeDrawText (uiNode_t* node, const linkedList_t* list) { vec4_t colorHover; vec4_t colorSelectedHover; int count; /* variable x position */ const char *font = UI_GetFontFromNode(node); vec2_t pos; int currentY; int viewSizeY; int lineHeight; int maxHeight; lineHeight = EXTRADATA(node).lineHeight; if (lineHeight == 0) lineHeight = UI_FontGetHeight(font); if (UI_AbstractScrollableNodeIsSizeChange(node)) viewSizeY = node->size[1] / lineHeight; else viewSizeY = EXTRADATA(node).super.scrollY.viewSize; /* text box */ UI_GetNodeAbsPos(node, pos); pos[0] += node->padding; pos[1] += node->padding; /* prepare colors */ VectorScale(node->color, 0.8, colorHover); colorHover[3] = node->color[3]; VectorScale(node->selectedColor, 0.8, colorSelectedHover); colorSelectedHover[3] = node->selectedColor[3]; /* skip lines over the scroll */ count = 0; while (list && count < EXTRADATA(node).super.scrollY.viewPos) { list = list->next; count++; } currentY = pos[1]; maxHeight = currentY + node->size[1] - node->padding - node->padding - node->padding - lineHeight; while (list) { const int width = node->size[0] - node->padding - node->padding; const char* text = (const char*) list->data; if (currentY > maxHeight) break; /* highlight selected line */ if (count == EXTRADATA(node).textLineSelected && EXTRADATA(node).textLineSelected >= 0) R_Color(node->selectedColor); else R_Color(node->color); /* highlight line under mouse */ if (node->state && count == EXTRADATA(node).lineUnderMouse) { if (count == EXTRADATA(node).textLineSelected && EXTRADATA(node).textLineSelected >= 0) R_Color(colorSelectedHover); else R_Color(colorHover); } UI_DrawStringInBox(font, node->contentAlign, pos[0], currentY, width, lineHeight, text, LONGLINES_PRETTYCHOP); /* next entries' position */ currentY += lineHeight; list = list->next; count++; } /* count all elements */ while (list) { list = list->next; count++; } /* update scroll status */ UI_AbstractScrollableNodeSetY(node, -1, viewSizeY, count); R_Color(NULL); }