ui_node_optionlist.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 #include "../ui_main.h"
00027 #include "../ui_parse.h"
00028 #include "../ui_actions.h"
00029 #include "../ui_font.h"
00030 #include "../ui_icon.h"
00031 #include "../ui_render.h"
00032 #include "ui_node_abstractoption.h"
00033 #include "ui_node_abstractnode.h"
00034 #include "ui_node_optionlist.h"
00035 #include "ui_node_panel.h"
00036 #include "ui_node_option.h"
00037 
00038 #include "../../client.h" /* gettext _() */
00039 
00040 #define EXTRADATA(node) UI_EXTRADATA(node, abstractOptionExtraData_t)
00041 
00042 #define CORNER_SIZE 25
00043 #define MID_SIZE 1
00044 #define MARGE 3
00045 
00050 static void UI_OptionListNodeUpdateScroll (uiNode_t *node)
00051 {
00052     const char *font;
00053     int fontHeight;
00054     qboolean updated;
00055     int elements;
00056 
00057     font = UI_GetFontFromNode(node);
00058     fontHeight = UI_FontGetHeight(font);
00059 
00060     elements = (node->size[1] - node->padding - node->padding) / fontHeight;
00061     updated = UI_SetScroll(&EXTRADATA(node).scrollY, -1, elements, EXTRADATA(node).count);
00062     if (updated && EXTRADATA(node).onViewChange)
00063         UI_ExecuteEventActions(node, EXTRADATA(node).onViewChange);
00064 }
00065 
00066 static void UI_OptionListNodeDraw (uiNode_t *node)
00067 {
00068     static const int panelTemplate[] = {
00069         CORNER_SIZE, MID_SIZE, CORNER_SIZE,
00070         CORNER_SIZE, MID_SIZE, CORNER_SIZE,
00071         MARGE
00072     };
00073     uiNode_t* option;
00074     const char *ref;
00075     const char *font;
00076     int fontHeight;
00077     vec2_t pos;
00078     const char* image;
00079     int currentY;
00080     const float *textColor;
00081     static vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0};
00082     int count = 0;
00083 
00084     ref = UI_AbstractOptionGetCurrentValue(node);
00085     if (ref == NULL)
00086         return;
00087 
00088     UI_GetNodeAbsPos(node, pos);
00089 
00090     image = UI_GetReferenceString(node, node->image);
00091     if (image)
00092         UI_DrawPanel(pos, node->size, image, 0, 0, panelTemplate);
00093 
00094     font = UI_GetFontFromNode(node);
00095     fontHeight = UI_FontGetHeight(font);
00096     currentY = pos[1] + node->padding;
00097 
00098     /* skip option over current position */
00099     option = UI_AbstractOptionGetFirstOption(node);
00100     while (option && count < EXTRADATA(node).scrollY.viewPos) {
00101         option = option->next;
00102         count++;
00103     }
00104 
00105     /* draw all available options for this selectbox */
00106     for (; option; option = option->next) {
00107         const char *label;
00108         int decX = pos[0] + node->padding;
00109         /* outside the node */
00110         if (currentY + fontHeight > pos[1] + node->size[1] - node->padding) {
00111             count++;
00112             break;
00113         }
00114 
00115         /* draw the hover effect */
00116         if (OPTIONEXTRADATA(option).hovered)
00117             UI_DrawFill(pos[0] + node->padding, currentY, node->size[0] - node->padding - node->padding, fontHeight, node->color);
00118 
00119         /* text color */
00120         if (!strcmp(OPTIONEXTRADATA(option).value, ref)) {
00121             textColor = node->selectedColor;
00122         } else if (node->disabled || option->disabled) {
00123             textColor = disabledColor;
00124         } else if (option->color[3] == 0.0f) {
00125             textColor = node->color;
00126         } else {
00127             textColor = option->color;
00128         }
00129 
00130         if (OPTIONEXTRADATA(option).icon) {
00131             uiIconStatus_t iconStatus = ICON_STATUS_NORMAL;
00132             if (option->disabled)
00133                 iconStatus = ICON_STATUS_DISABLED;
00134             R_Color(NULL);
00135             UI_DrawIconInBox(OPTIONEXTRADATA(option).icon, iconStatus, decX, currentY, OPTIONEXTRADATA(option).icon->size[0], fontHeight);
00136             decX += OPTIONEXTRADATA(option).icon->size[0] + fontHeight / 4;
00137         }
00138 
00139         /* print the option label */
00140         label = OPTIONEXTRADATA(option).label;
00141         if (label[0] == '_')
00142             label = _(label + 1);
00143 
00144         R_Color(textColor);
00145         UI_DrawString(font, ALIGN_UL, decX, currentY,
00146             pos[0], node->size[0] - node->padding - node->padding,
00147             0, label, 0, 0, NULL, qfalse, LONGLINES_PRETTYCHOP);
00148 
00149         /* next entries' position */
00150         currentY += fontHeight;
00151         count++;
00152     }
00153     R_Color(NULL);
00154 
00155     /* count number of options (current architecture doesn't allow to know if the data change) */
00156     for (; option; option = option->next) {
00157         count++;
00158     }
00159 
00160     if (EXTRADATA(node).count != count) {
00161         EXTRADATA(node).count = count;
00162     }
00163 
00164     UI_OptionListNodeUpdateScroll(node);
00165 }
00166 
00167 static uiNode_t* UI_OptionListNodeGetOptionAtPosition (uiNode_t * node, int x, int y)
00168 {
00169     uiNode_t* option;
00170     vec2_t pos;
00171     int fontHeight;
00172     int currentY;
00173     int count = 0;
00174     const char *font;
00175 
00176     UI_GetNodeAbsPos(node, pos);
00177     currentY = pos[1] + node->padding;
00178 
00179     font = UI_GetFontFromNode(node);
00180     fontHeight = UI_FontGetHeight(font);
00181 
00182     option = UI_AbstractOptionGetFirstOption(node);
00183     while (option && count < EXTRADATA(node).scrollY.viewPos) {
00184         option = option->next;
00185         count++;
00186     }
00187 
00188     /* now draw all available options for this selectbox */
00189     for (; option; option = option->next) {
00190         if (y < currentY + fontHeight)
00191             return option;
00192         if (currentY + fontHeight > pos[1] + node->size[1] - node->padding)
00193             break;
00194         currentY += fontHeight;
00195     }
00196     return NULL;
00197 }
00198 
00202 static void UI_OptionListNodeClick (uiNode_t * node, int x, int y)
00203 {
00204     uiNode_t* option;
00205 
00206     if (UI_AbstractOptionGetCurrentValue(node) == NULL)
00207         return;
00208 
00209     /* select the right option */
00210     option = UI_OptionListNodeGetOptionAtPosition(node, x, y);
00211 
00212     /* update the status */
00213     if (option)
00214         UI_AbstractOptionSetCurrentValue(node, OPTIONEXTRADATA(option).value);
00215 }
00216 
00220 static void UI_OptionListNodeMouseWheel (uiNode_t *node, qboolean down, int x, int y)
00221 {
00222     qboolean updated;
00223     updated = UI_SetScroll(&EXTRADATA(node).scrollY, EXTRADATA(node).scrollY.viewPos + (down ? 1 : -1), -1, -1);
00224     if (EXTRADATA(node).onViewChange && updated)
00225         UI_ExecuteEventActions(node, EXTRADATA(node).onViewChange);
00226 
00227     if (node->onWheelUp && !down)
00228         UI_ExecuteEventActions(node, node->onWheelUp);
00229     if (node->onWheelDown && down)
00230         UI_ExecuteEventActions(node, node->onWheelDown);
00231     if (node->onWheel)
00232         UI_ExecuteEventActions(node, node->onWheel);
00233 }
00234 
00238 static void UI_OptionListNodeLoading (uiNode_t *node)
00239 {
00240     Vector4Set(node->color, 1, 1, 1, 1);
00241     EXTRADATA(node).versionId = -1;
00242     node->padding = 3;
00243 }
00244 
00245 static void UI_OptionListNodeLoaded (uiNode_t *node)
00246 {
00247 }
00248 
00249 void UI_RegisterOptionListNode (uiBehaviour_t *behaviour)
00250 {
00251     behaviour->name = "optionlist";
00252     behaviour->extends = "abstractoption";
00253     behaviour->draw = UI_OptionListNodeDraw;
00254     behaviour->leftClick = UI_OptionListNodeClick;
00255     behaviour->mouseWheel = UI_OptionListNodeMouseWheel;
00256     behaviour->loading = UI_OptionListNodeLoading;
00257     behaviour->loaded = UI_OptionListNodeLoaded;
00258     behaviour->drawItselfChild = qtrue;
00259 }

Generated by  doxygen 1.6.2