00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "../ui_nodes.h"
00027 #include "../ui_parse.h"
00028 #include "../ui_main.h"
00029 #include "../ui_input.h"
00030 #include "../ui_timer.h"
00031 #include "../ui_actions.h"
00032 #include "../ui_render.h"
00033 #include "ui_node_spinner.h"
00034 #include "ui_node_abstractvalue.h"
00035 #include "ui_node_abstractnode.h"
00036
00037 #include "../../input/cl_input.h"
00038 #include "../../input/cl_keys.h"
00039
00040 #define EXTRADATA(node) UI_EXTRADATA(node, abstractValueExtraData_t)
00041
00042 static const uiBehaviour_t const *localBehaviour;
00043
00044 static const int TILE_SIZE = 32;
00045 static const int SPINNER_WIDTH = 15;
00046 static const int SPINNER_HEIGHT = 19;
00047 static const int BUTTON_TOP_SIZE = 9;
00048 static const int BUTTON_BOTTOM_SIZE = 10;
00049
00055 static void UI_SpinnerNodeStep (uiNode_t *node, qboolean down)
00056 {
00057 float value = UI_GetReferenceFloat(node, EXTRADATA(node).value);
00058 const float last = value;
00059 const float delta = UI_GetReferenceFloat(node, EXTRADATA(node).delta);
00060 const float max = UI_GetReferenceFloat(node, EXTRADATA(node).max);
00061 const float min = UI_GetReferenceFloat(node, EXTRADATA(node).min);
00062
00063 if (!down) {
00064 if (value + delta <= max) {
00065 value += delta;
00066 } else {
00067 value = max;
00068 }
00069 } else {
00070 if (value - delta >= min) {
00071 value -= delta;
00072 } else {
00073 value = min;
00074 }
00075 }
00076
00077
00078 if (value < min)
00079 value = min;
00080 else if (value > max)
00081 value = max;
00082
00083
00084 if (last == value)
00085 return;
00086
00087
00088 EXTRADATA(node).lastdiff = value - last;
00089 if (!strncmp(EXTRADATA(node).value, "*cvar:", 6))
00090 UI_SetCvar(&((char*)EXTRADATA(node).value)[6], NULL, value);
00091 else
00092 *(float*) EXTRADATA(node).value = value;
00093
00094
00095 if (node->onChange)
00096 UI_ExecuteEventActions(node, node->onChange);
00097 }
00098
00099 static qboolean capturedDownButton;
00100 static uiTimer_t *capturedTimer = NULL;
00101
00102 static void UI_SpinnerNodeRepeat (uiNode_t *node, uiTimer_t *timer)
00103 {
00104 UI_SpinnerNodeStep(node, capturedDownButton);
00105 switch (timer->calledTime) {
00106 case 1:
00107 timer->delay = 50;
00108 break;
00109 }
00110 }
00111
00112 static void UI_SpinnerNodeDown (uiNode_t *node, int x, int y, int button)
00113 {
00114 if (button == K_MOUSE1) {
00115 UI_SetMouseCapture(node);
00116 UI_NodeAbsoluteToRelativePos(node, &x, &y);
00117 capturedDownButton = y > BUTTON_TOP_SIZE;
00118 UI_SpinnerNodeStep(node, capturedDownButton);
00119 capturedTimer = UI_AllocTimer(node, 500, UI_SpinnerNodeRepeat);
00120 UI_TimerStart (capturedTimer);
00121 }
00122 }
00123
00124 static void UI_SpinnerNodeUp (uiNode_t *node, int x, int y, int button)
00125 {
00126 if (button == K_MOUSE1) {
00127 UI_MouseRelease();
00128 }
00129 }
00130
00135 static void UI_SpinnerNodeCapturedMouseLost (uiNode_t *node)
00136 {
00137 if (capturedTimer) {
00138 UI_TimerRelease(capturedTimer);
00139 capturedTimer = NULL;
00140 }
00141 }
00142
00146 static void UI_SpinnerNodeWheel (uiNode_t *node, qboolean down, int x, int y)
00147 {
00148 const qboolean disabled = node->disabled || node->parent->disabled;
00149 if (disabled)
00150 return;
00151 UI_SpinnerNodeStep(node, down);
00152 }
00153
00154 static void UI_SpinnerNodeDraw (uiNode_t *node)
00155 {
00156 vec2_t pos;
00157 int topTexX, topTexY;
00158 int bottomTexX, bottomTexY;
00159 const char* image = UI_GetReferenceString(node, node->image);
00160 const float delta = UI_GetReferenceFloat(node, EXTRADATA(node).delta);
00161 const qboolean disabled = node->disabled || node->parent->disabled;
00162
00163 if (!image)
00164 return;
00165
00166 UI_GetNodeAbsPos(node, pos);
00167
00168 if (disabled || delta == 0) {
00169 topTexX = TILE_SIZE;
00170 topTexY = TILE_SIZE;
00171 bottomTexX = TILE_SIZE;
00172 bottomTexY = TILE_SIZE;
00173 } else {
00174 const float value = UI_GetReferenceFloat(node, EXTRADATA(node).value);
00175 const float min = UI_GetReferenceFloat(node, EXTRADATA(node).min);
00176 const float max = UI_GetReferenceFloat(node, EXTRADATA(node).max);
00177
00178
00179 if (value >= max) {
00180 topTexX = TILE_SIZE;
00181 topTexY = TILE_SIZE;
00182 } else if (node->state && mousePosY < pos[1] + BUTTON_TOP_SIZE) {
00183 topTexX = TILE_SIZE;
00184 topTexY = 0;
00185 } else {
00186 topTexX = 0;
00187 topTexY = 0;
00188 }
00189
00190 if (value <= min) {
00191 bottomTexX = TILE_SIZE;
00192 bottomTexY = TILE_SIZE;
00193 } else if (node->state && mousePosY > pos[1] + BUTTON_TOP_SIZE) {
00194 bottomTexX = TILE_SIZE;
00195 bottomTexY = 0;
00196 } else {
00197 bottomTexX = 0;
00198 bottomTexY = 0;
00199 }
00200 }
00201
00202
00203 UI_DrawNormImageByName(pos[0], pos[1], SPINNER_WIDTH, BUTTON_TOP_SIZE,
00204 topTexX + SPINNER_WIDTH, topTexY + BUTTON_TOP_SIZE, topTexX, topTexY, image);
00205
00206 UI_DrawNormImageByName(pos[0], pos[1] + BUTTON_TOP_SIZE, SPINNER_WIDTH, BUTTON_BOTTOM_SIZE,
00207 bottomTexX + SPINNER_WIDTH, bottomTexY + SPINNER_HEIGHT, bottomTexX, bottomTexY + SPINNER_HEIGHT - BUTTON_BOTTOM_SIZE, image);
00208 }
00209
00210 static void UI_SpinnerNodeLoaded (uiNode_t *node)
00211 {
00212 localBehaviour->super->loaded(node);
00213
00214 node->size[0] = SPINNER_WIDTH;
00215 node->size[1] = SPINNER_HEIGHT;
00216 }
00217
00218 static const value_t properties[] = {
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 {NULL, V_NULL, 0, 0}
00230 };
00231
00232 void UI_RegisterSpinnerNode (uiBehaviour_t *behaviour)
00233 {
00234 localBehaviour = behaviour;
00235 behaviour->name = "spinner";
00236 behaviour->extends = "abstractvalue";
00237 behaviour->mouseWheel = UI_SpinnerNodeWheel;
00238 behaviour->mouseDown = UI_SpinnerNodeDown;
00239 behaviour->mouseUp = UI_SpinnerNodeUp;
00240 behaviour->capturedMouseLost = UI_SpinnerNodeCapturedMouseLost;
00241 behaviour->draw = UI_SpinnerNodeDraw;
00242 behaviour->loaded = UI_SpinnerNodeLoaded;
00243 behaviour->properties = properties;
00244 }