1 #ifndef UI_H
2 #define UI_H
3 
4 #include "sized_string.h"
5 
6 #include "../langs/i18n_decls.h"
7 #include "settings.h"
8 
9 #include <stdbool.h>
10 #include <stdint.h>
11 
12 typedef struct native_image NATIVE_IMAGE;
13 typedef struct panel PANEL;
14 typedef struct scrollable SCROLLABLE;
15 
16 #define S(x) (ui_gettext(settings.language, (STR_##x))->str)
17 #define SLEN(x) (ui_gettext(settings.language, (STR_##x))->length)
18 #define SPTR(x) (ui_gettext(settings.language, (STR_##x)))
19 
20 /* if UTOX_STR_WIDTH, is giving you a bad size you've probably changed setfont() from the string you're trying to get
21  * the size of. Either store the size before changing, or swap it -> run UTOX_STR_WIDTH() -> swap back. */
22 #define UTOX_STR_WIDTH(x) (textwidth((ui_gettext(settings.language, (STR_##x))->str), \
23                           (ui_gettext(settings.language, (STR_##x))->length)))
24 #define SPTRFORLANG(l, x) (ui_gettext((l), (x)))
25 
26 // TODO: Create ui_native headers or something.
27 // This is hard to read. I know. I'm sorry.
28 // This is to stop a circular dependency between svg.c and xlib/main.h.
29 #if defined __WIN32__ || defined _WIN32 || defined __CYGWIN__
30 // Windows supplies its own RGB function.
31 #include <windows.h>  // TODO, don't do this
32 #elif defined __ANDROID__
33 #define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16))
34 #elif defined __OBJC__
35 // xlib and cocoa use the same format for this, but I left both cases here
36 // in case I want to use this #ifdef construct elsewhere.
37 #define RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
38 #else
39 #define RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
40 #endif
41 
42 // Mouse stuff
43 enum {
44     CURSOR_NONE,
45     CURSOR_TEXT,
46     CURSOR_HAND,
47     CURSOR_SELECT,
48     CURSOR_ZOOM_IN,
49     CURSOR_ZOOM_OUT,
50 };
51 
52 extern struct utox_mouse {
53     int x, y;
54 } mouse;
55 
56 extern uint8_t cursor;
57 extern bool mdown;
58 
59 enum {
60     FONT_TEXT,
61     FONT_TITLE,
62     FONT_SELF_NAME,
63     FONT_STATUS,
64     FONT_LIST_NAME,
65     FONT_MISC,
66 
67     FONT_END,
68 };
69 
70 typedef enum {
71     MAIN_STYLE,      // white style, used in right side
72     AUXILIARY_STYLE, // gray style, used on friends side
73 } UI_ELEMENT_STYLE;
74 
75 typedef struct maybe_i18nal_string {
76     STRING        plain;
77     UTOX_I18N_STR i18nal;
78 } MAYBE_I18NAL_STRING;
79 
80 void maybe_i18nal_string_set_plain(MAYBE_I18NAL_STRING *, char *str, uint16_t length);
81 void    maybe_i18nal_string_set_i18nal(MAYBE_I18NAL_STRING *, UTOX_I18N_STR);
82 STRING *maybe_i18nal_string_get(MAYBE_I18NAL_STRING *);
83 bool    maybe_i18nal_string_is_valid(MAYBE_I18NAL_STRING *);
84 
85 /* draws an image in the style of an avatar at within rect (x,y,targetwidth,targetheight)
86  * this means: resize the image while keeping proportion so that the dimension(width or height) that has the smallest
87  * rational difference to the targetdimension becomes exactly targetdimension, then
88  * crop the image so it fits in the (x,y,targetwidth,targetheight) rect, and
89  * set the position if a dimension is too large so it's centered on the middle
90  *
91  * first argument is the image to draw, width and height are the width and height of the input image
92  */
93 void draw_avatar_image(NATIVE_IMAGE *image, int x, int y, uint32_t width, uint32_t height, uint32_t targetwidth,
94                        uint32_t targetheight);
95 
96 void ui_set_scale(uint8_t scale);
97 void ui_rescale(uint8_t scale);
98 void ui_size(int width, int height);
99 
100 void ui_mouseleave(void);
101 
102 void panel_draw(PANEL *p, int x, int y, int width, int height);
103 
104 bool panel_mmove(PANEL *p, int x, int y, int width, int height, int mx, int my, int dx, int dy);
105 void panel_mdown(PANEL *p);
106 bool panel_dclick(PANEL *p, bool triclick);
107 bool panel_mright(PANEL *p);
108 bool panel_mwheel(PANEL *p, int x, int y, int width, int height, double d, bool smooth);
109 bool panel_mup(PANEL *p);
110 bool panel_mleave(PANEL *p);
111 
112 extern char search_data[1024]; // TODO this is NOT where this belongs
113 
114 extern double ui_scale;
115 
116 #define SCALE(x)      ((int)(((double)x) * (ui_scale / 10.0)))
117 #define SCALE_DIV(x) (((int)(((double)x) * (ui_scale / 10.0))) ?: 1)
118 
119 #define UI_FSCALE(x)      (((double)x) * (ui_scale / 10.0))
120 #define UI_FSCALE_DIV(x) ((((double)x) * (ui_scale / 10.0)) ?: 1)
121 
122 #define UN_SCALE(x) (((int)(((double)x) / (ui_scale / 10.0))))
123 
124 #define drawstr(x, y, i) drawtext(x, y, S(i), SLEN(i))
125 #define drawstr_getwidth(x, y, str) drawtext_getwidth(x, y, (char *)str, sizeof(str) - 1)
126 #define strwidth(x) textwidth((char *)x, sizeof(x) - 1)
127 
128 /* colors */
129 #define GRAY(x) (((x) << 16) | ((x) << 8) | (x))
130 #define BLACK 0
131 #define C_RED RGB(200, 78, 78)
132 #define C_SCROLL GRAY(209)
133 
134 /* These are the new defines to help align UI elements, the new ones must use a _top/_bottom/ or _left/_right or
135  * _width/_height postfix, and should be used to replace the originals whenever possible.
136  * If you're able to replace an original, replace all occurrences, and delete the define. */
137 
138 
139 /* User badge */
140 #define SIDEBAR_PADDING 6
141 #define SIDEBAR_AVATAR_TOP 5
142 #define SIDEBAR_AVATAR_LEFT 5
143 #define SIDEBAR_AVATAR_WIDTH 10
144 #define SIDEBAR_AVATAR_HEIGHT 10
145 #define SIDEBAR_NAME_TOP 10
146 #define SIDEBAR_NAME_LEFT 50
147 #define SIDEBAR_NAME_WIDTH 145
148 #define SIDEBAR_NAME_HEIGHT 18
149 #define SIDEBAR_STATUSMSG_TOP 28
150 #define SIDEBAR_STATUSMSG_LEFT 50
151 #define SIDEBAR_STATUSMSG_WIDTH 145
152 #define SIDEBAR_STATUSMSG_HEIGHT 18
153 
154 
155 /* Sidebar buttons and settings */
156 #define SIDEBAR_FILTER_FRIENDS_TOP 50
157 #define SIDEBAR_FILTER_FRIENDS_LEFT 5
158 #define SIDEBAR_FILTER_FRIENDS_WIDTH 168
159 #define SIDEBAR_FILTER_FRIENDS_HEIGHT 16
160 
161 /* Roster defines */
162 #define ROSTER_LEFT 16
163 #define ROSTER_BOTTOM -30
164 #define ROSTER_BOX_HEIGHT 50
165 #define ROSTER_AVATAR_TOP 5
166 #define ROSTER_AVATAR_LEFT 10
167 
168 #define ROSTER_NAME_TOP 12
169 
170 /* Sidebar Lower search box and setting button */
171 #define SIDEBAR_SEARCH_TOP -30
172 #define SIDEBAR_SEARCH_LEFT 0
173 #define SIDEBAR_SEARCH_WIDTH 199
174 #define SIDEBAR_SEARCH_HEIGHT 30
175 
176 #define SIDEBAR_BUTTON_TOP -30
177 #define SIDEBAR_BUTTON_LEFT 200
178 #define SIDEBAR_BUTTON_WIDTH 30
179 #define SIDEBAR_BUTTON_HEIGHT 30
180 
181 /* Main box/Chat box size settings */
182 #define CHAT_BOX_TOP -52 /* size of the bottom message box */
183 #define MAIN_TOP_FRAME_THIN 30
184 #define MAIN_TOP_FRAME_THICK 60
185 
186 /* Global UI size settings... */
187 #define SCROLL_WIDTH 8 // must be divisible by 2
188 #define FILE_TRANSFER_BOX_HEIGHT 28
189 
190 
191 /* Main panel defines */
192 #define MAIN_TOP 60
193 
194 /* Legacy defines, instead of using these, you should replace them with something more descriptive */
195 #define LIST_Y2 86
196 #define LIST_BUTTON_Y -26
197 #define MESSAGES_SPACING 4
198 #define MESSAGES_X 94
199 #define TIME_WIDTH 45
200 #define TIME_WIDTH_LONG 60
201 #define NAME_OFFSET 14
202 
203 #endif
204