00001
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "../ui_main.h"
00047 #include "../ui_internal.h"
00048 #include "../ui_parse.h"
00049 #include "../ui_font.h"
00050 #include "../ui_input.h"
00051 #include "../ui_draw.h"
00052 #include "../ui_render.h"
00053 #include "ui_node_selectbox.h"
00054 #include "ui_node_abstractoption.h"
00055 #include "ui_node_abstractnode.h"
00056 #include "ui_node_option.h"
00057
00058 #include "../../client.h"
00059
00060 #define EXTRADATA(node) UI_EXTRADATA(node, abstractOptionExtraData_t)
00061
00062 #define SELECTBOX_DEFAULT_HEIGHT 20.0f
00063
00064 #define SELECTBOX_SIDE_WIDTH 7.0f
00065 #define SELECTBOX_RIGHT_WIDTH 20.0f
00066
00067 #define SELECTBOX_SPACER 2.0f
00068 #define SELECTBOX_BOTTOM_HEIGHT 4.0f
00069
00074 static void UI_SelectBoxNodeCapturedMouseMove (uiNode_t *node, int x, int y)
00075 {
00076 uiNode_t* option;
00077 int posy;
00078
00079 UI_NodeAbsoluteToRelativePos(node, &x, &y);
00080
00081
00082 if (x < 0 || y < 0 || x > node->size[0] || y > node->size[1] * (EXTRADATA(node).count + 1)) {
00083 return;
00084 }
00085
00086 posy = node->size[1];
00087 for (option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) {
00088 if (option->invis)
00089 continue;
00090 OPTIONEXTRADATA(option).hovered = (posy <= y && y < posy + node->size[1]);
00091 posy += node->size[1];
00092 }
00093 }
00094
00095 static void UI_SelectBoxNodeDraw (uiNode_t *node)
00096 {
00097 uiNode_t* option;
00098 int selBoxX, selBoxY;
00099 const char *ref;
00100 const char *font;
00101 vec2_t nodepos;
00102 const char* imageName;
00103 const image_t *image;
00104 static vec4_t invisColor = {1.0, 1.0, 1.0, 0.7};
00105
00106 ref = UI_AbstractOptionGetCurrentValue(node);
00107 if (ref == NULL)
00108 return;
00109
00110 UI_GetNodeAbsPos(node, nodepos);
00111 imageName = UI_GetReferenceString(node, node->image);
00112 if (!imageName)
00113 imageName = "ui/selectbox";
00114
00115 image = UI_LoadImage(imageName);
00116
00117 font = UI_GetFontFromNode(node);
00118 selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH;
00119 selBoxY = nodepos[1] + SELECTBOX_SPACER;
00120
00121
00122 UI_DrawNormImage(nodepos[0], nodepos[1], SELECTBOX_SIDE_WIDTH, node->size[1],
00123 SELECTBOX_SIDE_WIDTH, SELECTBOX_DEFAULT_HEIGHT, 0.0f, 0.0f, image);
00124
00125 UI_DrawNormImage(nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1], node->size[0]-SELECTBOX_SIDE_WIDTH-SELECTBOX_RIGHT_WIDTH, node->size[1],
00126 12.0f, SELECTBOX_DEFAULT_HEIGHT, 7.0f, 0.0f, image);
00127
00128 UI_DrawNormImage(nodepos[0] + node->size[0] - SELECTBOX_RIGHT_WIDTH, nodepos[1], SELECTBOX_DEFAULT_HEIGHT, node->size[1],
00129 12.0f + SELECTBOX_RIGHT_WIDTH, SELECTBOX_DEFAULT_HEIGHT, 12.0f, 0.0f, image);
00130
00131
00132 for (option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) {
00133 const char *label;
00134
00135 if (strcmp(OPTIONEXTRADATA(option).value, ref) != 0)
00136 continue;
00137
00138 if (option->invis)
00139 R_Color(invisColor);
00140
00141 label = OPTIONEXTRADATA(option).label;
00142 if (label[0] == '_')
00143 label = _(label + 1);
00144
00145 UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY,
00146 selBoxX, node->size[0] - 4,
00147 0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00148
00149 R_Color(NULL);
00150 break;
00151 }
00152
00153
00154 if (UI_GetMouseCapture() == node) {
00155 UI_CaptureDrawOver(node);
00156 }
00157 }
00158
00159 static void UI_SelectBoxNodeDrawOverWindow (uiNode_t *node)
00160 {
00161 uiNode_t* option;
00162 int selBoxX, selBoxY;
00163 const char *ref;
00164 const char *font;
00165 vec2_t nodepos;
00166 const char* imageName;
00167 const image_t *image;
00168
00169 ref = UI_AbstractOptionGetCurrentValue(node);
00170 if (ref == NULL)
00171 return;
00172
00173 UI_GetNodeAbsPos(node, nodepos);
00174 imageName = UI_GetReferenceString(node, node->image);
00175 if (!imageName)
00176 imageName = "ui/selectbox";
00177
00178 image = UI_LoadImage(imageName);
00179
00180 font = UI_GetFontFromNode(node);
00181 selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH;
00182 selBoxY = nodepos[1] + SELECTBOX_SPACER;
00183
00184 selBoxY += node->size[1];
00185
00186
00187
00188 UI_DrawNormImage(nodepos[0], nodepos[1] + node->size[1], SELECTBOX_SIDE_WIDTH, node->size[1] * EXTRADATA(node).count,
00189 7.0f, 28.0f, 0.0f, 21.0f, image);
00190
00191
00192 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,
00193 16.0f, 28.0f, 7.0f, 21.0f, image);
00194
00195
00196 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,
00197 23.0f, 28.0f, 16.0f, 21.0f, image);
00198
00199
00200 for (option = UI_AbstractOptionGetFirstOption(node); option; option = option->next) {
00201 const char *label;
00202 if (option->invis)
00203 continue;
00204
00205 if (OPTIONEXTRADATA(option).hovered)
00206 UI_DrawFill(selBoxX, selBoxY, node->size[0] -SELECTBOX_SIDE_WIDTH - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH,
00207 SELECTBOX_DEFAULT_HEIGHT, node->color);
00208
00209 label = OPTIONEXTRADATA(option).label;
00210 if (label[0] == '_')
00211 label = _(label + 1);
00212 UI_DrawString(font, ALIGN_UL, selBoxX, selBoxY,
00213 selBoxX, node->size[0] - 4,
00214 0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00215
00216 selBoxY += node->size[1];
00217 }
00218
00219 UI_DrawNormImage(nodepos[0], selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT,
00220 7.0f, 32.0f, 0.0f, 28.0f, image);
00221
00222
00223 UI_DrawNormImage(nodepos[0] + SELECTBOX_SIDE_WIDTH, selBoxY - SELECTBOX_SPACER, node->size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH,
00224 SELECTBOX_BOTTOM_HEIGHT,
00225 16.0f, 32.0f, 7.0f, 28.0f, image);
00226
00227
00228 UI_DrawNormImage(nodepos[0] + node->size[0] - SELECTBOX_SIDE_WIDTH - SELECTBOX_RIGHT_WIDTH, selBoxY - SELECTBOX_SPACER,
00229 SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT,
00230 23.0f, 32.0f, 16.0f, 28.0f, image);
00231 }
00232
00236 static void UI_SelectBoxNodeClick (uiNode_t *node, int x, int y)
00237 {
00238 uiNode_t* option;
00239 int clickedAtOption;
00240 vec2_t pos;
00241
00242
00243 if (UI_GetMouseCapture() == NULL) {
00244 UI_SetMouseCapture(node);
00245 return;
00246 }
00247
00248 UI_GetNodeAbsPos(node, pos);
00249 clickedAtOption = (y - pos[1]);
00250
00251
00252 if (x < pos[0] || y < pos[1] || x >= pos[0] + node->size[0] || y >= pos[1] + node->size[1] * (EXTRADATA(node).count + 1)) {
00253 UI_MouseRelease();
00254 return;
00255 }
00256
00257
00258 if (clickedAtOption < node->size[1]) {
00259 UI_MouseRelease();
00260 return;
00261 }
00262
00263 clickedAtOption = (clickedAtOption - node->size[1]) / node->size[1];
00264 if (clickedAtOption < 0 || clickedAtOption >= EXTRADATA(node).count)
00265 return;
00266
00267 if (UI_AbstractOptionGetCurrentValue(node) == NULL)
00268 return;
00269
00270
00271 option = UI_AbstractOptionGetFirstOption(node);
00272 for (; option; option = option->next) {
00273 if (option->invis)
00274 continue;
00275 if (clickedAtOption == 0)
00276 break;
00277 clickedAtOption--;
00278 }
00279
00280
00281 if (option)
00282 UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);
00283
00284
00285 UI_MouseRelease();
00286 }
00287
00291 static void UI_SelectBoxNodeLoading (uiNode_t *node)
00292 {
00293 Vector4Set(node->color, 0.6, 0.6, 0.6, 0.3);
00294 }
00295
00296 static void UI_SelectBoxNodeLoaded (uiNode_t *node)
00297 {
00298
00299 node->size[1] = SELECTBOX_DEFAULT_HEIGHT;
00300 }
00301
00302 void UI_RegisterSelectBoxNode (uiBehaviour_t *behaviour)
00303 {
00304 behaviour->name = "selectbox";
00305 behaviour->extends = "abstractoption";
00306 behaviour->draw = UI_SelectBoxNodeDraw;
00307 behaviour->drawOverWindow = UI_SelectBoxNodeDrawOverWindow;
00308 behaviour->leftClick = UI_SelectBoxNodeClick;
00309 behaviour->loading = UI_SelectBoxNodeLoading;
00310 behaviour->loaded = UI_SelectBoxNodeLoaded;
00311 behaviour->capturedMouseMove = UI_SelectBoxNodeCapturedMouseMove;
00312 behaviour->drawItselfChild = qtrue;
00313 }