00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "ui_main.h"
00026 #include "ui_nodes.h"
00027 #include "ui_internal.h"
00028 #include "ui_draw.h"
00029 #include "ui_actions.h"
00030 #include "ui_input.h"
00031 #include "ui_timer.h"
00032 #include "ui_dragndrop.h"
00033 #include "ui_tooltip.h"
00034 #include "ui_render.h"
00035 #include "node/ui_node_abstractnode.h"
00036
00037 #include "../client.h"
00038 #include "../renderer/r_draw.h"
00039 #include "../renderer/r_misc.h"
00040
00041 static cvar_t *mn_show_tooltips;
00042 static const int TOOLTIP_DELAY = 500;
00043 static qboolean tooltipVisible = qfalse;
00044 static uiTimer_t *tooltipTimer;
00045
00046 static int noticeTime;
00047 static char noticeText[256];
00048 static uiNode_t *noticeWindow;
00049
00055 static uiNode_t *drawOverNode;
00056
00062 void UI_CaptureDrawOver (uiNode_t *node)
00063 {
00064 drawOverNode = node;
00065 }
00066
00067 #ifdef DEBUG
00068
00069 static int debugTextPositionY = 0;
00070 static int debugPositionX = 0;
00071 #define DEBUG_PANEL_WIDTH 300
00072
00073 static void UI_HighlightNode (const uiNode_t *node, const vec4_t color)
00074 {
00075 static const vec4_t grey = {0.7, 0.7, 0.7, 1.0};
00076 vec2_t pos;
00077 int width;
00078 int lineDefinition[4];
00079 const char* text;
00080
00081 if (node->parent)
00082 UI_HighlightNode(node->parent, grey);
00083
00084 UI_GetNodeAbsPos(node, pos);
00085
00086 text = va("%s (%s)", node->name, node->behaviour->name);
00087 R_FontTextSize("f_small_bold", text, DEBUG_PANEL_WIDTH, LONGLINES_PRETTYCHOP, &width, NULL, NULL, NULL);
00088
00089 R_Color(color);
00090 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX + 20, debugTextPositionY, debugPositionX + 20, DEBUG_PANEL_WIDTH, 0, text, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00091 debugTextPositionY += 15;
00092
00093 if (debugPositionX != 0) {
00094 lineDefinition[0] = debugPositionX + 20;
00095 lineDefinition[2] = pos[0] + node->size[0];
00096 } else {
00097 lineDefinition[0] = debugPositionX + 20 + width;
00098 lineDefinition[2] = pos[0];
00099 }
00100 lineDefinition[1] = debugTextPositionY - 5;
00101 lineDefinition[3] = pos[1];
00102 R_DrawLine(lineDefinition, 1);
00103 R_Color(NULL);
00104
00105
00106 if (node->excludeRectNum) {
00107 int i;
00108 vec4_t trans = {1, 1, 1, 1};
00109 Vector4Copy(color, trans);
00110 trans[3] = trans[3] / 2;
00111 for (i = 0; i < node->excludeRectNum; i++) {
00112 const int x = pos[0] + node->excludeRect[i].pos[0];
00113 const int y = pos[1] + node->excludeRect[i].pos[1];
00114 UI_DrawFill(x, y, node->excludeRect[i].size[0], node->excludeRect[i].size[1], trans);
00115 }
00116 }
00117
00118
00119 R_DrawRect(pos[0] - 1, pos[1] - 1, node->size[0] + 2, node->size[1] + 2, color, 2.0, 0x3333);
00120 }
00121
00125 static void UI_DrawDebugNodeNames (void)
00126 {
00127 static const vec4_t red = {1.0, 0.0, 0.0, 1.0};
00128 static const vec4_t green = {0.0, 0.5, 0.0, 1.0};
00129 static const vec4_t white = {1, 1.0, 1.0, 1.0};
00130 static const vec4_t background = {0.0, 0.0, 0.0, 0.5};
00131 uiNode_t *hoveredNode;
00132 int stackPosition;
00133
00134 debugTextPositionY = 100;
00135
00136
00137 if (mousePosX < viddef.virtualWidth / 3)
00138 debugPositionX = viddef.virtualWidth - DEBUG_PANEL_WIDTH;
00139 if (mousePosX > 2 * viddef.virtualWidth / 3)
00140 debugPositionX = 0;
00141
00142
00143 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, va("Mouse X: %i Y: %i", mousePosX, mousePosY), 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00144 debugTextPositionY += 15;
00145
00146 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "main active window:", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00147 debugTextPositionY += 15;
00148 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX+20, debugTextPositionY, debugPositionX + 20, 200, 0, Cvar_GetString("mn_sys_active"), 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00149 debugTextPositionY += 15;
00150 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "main option window:", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00151 debugTextPositionY += 15;
00152 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX+20, debugTextPositionY, debugPositionX + 20, 200, 0, Cvar_GetString("mn_sys_main"), 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00153 debugTextPositionY += 15;
00154 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "-----------------------", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00155 debugTextPositionY += 15;
00156
00157
00158 UI_DrawFill(debugPositionX, debugTextPositionY, DEBUG_PANEL_WIDTH, VID_NORM_HEIGHT - debugTextPositionY - 100, background);
00159
00160
00161 R_Color(white);
00162 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "window stack:", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00163 debugTextPositionY += 15;
00164 for (stackPosition = 0; stackPosition < ui_global.windowStackPos; stackPosition++) {
00165 uiNode_t *window = ui_global.windowStack[stackPosition];
00166 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX+20, debugTextPositionY, debugPositionX + 20, 200, 0, window->name, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00167 debugTextPositionY += 15;
00168 }
00169
00170
00171 hoveredNode = UI_GetHoveredNode();
00172 if (hoveredNode) {
00173 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "-----------------------", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00174 debugTextPositionY += 15;
00175
00176 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "hovered node:", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00177 debugTextPositionY += 15;
00178 UI_HighlightNode(hoveredNode, red);
00179 R_Color(white);
00180 }
00181
00182
00183 if (UI_DNDIsDragging()) {
00184 uiNode_t *targetNode = UI_DNDGetTargetNode();
00185 if (targetNode) {
00186 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "-----------------------", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00187 debugTextPositionY += 15;
00188
00189 R_Color(green);
00190 UI_DrawString("f_small_bold", ALIGN_UL, debugPositionX, debugTextPositionY, debugPositionX, 200, 0, "drag and drop target node:", 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00191 debugTextPositionY += 15;
00192 UI_HighlightNode(targetNode, green);
00193 }
00194 }
00195 R_Color(NULL);
00196 }
00197 #endif
00198
00199
00200 static void UI_CheckTooltipDelay (uiNode_t *node, uiTimer_t *timer)
00201 {
00202 tooltipVisible = qtrue;
00203 UI_TimerStop(timer);
00204 }
00205
00206 static void UI_DrawNode (uiNode_t *node)
00207 {
00208 static int globalTransX = 0;
00209 static int globalTransY = 0;
00210 uiNode_t *child;
00211 vec2_t pos;
00212
00213
00214 UI_Validate(node);
00215
00216
00217 if (node->invis || node->behaviour->isVirtual)
00218 return;
00219
00220 if (!UI_CheckVisibility(node))
00221 return;
00222
00223 UI_GetNodeAbsPos(node, pos);
00224
00228
00229 if (node->size[0] && node->size[1]) {
00230 if (node->bgcolor[3] != 0)
00231 UI_DrawFill(pos[0], pos[1], node->size[0], node->size[1], node->bgcolor);
00232
00233 if (node->border && node->bordercolor[3] != 0) {
00234 R_DrawRect(pos[0], pos[1], node->size[0], node->size[1],
00235 node->bordercolor, node->border, 0xFFFF);
00236 }
00237 }
00238
00239
00240 if (node->behaviour->draw) {
00241 node->behaviour->draw(node);
00242 }
00243
00244
00245 if (!node->behaviour->drawItselfChild && node->firstChild) {
00246 qboolean hasClient = qfalse;
00247 vec2_t clientPosition;
00248 if (node->behaviour->getClientPosition) {
00249 node->behaviour->getClientPosition(node, clientPosition);
00250 hasClient = qtrue;
00251 }
00252
00253 R_PushClipRect(pos[0] + globalTransX, pos[1] + globalTransY, node->size[0], node->size[1]);
00254
00256 if (hasClient) {
00257 vec3_t trans;
00258 globalTransX += clientPosition[0];
00259 globalTransY += clientPosition[1];
00260 trans[0] = clientPosition[0];
00261 trans[1] = clientPosition[1];
00262 trans[2] = 0;
00263 R_Transform(trans, NULL, NULL);
00264 }
00265
00266 for (child = node->firstChild; child; child = child->next)
00267 UI_DrawNode(child);
00268
00270 if (hasClient) {
00271 vec3_t trans;
00272 globalTransX -= clientPosition[0];
00273 globalTransY -= clientPosition[1];
00274 trans[0] = -clientPosition[0];
00275 trans[1] = -clientPosition[1];
00276 trans[2] = 0;
00277 R_Transform(trans, NULL, NULL);
00278 }
00279
00280 R_PopClipRect();
00281 }
00282 }
00283
00288 static void UI_DrawNotice (void)
00289 {
00290 const vec4_t noticeBG = { 1.0f, 0.0f, 0.0f, 0.2f };
00291 const vec4_t noticeColor = { 1.0f, 1.0f, 1.0f, 1.0f };
00292 int height = 0, width = 0;
00293 const int maxWidth = 500;
00294 const char *font = "f_normal";
00295 int lines = 5;
00296 int dx;
00297 int x, y;
00298 vec_t *noticePosition;
00299
00300 noticePosition = UI_WindowNodeGetNoticePosition(noticeWindow);
00301 if (noticePosition) {
00302 x = noticePosition[0];
00303 y = noticePosition[1];
00304 } else {
00305 x = VID_NORM_WIDTH / 2;
00306 y = 110;
00307 }
00308
00309
00310 x += noticeWindow->pos[0];
00311 y += noticeWindow->pos[1];
00312
00313 R_FontTextSize(font, noticeText, maxWidth, LONGLINES_WRAP, &width, &height, NULL, NULL);
00314
00315 if (!width)
00316 return;
00317
00318 if (x + width + 3 > viddef.virtualWidth)
00319 dx = -(width + 10);
00320 else
00321 dx = 0;
00322
00323 UI_DrawFill((x - 2 + dx) - ((width + 2) / 2), (y - 2) - ((height + 2) / 2), width + 4, height + 4, noticeBG);
00324 R_Color(noticeColor);
00325 UI_DrawString(font, ALIGN_CC, x + 1 + dx, y + 1, x + 1, maxWidth, 0, noticeText, lines, 0, NULL, qfalse, LONGLINES_WRAP);
00326 R_Color(NULL);
00327 }
00328
00333 void UI_Draw (void)
00334 {
00335 uiNode_t *hoveredNode;
00336 int pos;
00337 qboolean mouseMoved = qfalse;
00338
00339 UI_HandleTimers();
00340
00341 assert(ui_global.windowStackPos >= 0);
00342
00343 mouseMoved = UI_CheckMouseMove();
00344 hoveredNode = UI_GetHoveredNode();
00345
00346
00347 if (mouseMoved && tooltipVisible) {
00348 UI_TimerStop(tooltipTimer);
00349 tooltipVisible = qfalse;
00350 } else if (!tooltipVisible && !mouseMoved && !tooltipTimer->isRunning && mn_show_tooltips->integer && hoveredNode) {
00351 UI_TimerStart(tooltipTimer);
00352 }
00353
00354
00355 pos = UI_GetLastFullScreenWindow();
00356 if (pos < 0)
00357 return;
00358
00359
00360 for (; pos < ui_global.windowStackPos; pos++) {
00361 uiNode_t *window;
00362 window = ui_global.windowStack[pos];
00363
00364 drawOverNode = NULL;
00365
00366 UI_DrawNode(window);
00367
00368
00369 if (drawOverNode && drawOverNode->behaviour->drawOverWindow) {
00370 drawOverNode->behaviour->drawOverWindow(drawOverNode);
00371 }
00372 }
00373
00374
00375 if (noticeWindow != NULL && CL_Milliseconds() < noticeTime)
00376 UI_DrawNotice();
00377
00378
00379 if (noticeWindow != NULL && CL_Milliseconds() >= noticeTime)
00380 noticeWindow = NULL;
00381
00382
00383 if (hoveredNode && tooltipVisible && !UI_DNDIsDragging()) {
00384 if (hoveredNode->behaviour->drawTooltip) {
00385 hoveredNode->behaviour->drawTooltip(hoveredNode, mousePosX, mousePosY);
00386 } else {
00387 UI_Tooltip(hoveredNode, mousePosX, mousePosY);
00388 }
00389 }
00390
00391 #ifdef DEBUG
00392
00393 if (UI_DebugMode() >= 1) {
00394 UI_DrawDebugNodeNames();
00395 }
00396 #endif
00397 }
00398
00399 void UI_DrawCursor (void)
00400 {
00401 UI_DrawDragAndDrop(mousePosX, mousePosY);
00402 }
00403
00411 void UI_DisplayNotice (const char *text, int time, const char* windowName)
00412 {
00413 noticeTime = CL_Milliseconds() + time;
00414 Q_strncpyz(noticeText, text, sizeof(noticeText));
00415
00416 if (windowName == NULL) {
00417 noticeWindow = UI_GetActiveWindow();
00418 if (noticeWindow == NULL)
00419 Com_Printf("UI_DisplayNotice: No active window\n");
00420 } else {
00421 noticeWindow = UI_GetWindow(windowName);
00422 if (noticeWindow == NULL)
00423 Com_Printf("UI_DisplayNotice: '%s' not found\n", windowName);
00424 }
00425 }
00426
00427 void UI_InitDraw (void)
00428 {
00429 mn_show_tooltips = Cvar_Get("mn_show_tooltips", "1", CVAR_ARCHIVE, "Show tooltips in the UI");
00430 tooltipTimer = UI_AllocTimer(NULL, TOOLTIP_DELAY, UI_CheckTooltipDelay);
00431 }