ui_node_image.c

Go to the documentation of this file.
00001 
00019 /*
00020 Copyright (C) 2002-2010 UFO: Alien Invasion.
00021 
00022 This program is free software; you can redistribute it and/or
00023 modify it under the terms of the GNU General Public License
00024 as published by the Free Software Foundation; either version 2
00025 of the License, or (at your option) any later version.
00026 
00027 This program is distributed in the hope that it will be useful,
00028 but WITHOUT ANY WARRANTY; without even the implied warranty of
00029 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00030 
00031 See the GNU General Public License for more details.
00032 
00033 You should have received a copy of the GNU General Public License
00034 along with this program; if not, write to the Free Software
00035 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00036 
00037 */
00038 
00039 #include "../ui_nodes.h"
00040 #include "../ui_parse.h"
00041 #include "../ui_render.h"
00042 #include "ui_node_image.h"
00043 #include "ui_node_abstractnode.h"
00044 
00045 #include "../../client.h"
00046 
00047 #define EXTRADATA_TYPE imageExtraData_t
00048 #define EXTRADATA(node) UI_EXTRADATA(node, EXTRADATA_TYPE)
00049 #define EXTRADATACONST(node) UI_EXTRADATACONST(node, EXTRADATA_TYPE)
00050 
00054 static void UI_ImageNodeLoaded (uiNode_t *node)
00055 {
00056     /* update the size when its possible */
00057     if (node->size[0] == 0 && node->size[1] == 0) {
00058         if (EXTRADATA(node).texl[0] != 0 || EXTRADATA(node).texh[0]) {
00059             node->size[0] = EXTRADATA(node).texh[0] - EXTRADATA(node).texl[0];
00060             node->size[1] = EXTRADATA(node).texh[1] - EXTRADATA(node).texl[1];
00061         } else if (node->image) {
00062             const image_t *image = UI_LoadImage(node->image);
00063             if (image) {
00064                 node->size[0] = image->width;
00065                 node->size[1] = image->height;
00066             }
00067         }
00068     }
00069 #ifdef DEBUG
00070     if (node->size[0] == 0 && node->size[1] == 0) {
00071         if (node->onClick || node->onRightClick || node->onMouseEnter || node->onMouseLeave || node->onWheelUp || node->onWheelDown || node->onWheel || node->onMiddleClick) {
00072             Com_DPrintf(DEBUG_CLIENT, "Node '%s' is an active image without size\n", UI_GetPath(node));
00073         }
00074     }
00075 #endif
00076 }
00077 
00081 void UI_ImageNodeDraw (uiNode_t *node)
00082 {
00083     vec2_t size;
00084     vec2_t nodepos;
00085     const image_t *image;
00086 
00087     const char* imageName = UI_GetReferenceString(node, node->image);
00088     if (!imageName || imageName[0] == '\0')
00089         return;
00090 
00091     image = UI_LoadImage(imageName);
00092     if (!image)
00093         return;
00094 
00095     /* mouse darken effect */
00099 #if 0
00100     if (node->mousefx && node->state) {
00101         vec4_t color;
00102         VectorScale(node->color, 0.8, color);
00103         color[3] = node->color[3];
00104         R_Color(color);
00105     }
00106 #endif
00107 
00108     UI_GetNodeAbsPos(node, nodepos);
00109 
00111     if (node->size[0] && !node->size[1]) {
00112         const float scale = image->width / node->size[0];
00113         Vector2Set(size, node->size[0], image->height / scale);
00114     } else if (node->size[1] && !node->size[0]) {
00115         const float scale = image->height / node->size[1];
00116         Vector2Set(size, image->width / scale, node->size[1]);
00117     } else {
00118         if (EXTRADATA(node).preventRatio) {
00119             /* maximize the image into the bounding box */
00120             const float ratio = (float) image->width / (float) image->height;
00121             if (node->size[1] * ratio > node->size[0]) {
00122                 Vector2Set(size, node->size[0], node->size[0] / ratio);
00123             } else {
00124                 Vector2Set(size, node->size[1] * ratio, node->size[1]);
00125             }
00126         } else {
00127             Vector2Copy(node->size, size);
00128         }
00129     }
00130     UI_DrawNormImage(nodepos[0], nodepos[1], size[0], size[1],
00131         EXTRADATA(node).texh[0], EXTRADATA(node).texh[1], EXTRADATA(node).texl[0], EXTRADATA(node).texl[1], image);
00132 
00136 #if 0
00137     if (node->mousefx && node->state) {
00138         R_Color(NULL);
00139     }
00140 #endif
00141 }
00142 
00143 static const value_t properties[] = {
00144     /* Do not change the image ratio. The image will be proportionally stretched. */
00145     {"preventratio", V_BOOL, UI_EXTRADATA_OFFSETOF(imageExtraData_t, preventRatio), MEMBER_SIZEOF(imageExtraData_t, preventRatio)},
00146     /* Now this property do nothing. But we use it like a tag, to remember nodes we should convert into button...
00147      * @todo delete it when its possible (use more button instead of image)
00148      */
00149     {"mousefx", V_BOOL, UI_EXTRADATA_OFFSETOF(imageExtraData_t, mousefx), MEMBER_SIZEOF(imageExtraData_t, mousefx)},
00150 
00151     /* Texture high. Optional. Define the higher corner of the texture we want to display. Used with texl to crop the image. */
00152     {"texh", V_POS, UI_EXTRADATA_OFFSETOF(imageExtraData_t, texh), MEMBER_SIZEOF(imageExtraData_t, texh)},
00153     /* Texture low. Optional. Define the lower corner of the texture we want to display. Used with texh to crop the image. */
00154     {"texl", V_POS, UI_EXTRADATA_OFFSETOF(imageExtraData_t, texl), MEMBER_SIZEOF(imageExtraData_t, texl)},
00155 
00156     /* Source of the image */
00157     {"src", V_CVAR_OR_STRING, offsetof(uiNode_t, image), 0},
00158 
00159     {NULL, V_NULL, 0, 0}
00160 };
00161 
00162 void UI_RegisterImageNode (uiBehaviour_t* behaviour)
00163 {
00165     behaviour->name = "image";
00166     behaviour->draw = UI_ImageNodeDraw;
00167     behaviour->loaded = UI_ImageNodeLoaded;
00168     behaviour->properties = properties;
00169     behaviour->extraDataSize = sizeof(EXTRADATA_TYPE);
00170 }

Generated by  doxygen 1.6.2