UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ui_node_image.cpp
Go to the documentation of this file.
1 
19 /*
20 Copyright (C) 2002-2020 UFO: Alien Invasion.
21 
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License
24 as published by the Free Software Foundation; either version 2
25 of the License, or (at your option) any later version.
26 
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30 
31 See the GNU General Public License for more details.
32 
33 You should have received a copy of the GNU General Public License
34 along with this program; if not, write to the Free Software
35 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 
37 */
38 
39 #include "../ui_nodes.h"
40 #include "../ui_parse.h"
41 #include "../ui_behaviour.h"
42 #include "../ui_render.h"
43 #include "ui_node_image.h"
44 #include "ui_node_abstractnode.h"
45 
46 #include "../../client.h"
47 
48 #include "../../../common/scripts_lua.h"
49 
50 #define EXTRADATA_TYPE imageExtraData_t
51 #define EXTRADATA(node) UI_EXTRADATA(node, EXTRADATA_TYPE)
52 #define EXTRADATACONST(node) UI_EXTRADATACONST(node, EXTRADATA_TYPE)
53 
58 {
59  /* update the size when its possible */
60  if (Vector2Empty(node->box.size)) {
61  if (EXTRADATA(node).texl[0] != 0 || EXTRADATA(node).texh[0]) {
62  node->box.size[0] = EXTRADATA(node).texh[0] - EXTRADATA(node).texl[0];
63  node->box.size[1] = EXTRADATA(node).texh[1] - EXTRADATA(node).texl[1];
64  } else if (node->image) {
65  const image_t* image = UI_LoadImage(node->image);
66  if (image) {
67  node->box.size[0] = image->width;
68  node->box.size[1] = image->height;
69  }
70  }
71  }
72 #ifdef DEBUG
73  if (Vector2Empty(node->box.size)) {
74  if (node->onClick || node->onRightClick || node->onMouseEnter || node->onMouseLeave || node->onWheelUp || node->onWheelDown || node->onWheel || node->onMiddleClick) {
75  Com_DPrintf(DEBUG_CLIENT, "Node '%s' is an active image without size\n", UI_GetPath(node));
76  }
77  }
78 #endif
79 }
80 
90 static void UI_ImageAlignBoxInBox (vec2_t outerBoxPos, vec2_t outerBoxSize, vec2_t innerBoxSize, align_t align, vec2_t innerBoxPos)
91 {
92  switch (align % 3) {
93  case 0: /* left */
94  innerBoxPos[0] = outerBoxPos[0];
95  break;
96  case 1: /* middle */
97  innerBoxPos[0] = outerBoxPos[0] + (outerBoxSize[0] * 0.5) - (innerBoxSize[0] * 0.5);
98  break;
99  case 2: /* right */
100  innerBoxPos[0] = outerBoxPos[0] + outerBoxSize[0] - innerBoxSize[0];
101  break;
102  }
103  switch (align / 3) {
104  case 0: /* top */
105  innerBoxPos[1] = outerBoxPos[1];
106  break;
107  case 1: /* middle */
108  innerBoxPos[1] = outerBoxPos[1] + (outerBoxSize[1] * 0.5) - (innerBoxSize[1] * 0.5);
109  break;
110  case 2: /* bottom */
111  innerBoxPos[1] = outerBoxPos[1] + outerBoxSize[1] - innerBoxSize[1];
112  break;
113  default:
114  innerBoxPos[1] = outerBoxPos[1];
115  Com_Error(ERR_FATAL, "UI_ImageAlignBoxInBox: Align %d not supported\n", align);
116  }
117 }
118 
124 {
125  vec2_t size;
126  vec2_t nodepos;
127  const image_t* image;
128  vec2_t nodesize;
129 
130  const char* imageName = UI_GetReferenceString(node, node->image);
131  if (Q_strnull(imageName))
132  return;
133 
134  image = UI_LoadImage(imageName);
135  if (!image)
136  return;
137 
138  /* mouse darken effect */
142 #if 0
143  if (node->mousefx && node->state) {
144  vec4_t color;
145  VectorScale(node->color, 0.8, color);
146  color[3] = node->color[3];
147  R_Color(color);
148  }
149 #endif
150 
151  UI_GetNodeAbsPos(node, nodepos);
152  Vector2Copy(node->box.size, nodesize);
153  nodesize[0] -= node->padding + node->padding;
154  if (nodesize[0] < 0)
155  nodesize[0] = 0;
156  nodesize[1] -= node->padding + node->padding;
157  if (nodesize[1] < 0)
158  nodesize[1] = 0;
159 
160  if (node->box.size[0] && !node->box.size[1]) {
161  const float scale = image->width / node->box.size[0];
162  Vector2Set(size, node->box.size[0], image->height / scale);
163  } else if (node->box.size[1] && !node->box.size[0]) {
164  const float scale = image->height / node->box.size[1];
165  Vector2Set(size, image->width / scale, node->box.size[1]);
166  } else {
167  Vector2Copy(nodesize, size);
168 
169  if (EXTRADATA(node).preventRatio) {
170  /* maximize the image into the bounding box */
171  const float ratio = (float) image->width / (float) image->height;
172  if (size[1] * ratio > size[0]) {
173  Vector2Set(size, size[0], size[0] / ratio);
174  } else {
175  Vector2Set(size, size[1] * ratio, size[1]);
176  }
177  }
178  }
179 
180  vec2_t imagepos;
181  OBJZERO(imagepos);
182  UI_ImageAlignBoxInBox(nodepos, nodesize, size, (align_t) node->contentAlign, imagepos);
183  UI_DrawNormImage(false, imagepos[0] + node->padding, imagepos[1] + node->padding, size[0], size[1],
184  EXTRADATA(node).texh[0], EXTRADATA(node).texh[1],
185  EXTRADATA(node).texl[0], EXTRADATA(node).texl[1], image);
186 
190 #if 0
191  if (node->mousefx && node->state) {
192  R_Color(nullptr);
193  }
194 #endif
195 }
196 
198 {
200  behaviour->name = "image";
201  behaviour->manager = UINodePtr(new uiImageNode());
202  behaviour->extraDataSize = sizeof(EXTRADATA_TYPE);
203  behaviour->lua_SWIG_typeinfo = UI_SWIG_TypeQuery("uiImageNode_t *");
204 
205  /* Do not change the image ratio. The image will be proportionally stretched. */
206  UI_RegisterExtradataNodeProperty(behaviour, "preventratio", V_BOOL, EXTRADATA_TYPE, preventRatio);
207  /* Now this property do nothing. But we use it like a tag, to remember nodes we should convert into button...
208  * @todo delete it when its possible (use more button instead of image)
209  */
210  UI_RegisterExtradataNodeProperty(behaviour, "mousefx", V_BOOL, EXTRADATA_TYPE, mousefx);
211 
212  /* Texture high. Optional. Define the higher corner of the texture we want to display. Used with texl to crop the image. */
213  UI_RegisterExtradataNodeProperty(behaviour, "texh", V_POS, EXTRADATA_TYPE, texh);
214  /* Texture low. Optional. Define the lower corner of the texture we want to display. Used with texh to crop the image. */
215  UI_RegisterExtradataNodeProperty(behaviour, "texl", V_POS, EXTRADATA_TYPE, texl);
216 
217  /* Source of the image */
218  //UI_RegisterExtradataNodeProperty(behaviour, "src", V_CVAR_OR_STRING, EXTRADATA_TYPE, image);
219  UI_RegisterNodeProperty(behaviour, "src", V_CVAR_OR_STRING, uiNode_t, image);
220 }
bool Q_strnull(const char *string)
Definition: shared.h:138
struct uiAction_s * onWheelDown
Definition: ui_nodes.h:142
vec2_t size
Definition: ui_nodes.h:52
const char * name
Definition: ui_behaviour.h:41
static const vec3_t scale
struct uiAction_s * onMouseEnter
Definition: ui_nodes.h:139
void draw(uiNode_t *node) override
Draws the image node.
struct uiAction_s * onMouseLeave
Definition: ui_nodes.h:140
UINodePtr manager
Definition: ui_behaviour.h:43
static void UI_ImageAlignBoxInBox(vec2_t outerBoxPos, vec2_t outerBoxSize, vec2_t innerBoxSize, align_t align, vec2_t innerBoxPos)
Get position of a inner box inside an outer box according to align param.
#define UI_RegisterNodeProperty(BEHAVIOUR, NAME, TYPE, OBJECTTYPE, ATTRIBUTE)
Initialize a property.
Definition: ui_behaviour.h:91
int width
Definition: r_image.h:64
struct uiAction_s * onClick
Definition: ui_nodes.h:135
void onLoaded(uiNode_t *node) override
Handled after the end of the load of the node from the script (all data and/or child are set) ...
#define VectorScale(in, scale, out)
Definition: vector.h:79
#define ERR_FATAL
Definition: common.h:210
#define UI_RegisterExtradataNodeProperty(BEHAVIOUR, NAME, TYPE, EXTRADATATYPE, ATTRIBUTE)
Initialize a property from extradata of node.
Definition: ui_behaviour.h:109
void R_Color(const vec4_t rgba)
Change the color to given value.
Definition: r_state.cpp:1011
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
#define Vector2Empty(a)
Definition: vector.h:74
align_t
We need this here for checking the boundaries from script values.
Definition: scripts.h:90
#define DEBUG_CLIENT
Definition: defines.h:59
bool state
Definition: ui_nodes.h:106
GLsizei size
Definition: r_gl.h:152
#define OBJZERO(obj)
Definition: shared.h:178
struct uiAction_s * onWheelUp
Definition: ui_nodes.h:141
#define Vector2Set(v, x, y)
Definition: vector.h:61
struct uiAction_s * onMiddleClick
Definition: ui_nodes.h:137
SharedPtr< uiNode > UINodePtr
const struct image_s * UI_LoadImage(const char *name)
Searches for an image in the image array.
Definition: ui_render.cpp:91
const char * UI_GetPath(const uiNode_t *node)
Return a path from a window to a node.
Definition: ui_nodes.cpp:174
int padding
Definition: ui_nodes.h:109
void * lua_SWIG_typeinfo
Definition: ui_behaviour.h:57
void UI_DrawNormImage(bool flip, float x, float y, float w, float h, float sh, float th, float sl, float tl, const image_t *image)
Draw a normalized (to the screen) image.
Definition: ui_render.cpp:126
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition: common.cpp:398
const char * UI_GetReferenceString(const uiNode_t *const node, const char *ref)
Definition: ui_parse.cpp:1406
#define EXTRADATA(node)
Atomic structure used to define most of the UI.
Definition: ui_nodes.h:80
void * UI_SWIG_TypeQuery(const char *name)
This function queries the SWIG type table for a type information structure. It is used in combination...
#define EXTRADATA_TYPE
void UI_GetNodeAbsPos(const uiNode_t *node, vec2_t pos)
Returns the absolute position of a node.
Definition: ui_node.cpp:514
struct uiAction_s * onRightClick
Definition: ui_nodes.h:136
intptr_t extraDataSize
Definition: ui_behaviour.h:54
Definition: scripts.h:50
node behaviour, how a node work
Definition: ui_behaviour.h:39
int contentAlign
Definition: ui_nodes.h:120
vec4_t color
Definition: ui_nodes.h:127
int height
Definition: r_image.h:64
struct uiAction_s * onWheel
Definition: ui_nodes.h:138
#define Vector2Copy(src, dest)
Definition: vector.h:52
vec_t vec2_t[2]
Definition: ufotypes.h:38
char * image
Definition: ui_nodes.h:123
#define V_CVAR_OR_STRING
Definition: ui_parse.h:69
uiBox_t box
Definition: ui_nodes.h:96
void UI_RegisterImageNode(uiBehaviour_t *behaviour)
Definition: scripts.h:55
vec_t vec4_t[4]
Definition: ufotypes.h:40