UFO: Alien Invasion
Loading...
Searching...
No Matches
ui_node_image.cpp
Go to the documentation of this file.
1
18
19/*
20Copyright (C) 2002-2025 UFO: Alien Invasion.
21
22This program is free software; you can redistribute it and/or
23modify it under the terms of the GNU General Public License
24as published by the Free Software Foundation; either version 2
25of the License, or (at your option) any later version.
26
27This program is distributed in the hope that it will be useful,
28but WITHOUT ANY WARRANTY; without even the implied warranty of
29MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30
31See the GNU General Public License for more details.
32
33You should have received a copy of the GNU General Public License
34along with this program; if not, write to the Free Software
35Foundation, 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"
45
46#include "../../client.h"
47
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
90static 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}
void R_Color(const vec4_t rgba)
Change the color to given value.
Definition r_state.cpp:1011
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).
void draw(uiNode_t *node) override
Draws the image node.
Primary header for client.
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition common.cpp:440
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
#define ERR_FATAL
Definition common.h:210
#define DEBUG_CLIENT
Definition defines.h:59
voidpf void uLong size
Definition ioapi.h:42
align_t
We need this here for checking the boundaries from script values.
Definition scripts.h:89
@ V_BOOL
Definition scripts.h:50
@ V_POS
Definition scripts.h:55
Header for lua script functions.
bool Q_strnull(const char *string)
Definition shared.h:138
#define OBJZERO(obj)
Definition shared.h:178
int height
Definition r_image.h:64
int width
Definition r_image.h:64
node behaviour, how a node work
const char * name
void * lua_SWIG_typeinfo
UINodePtr manager
intptr_t extraDataSize
vec2_t size
Definition ui_nodes.h:52
Atomic structure used to define most of the UI.
Definition ui_nodes.h:80
struct uiAction_s * onWheelDown
Definition ui_nodes.h:142
struct uiAction_s * onMouseLeave
Definition ui_nodes.h:140
int contentAlign
Definition ui_nodes.h:120
vec4_t color
Definition ui_nodes.h:127
struct uiAction_s * onWheel
Definition ui_nodes.h:138
struct uiAction_s * onMiddleClick
Definition ui_nodes.h:137
uiBox_t box
Definition ui_nodes.h:96
int padding
Definition ui_nodes.h:109
struct uiAction_s * onClick
Definition ui_nodes.h:135
struct uiAction_s * onRightClick
Definition ui_nodes.h:136
char * image
Definition ui_nodes.h:123
struct uiAction_s * onMouseEnter
Definition ui_nodes.h:139
struct uiAction_s * onWheelUp
Definition ui_nodes.h:141
bool state
Definition ui_nodes.h:106
vec_t vec4_t[4]
Definition ufotypes.h:40
vec_t vec2_t[2]
Definition ufotypes.h:38
#define UI_RegisterNodeProperty(BEHAVIOUR, NAME, TYPE, OBJECTTYPE, ATTRIBUTE)
Initialize a property.
#define UI_RegisterExtradataNodeProperty(BEHAVIOUR, NAME, TYPE, EXTRADATATYPE, ATTRIBUTE)
Initialize a property from extradata of node.
void * UI_SWIG_TypeQuery(const char *name)
This function queries the SWIG type table for a type information structure. It is used in combination...
void UI_GetNodeAbsPos(const uiNode_t *node, vec2_t pos)
Returns the absolute position of a node.
Definition ui_node.cpp:526
SharedPtr< uiNode > UINodePtr
#define EXTRADATA_TYPE
#define EXTRADATA(node)
static const vec3_t scale
void UI_RegisterImageNode(uiBehaviour_t *behaviour)
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.
const char * UI_GetPath(const uiNode_t *node)
Return a path from a window to a node.
Definition ui_nodes.cpp:174
const char * UI_GetReferenceString(const uiNode_t *const node, const char *ref)
#define V_CVAR_OR_STRING
Definition ui_parse.h:69
const struct image_s * UI_LoadImage(const char *name)
Searches for an image in the image array.
Definition ui_render.cpp:91
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.
#define Vector2Set(v, x, y)
Definition vector.h:61
#define Vector2Empty(a)
Definition vector.h:74
#define VectorScale(in, scale, out)
Definition vector.h:79
#define Vector2Copy(src, dest)
Definition vector.h:52