/** * @brief Called by the client when the user type a key * @param[in] key key code, either K_ value or lowercase ascii * @param[in] unicode translated meaning of keypress in unicode * @return true, if we used the event * @todo think about what we should do when the mouse is captured */ bool UI_KeyPressed (unsigned int key, unsigned short unicode) { int windowId; int lastWindowId; if (UI_DNDIsDragging()) { if (key == K_ESCAPE) UI_DNDAbort(); return false; } if (key == K_ESCAPE && CL_BattlescapeRunning() && selActor && CL_ActorFireModeActivated(selActor->actorMode)) { /* Cancel firing with Escape, needed for Android, where right mouse click is bound to multitouch, which is non-obvious */ CL_ActorSetMode(selActor, M_MOVE); return true; } /* translate event into the node with focus */ if (focusNode && UI_Node_KeyPressed(focusNode, key, unicode)) { return true; } /* else use common behaviour */ switch (key) { case K_TAB: if (UI_FocusNextActionNode()) return true; break; case K_ENTER: case K_KP_ENTER: if (UI_FocusExecuteActionNode()) return true; break; case K_ESCAPE: if (UI_GetMouseCapture() != nullptr) { UI_MouseRelease(); return true; } UI_PopWindowWithEscKey(); return true; } lastWindowId = UI_GetLastFullScreenWindow(); if (lastWindowId < 0) return false; /* check "active" window from top to down */ for (windowId = ui_global.windowStackPos - 1; windowId >= lastWindowId; windowId--) { const uiNode_t* window = ui_global.windowStack[windowId]; if (!window) return false; if (UI_KeyPressedInWindow(key, window)) return true; if (UI_WindowIsModal(window)) break; } return false; }
/** * @brief Set the focus to the next action node * @note Action nodes are nodes with click defined * @sa Key_Event * @sa UI_FocusExecuteActionNode */ static bool UI_FocusNextActionNode (void) { #if 0 /**< @todo need a cleanup */ static int i = UI_MAX_WINDOWSTACK + 1; /* to cycle between all windows */ if (IN_GetMouseSpace() != MS_UI) return false; if (UI_GetMouseCapture()) return false; if (i >= ui_global.windowStackPos) i = UI_GetLastFullScreenWindow(); assert(i >= 0); if (focusNode) { uiNode_t* node = UI_GetNextActionNode(focusNode); if (node) return UI_FocusSetNode(node); } while (i < ui_global.windowStackPos) { uiNode_t* window; window = ui_global.windowStack[i++]; if (UI_FocusSetNode(UI_GetNextActionNode(window->firstChild))) return true; } i = UI_GetLastFullScreenWindow(); /* no node to focus */ UI_RemoveFocus(); #endif return false; }
void uiEditorNode::drawOverWindow (uiNode_t* node) { uiNode_t* hovered = nullptr; if (UI_GetMouseCapture() != node) { if (anchoredNode) UI_EditorNodeHighlightNode(anchoredNode, red, false); return; } if (dragStatus == ZONE_NONE) { #if 0 /* it does nothing, remember why we need that... */ if (anchoredNode) UI_EditorNodeGetElementAtPosition(anchoredNode, mousePosX, mousePosY); #endif hovered = UI_GetNodeAtPosition(mousePosX, mousePosY); /* do not edit node from editor window */ if (hovered && hovered->root == node->root) hovered = nullptr; } if (hovered && hovered != anchoredNode) UI_EditorNodeHighlightNode(hovered, grey, true); if (anchoredNode) UI_EditorNodeHighlightNode(anchoredNode, red, true); }
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); } }
void uiEditorNode::onMouseUp (uiNode_t* node, int x, int y, int button) { if (UI_GetMouseCapture() != node) return; if (button != K_MOUSE1) return; dragStatus = ZONE_NONE; }
void uiModelNode::onMouseUp (uiNode_t* node, int x, int y, int button) { if (button != K_MOUSE1) return; if (UI_GetMouseCapture() != node) return; UI_MouseRelease(); }
/** * @brief Track mouse down/up events to implement drag&drop-like scrolling, for touchscreen devices * @sa UI_OptionListNodeMouseUp, UI_OptionListNodeCapturedMouseMove */ void uiOptionListNode::onMouseDown (uiNode_t* node, int x, int y, int button) { if (!UI_GetMouseCapture() && button == K_MOUSE1 && EXTRADATA(node).scrollY.fullSize > EXTRADATA(node).scrollY.viewSize) { UI_SetMouseCapture(node); mouseScrollX = x; mouseScrollY = y; } }
/** * @brief Track mouse down/up events to implement drag&drop-like scrolling, for touchscreen devices * @sa UI_OptionListNodeMouseUp, UI_OptionListNodeCapturedMouseMove */ static void UI_OptionListNodeMouseDown (struct uiNode_s *node, int x, int y, int button) { if (!UI_GetMouseCapture() && button == K_MOUSE1 && EXTRADATA(node).scrollY.fullSize > EXTRADATA(node).scrollY.viewSize) { UI_SetMouseCapture(node); mouseScrollX = x; mouseScrollY = y; } }
void uiBaseInventoryNode::onMouseUp (uiNode_t* node, int x, int y, int button) { if (button != K_MOUSE1) return; if (UI_GetMouseCapture() == node) { UI_MouseRelease(); } if (UI_DNDIsDragging()) { UI_DNDDrop(); } }
static void UI_VScrollbarNodeMouseUp (uiNode_t *node, int x, int y, int button) { if (EXTRADATA(node).fullsize == 0 || EXTRADATA(node).fullsize < EXTRADATA(node).viewsize) return; if (button != K_MOUSE1) return; if (UI_GetMouseCapture() == node) { UI_MouseRelease(); } }
/** * @brief Called by the client when the user type a key * @param[in] key key code, either K_ value or lowercase ascii * @param[in] unicode translated meaning of keypress in unicode * @return true, if we used the event * @todo think about what we should do when the mouse is captured */ bool UI_KeyPressed (unsigned int key, unsigned short unicode) { int windowId; int lastWindowId; if (UI_DNDIsDragging()) { if (key == K_ESCAPE) UI_DNDAbort(); return false; } /* translate event into the node with focus */ if (focusNode && UI_Node_KeyPressed(focusNode, key, unicode)) { return true; } /* else use common behaviour */ switch (key) { case K_TAB: if (UI_FocusNextActionNode()) return true; break; case K_ENTER: case K_KP_ENTER: if (UI_FocusExecuteActionNode()) return true; break; case K_ESCAPE: if (UI_GetMouseCapture() != NULL) { UI_MouseRelease(); return true; } UI_PopWindowWithEscKey(); return true; } lastWindowId = UI_GetLastFullScreenWindow(); if (lastWindowId < 0) return false; /* check "active" window from top to down */ for (windowId = ui_global.windowStackPos - 1; windowId >= lastWindowId; windowId--) { const uiNode_t *window = ui_global.windowStack[windowId]; if (!window) return false; if (UI_KeyPressedInWindow(key, window)) return true; if (UI_WindowIsModal(window)) break; } return false; }
/** * @brief Handles selectboxes clicks */ static void UI_SelectBoxNodeClick (uiNode_t *node, int x, int y) { uiNode_t* option; int clickedAtOption; vec2_t pos; /* dropdown the node */ if (UI_GetMouseCapture() == NULL) { UI_SetMouseCapture(node); return; } UI_GetNodeAbsPos(node, pos); clickedAtOption = (y - pos[1]); /* we click outside */ if (x < pos[0] || y < pos[1] || x >= pos[0] + node->size[0] || y >= pos[1] + node->size[1] * (EXTRADATA(node).count + 1)) { UI_MouseRelease(); return; } /* we click on the head */ if (clickedAtOption < node->size[1]) { UI_MouseRelease(); return; } clickedAtOption = (clickedAtOption - node->size[1]) / node->size[1]; if (clickedAtOption < 0 || clickedAtOption >= EXTRADATA(node).count) return; if (UI_AbstractOptionGetCurrentValue(node) == NULL) return; /* select the right option */ option = UI_AbstractOptionGetFirstOption(node); for (; option; option = option->next) { if (option->invis) continue; if (clickedAtOption == 0) break; clickedAtOption--; } /* update the status */ if (option) UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value); /* close the dropdown */ UI_MouseRelease(); }
/** * @sa UI_FocusExecuteActionNode * @sa UI_FocusNextActionNode * @sa IN_Frame * @sa Key_Event */ void UI_RemoveFocus (void) { uiNode_t* tmp; if (UI_GetMouseCapture()) return; if (!focusNode) return; /* invalidate the data before calling the event */ tmp = focusNode; focusNode = nullptr; /* callback the lost of the focus */ UI_Node_FocusLost(tmp); }
/** * @brief Execute the current focused action node * @note Action nodes are nodes with click defined * @sa Key_Event * @sa UI_FocusNextActionNode */ static bool UI_FocusExecuteActionNode (void) { #if 0 /**< @todo need a cleanup */ if (IN_GetMouseSpace() != MS_UI) return false; if (UI_GetMouseCapture()) return false; if (focusNode) { if (focusNode->onClick) { UI_ExecuteEventActions(focusNode, focusNode->onClick); } UI_ExecuteEventActions(focusNode, focusNode->onMouseLeave); focusNode = nullptr; return true; } #endif return false; }
void uiEditorNode::onMouseDown (uiNode_t* node, int x, int y, int button) { uiNode_t* hovered; if (UI_GetMouseCapture() != node) return; if (button != K_MOUSE1) return; hovered = UI_GetNodeAtPosition(mousePosX, mousePosY); /* stop the capture */ if (hovered && hovered->root == node->root) { UI_MouseRelease(); return; } if (hovered == anchoredNode) hovered = nullptr; if (anchoredNode) { dragStatus = UI_EditorNodeGetElementAtPosition(anchoredNode, x, y); if (dragStatus == ZONE_BODY) { if (hovered == nullptr) { startX = x; startY = y; return; } } else if (dragStatus != ZONE_NONE) { startX = x; startY = y; return; } } /* select the node */ UI_EditorNodeSelectNode(node, hovered); }
/** * @brief Check if a point is over a window from the stack * @sa IN_Parse */ bool UI_IsMouseOnWindow (void) { const uiNode_t *hovered; if (UI_GetMouseCapture() != NULL) return true; if (ui_global.windowStackPos != 0) { if (WINDOWEXTRADATA(ui_global.windowStack[ui_global.windowStackPos - 1]).dropdown) return true; } hovered = UI_GetHoveredNode(); if (hovered) { /* else if it is a render node */ if (UI_Node_IsBattleScape(hovered)) { return false; } return true; } return true; }
/** * @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_OptionListNodeMouseUp (struct uiNode_s *node, int x, int y, int button) { if (UI_GetMouseCapture() == node) /* More checks can never hurt */ UI_MouseRelease(); }
void uiOptionListNode::onMouseUp (uiNode_t* node, int x, int y, int button) { if (UI_GetMouseCapture() == node) /* More checks can never hurt */ UI_MouseRelease(); }
void uiSpinnerNode::onMouseUp (uiNode_t *node, int x, int y, int button) { if (button == K_MOUSE1 && UI_GetMouseCapture() == node) { UI_MouseRelease(); } }