00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "../ui_main.h"
00029 #include "../ui_parse.h"
00030 #include "../ui_draw.h"
00031 #include "../ui_input.h"
00032 #include "../ui_nodes.h"
00033 #include "../ui_windows.h"
00034 #include "../ui_render.h"
00035 #include "../ui_actions.h"
00036 #include "ui_node_editor.h"
00037 #include "ui_node_abstractnode.h"
00038
00039 #include "../../input/cl_keys.h"
00040 #include "../../input/cl_input.h"
00041 #include "../../renderer/r_draw.h"
00042
00043 typedef enum {
00044 ZONE_NONE = -1,
00045 ZONE_TOPRIGHT_CORNER,
00046 ZONE_TOPLEFT_CORNER,
00047 ZONE_BOTTOMRIGHT_CORNER,
00048 ZONE_BOTTOMLEFT_CORNER,
00049 ZONE_BODY
00050 } zoneNode_t;
00051
00052
00053 static uiNode_t* anchoredNode = NULL;
00054 static const vec4_t red = {1.0, 0.0, 0.0, 1.0};
00055 static const vec4_t grey = {0.8, 0.8, 0.8, 1.0};
00056 static const int anchorSize = 10;
00057 static zoneNode_t dragStatus = ZONE_NONE;
00058 static int startX;
00059 static int startY;
00060
00061 static void UI_EditorNodeHighlightNode (uiNode_t *node, const vec4_t color, qboolean displayAnchor)
00062 {
00063 vec2_t pos;
00064 UI_GetNodeAbsPos(node, pos);
00065
00066 R_DrawRect(pos[0] - 1, pos[1] - 1, node->size[0] + 2, node->size[1] + 2, color, 1.0, 0x3333);
00067
00068 if (displayAnchor) {
00069 UI_DrawFill(pos[0] - anchorSize, pos[1] - anchorSize, anchorSize, anchorSize, color);
00070 UI_DrawFill(pos[0] - anchorSize, pos[1] + node->size[1], anchorSize, anchorSize, color);
00071 UI_DrawFill(pos[0] + node->size[0], pos[1] + node->size[1], anchorSize, anchorSize, color);
00072 UI_DrawFill(pos[0] + node->size[0], pos[1] - anchorSize, anchorSize, anchorSize, color);
00073 }
00074 }
00075
00076 static zoneNode_t UI_EditorNodeGetElementAtPosition (uiNode_t *node, int x, int y)
00077 {
00078 UI_NodeAbsoluteToRelativePos(anchoredNode, &x, &y);
00079
00080 if (x > 0 && x < node->size[0] && y > 0 && y < node->size[1]) {
00081 return ZONE_BODY;
00082 }
00083
00084 if (y > -anchorSize && y < 0) {
00085 if (x > -anchorSize && x < 0) {
00086 return ZONE_TOPLEFT_CORNER;
00087 } else if (x > node->size[0] && x < node->size[0] + anchorSize) {
00088 return ZONE_TOPRIGHT_CORNER;
00089 }
00090 } else if (y > node->size[1] && y < node->size[1] + anchorSize) {
00091 if (x > -anchorSize && x < 0) {
00092 return ZONE_BOTTOMLEFT_CORNER;
00093 } else if (x > node->size[0] && x < node->size[0] + anchorSize) {
00094 return ZONE_BOTTOMRIGHT_CORNER;
00095 }
00096 }
00097 return ZONE_NONE;
00098 }
00099
00100 static void UI_EditorNodeDraw (uiNode_t *node)
00101 {
00102 UI_CaptureDrawOver(node);
00103 }
00104
00105 static void UI_EditorNodeDrawOverWindow (uiNode_t *node)
00106 {
00107 uiNode_t* hovered = NULL;
00108
00109 if (UI_GetMouseCapture() != node) {
00110 if (anchoredNode)
00111 UI_EditorNodeHighlightNode(anchoredNode, red, qfalse);
00112 return;
00113 }
00114
00115 if (dragStatus == ZONE_NONE) {
00116 #if 0
00117 if (anchoredNode)
00118 UI_EditorNodeGetElementAtPosition(anchoredNode, mousePosX, mousePosY);
00119 #endif
00120 hovered = UI_GetNodeAtPosition(mousePosX, mousePosY);
00121
00122 if (hovered && hovered->root == node->root)
00123 hovered = NULL;
00124 }
00125
00126 if (hovered && hovered != anchoredNode)
00127 UI_EditorNodeHighlightNode(hovered, grey, qtrue);
00128
00129 if (anchoredNode)
00130 UI_EditorNodeHighlightNode(anchoredNode, red, qtrue);
00131 }
00132
00133 static void UI_EditorNodeCapturedMouseMove (uiNode_t *node, int x, int y)
00134 {
00135 vec2_t size;
00136 const int diffX = x - startX;
00137 const int diffY = y - startY;
00138 startX = x;
00139 startY = y;
00140
00141 if (anchoredNode == NULL)
00142 return;
00143
00144 switch (dragStatus) {
00145 case ZONE_NONE:
00146 return;
00147 case ZONE_TOPLEFT_CORNER:
00148 anchoredNode->pos[0] += diffX;
00149 anchoredNode->pos[1] += diffY;
00150 size[0] = anchoredNode->size[0] - diffX;
00151 size[1] = anchoredNode->size[1] - diffY;
00152 break;
00153 case ZONE_TOPRIGHT_CORNER:
00154 anchoredNode->pos[1] += diffY;
00155 size[0] = anchoredNode->size[0] + diffX;
00156 size[1] = anchoredNode->size[1] - diffY;
00157 break;
00158 case ZONE_BOTTOMLEFT_CORNER:
00159 anchoredNode->pos[0] += diffX;
00160 size[0] = anchoredNode->size[0] - diffX;
00161 size[1] = anchoredNode->size[1] + diffY;
00162 break;
00163 case ZONE_BOTTOMRIGHT_CORNER:
00164 size[0] = anchoredNode->size[0] + diffX;
00165 size[1] = anchoredNode->size[1] + diffY;
00166 break;
00167 case ZONE_BODY:
00168 anchoredNode->pos[0] += diffX;
00169 anchoredNode->pos[1] += diffY;
00170 size[0] = anchoredNode->size[0];
00171 size[1] = anchoredNode->size[1];
00172 break;
00173 default:
00174 Sys_Error("UI_EditorNodeCapturedMouseMove: Invalid status of %i", dragStatus);
00175 }
00176
00177 if (size[0] < 5)
00178 size[0] = 5;
00179 if (size[1] < 5)
00180 size[1] = 5;
00181
00182 UI_NodeSetSize(anchoredNode, size);
00183 }
00184
00188 static void UI_EditorNodeCapturedMouseLost (uiNode_t *node)
00189 {
00190 dragStatus = ZONE_NONE;
00191 }
00192
00193 static void UI_EditorNodeMouseUp (uiNode_t *node, int x, int y, int button)
00194 {
00195 if (UI_GetMouseCapture() != node)
00196 return;
00197 if (button != K_MOUSE1)
00198 return;
00199 dragStatus = ZONE_NONE;
00200 }
00201
00202 static void UI_EditorNodeSelectNode (uiNode_t *node, uiNode_t *selected)
00203 {
00204 if (selected == NULL)
00205 return;
00206
00207 if (selected->root == node->root)
00208 return;
00209 anchoredNode = selected;
00210 Cvar_Set("mn_sys_editor_node", anchoredNode->name);
00211 Cvar_Set("mn_sys_editor_window", anchoredNode->root->name);
00212 }
00213
00214 static void UI_EditorNodeMouseDown (uiNode_t *node, int x, int y, int button)
00215 {
00216 uiNode_t* hovered;
00217
00218 if (UI_GetMouseCapture() != node)
00219 return;
00220 if (button != K_MOUSE1)
00221 return;
00222
00223 hovered = UI_GetNodeAtPosition(mousePosX, mousePosY);
00224
00225
00226 if (hovered && hovered->root == node->root) {
00227 UI_MouseRelease();
00228 return;
00229 }
00230
00231 if (hovered == anchoredNode)
00232 hovered = NULL;
00233
00234 if (anchoredNode) {
00235 dragStatus = UI_EditorNodeGetElementAtPosition(anchoredNode, x, y);
00236 if (dragStatus == ZONE_BODY) {
00237 if (hovered == NULL) {
00238 startX = x;
00239 startY = y;
00240 return;
00241 }
00242 } else if (dragStatus != ZONE_NONE) {
00243 startX = x;
00244 startY = y;
00245 return;
00246 }
00247 }
00248
00249
00250 UI_EditorNodeSelectNode(node, hovered);
00251 }
00252
00253 static void UI_EditorNodeStart (uiNode_t *node, const uiCallContext_t *context)
00254 {
00255 UI_SetMouseCapture(node);
00256 }
00257
00258 static void UI_EditorNodeStop (uiNode_t *node, const uiCallContext_t *context)
00259 {
00260 UI_MouseRelease();
00261 }
00262
00263 static void UI_EditorNodeSelectNext (uiNode_t *node, const uiCallContext_t *context)
00264 {
00265 if (dragStatus != ZONE_NONE)
00266 return;
00267 if (anchoredNode == NULL)
00268 return;
00269 UI_EditorNodeSelectNode(node, anchoredNode->next);
00270 }
00271
00272 static void UI_EditorNodeSelectParent (uiNode_t *node, const uiCallContext_t *context)
00273 {
00274 if (dragStatus != ZONE_NONE)
00275 return;
00276 if (anchoredNode == NULL)
00277 return;
00278 UI_EditorNodeSelectNode(node, anchoredNode->parent);
00279 }
00280
00281 static void UI_EditorNodeSelectFirstChild (uiNode_t *node, const uiCallContext_t *context)
00282 {
00283 if (dragStatus != ZONE_NONE)
00284 return;
00285 if (anchoredNode == NULL)
00286 return;
00287 UI_EditorNodeSelectNode(node, anchoredNode->firstChild);
00288 }
00289
00290 static void UI_EditorNodeExtractNode (qFILE *file, uiNode_t *node, int depth)
00291 {
00292 int i;
00293 char tab[16];
00294 uiNode_t *child;
00295 assert(depth < 16);
00296
00297 for (i = 0; i < depth; i++) {
00298 tab[i] = '\t';
00299 }
00300 tab[i] = '\0';
00301
00302 FS_Printf(file, "%s%s %s {\n", tab, node->behaviour->name, node->name);
00303 child = node->firstChild;
00304
00305
00306 if (child) {
00307 FS_Printf(file, "%s\t{\n", tab);
00308 FS_Printf(file, "%s\t\tpos\t\"%d %d\"\n", tab, (int)node->pos[0], (int)node->pos[1]);
00309 FS_Printf(file, "%s\t\tsize\t\"%d %d\"\n", tab, (int)node->size[0], (int)node->size[1]);
00310 FS_Printf(file, "%s\t}\n", tab);
00311 } else {
00312 FS_Printf(file, "%s\tpos\t\"%d %d\"\n", tab, (int)node->pos[0], (int)node->pos[1]);
00313 FS_Printf(file, "%s\tsize\t\"%d %d\"\n", tab, (int)node->size[0], (int)node->size[1]);
00314 }
00315
00316
00317 while (child) {
00318 UI_EditorNodeExtractNode(file, child, depth + 1);
00319 child = child->next;
00320 }
00321
00322 FS_Printf(file, "%s}\n", tab);
00323 }
00324
00329 static void UI_EditorNodeExtract_f (void)
00330 {
00331 uiNode_t* window;
00332 qFILE file;
00333
00334 if (Cmd_Argc() != 2) {
00335 Com_Printf("Usage: %s <windowname>\n", Cmd_Argv(0));
00336 return;
00337 }
00338 window = UI_GetWindow(Cmd_Argv(1));
00339 if (!window) {
00340 Com_Printf("Window '%s' not found\n", Cmd_Argv(1));
00341 return;
00342 }
00343
00344 FS_OpenFile(va("window_%s_extracted.ufo", window->name), &file, FILE_WRITE);
00345 UI_EditorNodeExtractNode(&file, window, 0);
00346 FS_CloseFile(&file);
00347
00348 Com_Printf("Window '%s' extracted.\n", Cmd_Argv(1));
00349 }
00350
00351 static const value_t properties[] = {
00352
00353 {"start", V_UI_NODEMETHOD, ((size_t) UI_EditorNodeStart), 0},
00354
00355 {"stop", V_UI_NODEMETHOD, ((size_t) UI_EditorNodeStop), 0},
00356
00357 {"selectnext", V_UI_NODEMETHOD, ((size_t) UI_EditorNodeSelectNext), 0},
00358
00359 {"selectparent", V_UI_NODEMETHOD, ((size_t) UI_EditorNodeSelectParent), 0},
00360
00361 {"selectfirstchild", V_UI_NODEMETHOD, ((size_t) UI_EditorNodeSelectFirstChild), 0},
00362 {NULL, V_NULL, 0, 0}
00363 };
00364
00365 void UI_RegisterEditorNode (uiBehaviour_t *behaviour)
00366 {
00367 behaviour->name = "editor";
00368 behaviour->extends = "special";
00369 behaviour->draw = UI_EditorNodeDraw;
00370 behaviour->drawOverWindow = UI_EditorNodeDrawOverWindow;
00371 behaviour->mouseDown = UI_EditorNodeMouseDown;
00372 behaviour->mouseUp = UI_EditorNodeMouseUp;
00373 behaviour->capturedMouseMove = UI_EditorNodeCapturedMouseMove;
00374 behaviour->capturedMouseLost = UI_EditorNodeCapturedMouseLost;
00375 behaviour->properties = properties;
00376
00377 Cmd_AddCommand("mn_extract", UI_EditorNodeExtract_f, "Extract position and size of nodes into a file");
00378 Cmd_AddParamCompleteFunction("mn_extract", UI_CompleteWithWindow);
00379 }