Mercurial > mplayer.hg
annotate gui/win32/widgetrender.c @ 34697:ac6b38cd0d45
Rename sub window video window.
It was a bad idea to name the video window "sub window" at the time
the GUI was written. The term "sub window" does make sense from the
programmer's point of view, but it doesn't make any sense at all from
the user's point of view, because the sub window simply is the window
where the video will be displayed.
Moreover, since the term "sub" is generally short for "subtitles",
the renaming makes the code much easier to understand.
author | ib |
---|---|
date | Sat, 03 Mar 2012 16:45:15 +0000 |
parents | 5a45efc630b8 |
children | 5b01e1e9d9ef |
rev | line source |
---|---|
23077 | 1 /* |
23079 | 2 * MPlayer GUI for Win32 |
3 * Copyright (C) 2003 Sascha Sommer <saschasommer@freenet.de> | |
4 * Copyright (C) 2006 Erik Augustson <erik_27can@yahoo.com> | |
5 * Copyright (C) 2006 Gianluigi Tiesi <sherpya@netfarm.it> | |
6 * | |
7 * This file is part of MPlayer. | |
8 * | |
9 * MPlayer is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * MPlayer is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
26457 | 19 * You should have received a copy of the GNU General Public License along |
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
23079 | 22 */ |
23077 | 23 |
24 #include <stdio.h> | |
25 #include <ctype.h> | |
26 #include <windows.h> | |
23091
52488bb09d90
Consistently use quotes instead of angled brackets in #include
diego
parents:
23079
diff
changeset
|
27 |
33564 | 28 #include "gui/util/bitmap.h" |
34175 | 29 #include "gui/util/string.h" |
26372
76413880bfad
Update include paths to account for build system changes.
diego
parents:
23091
diff
changeset
|
30 #include "gui/interface.h" |
23077 | 31 #include "gui.h" |
32 | |
33 #define MAX_LABELSIZE 250 | |
34 | |
35 static void render(int bitsperpixel, image *dst, image *src, int x, int y, int sx, int sy, int sw, int sh, int transparent) | |
36 { | |
37 int i; | |
38 int bpp = bitsperpixel / 8; | |
39 int offset = (dst->width * bpp * y) + (x * bpp); | |
40 int soffset = (src->width * bpp * sy) + (sx * bpp); | |
41 | |
42 for(i=0; i<sh; i++) | |
43 { | |
44 int c; | |
45 for(c=0; c < (sw * bpp); c += bpp) | |
46 { | |
47 if(bpp == 2) | |
48 { | |
49 if(!transparent || (((src->data + soffset + (i * src->width * bpp) + c)[0] != 0x1f) | |
50 && ((src->data + soffset + (i * src->width * bpp) + c)[1] != 0x7c))) | |
51 memcpy(dst->data + offset + c, src->data + soffset + (i * src->width * bpp) + c, bpp); | |
52 } | |
53 else if(bpp > 2) | |
54 { | |
33534 | 55 if(!transparent || !IS_TRANSPARENT(*((unsigned int *) (src->data + soffset + (i * src->width * bpp) + c)))) |
23077 | 56 memcpy(dst->data + offset + c, src->data + soffset + (i * src->width * bpp) + c, bpp); |
57 } | |
58 } | |
59 offset += (dst->width * bpp); | |
60 } | |
61 } | |
62 | |
63 static image *find_background(skin_t *skin, widget *item) | |
64 { | |
65 unsigned int i; | |
66 for (i=0; i < skin->windowcount; i++) | |
67 if(skin->windows[i]->type == item->window) | |
68 return skin->windows[i]->base->bitmap[0]; | |
69 return NULL; | |
70 } | |
71 | |
72 /******************************************************************/ | |
73 /* FONT related functions */ | |
74 /******************************************************************/ | |
75 | |
76 /* returns the pos of s2 inside s1 or -1 if s1 doesn't contain s2 */ | |
77 static int strpos(char *s1, const char* s2) | |
78 { | |
79 unsigned int i, x; | |
80 for (i=0; i < strlen(s1); i++) | |
81 { | |
82 if(s1[i] == s2[0]) | |
83 { | |
84 if(strlen(s1 + i) >= strlen(s2)) | |
85 { | |
86 for (x=0; x <strlen(s2); x++) | |
87 if(s1[i + x] != s2[x]) break; | |
88 if(x == strlen(s2)) return i; | |
89 } | |
90 } | |
91 } | |
92 return -1; | |
93 } | |
94 | |
95 /* replaces all occurences of what in dest with format */ | |
96 static void stringreplace(char *dest, const char *what, const char *format, ... ) | |
97 { | |
98 char tmp[MAX_LABELSIZE]; | |
99 int offset=0; | |
100 va_list va; | |
101 va_start(va, format); | |
102 vsnprintf(tmp, MAX_LABELSIZE, format, va); | |
103 va_end(va); | |
104 /* no search string == replace the entire string */ | |
105 if(!what) | |
106 { | |
107 memcpy(dest, tmp, strlen(tmp)); | |
108 dest[strlen(tmp)] = 0; | |
109 return; | |
110 } | |
111 while((offset = strpos(dest, what)) != -1) | |
112 { | |
113 memmove(dest + offset + strlen(tmp), dest + offset + strlen(what), strlen(dest + offset + strlen(what)) + 1); | |
114 memcpy(dest + offset, tmp, strlen(tmp)); | |
115 } | |
116 } | |
117 | |
118 /* replaces the chars with special meaning with the associated data from the player info struct */ | |
119 static char *generatetextfromlabel(widget *item) | |
120 { | |
121 char *text = malloc(MAX_LABELSIZE); | |
122 char tmp[MAX_LABELSIZE]; | |
123 unsigned int i; | |
124 if(!item) | |
125 { | |
126 free(text); | |
127 return NULL; | |
128 } | |
129 strcpy(text, item->label); | |
130 if(item->type == tySlabel) return text; | |
33897 | 131 stringreplace(text, "$1", "%.2i:%.2i:%.2i", guiInfo.ElapsedTime / 3600, |
132 (guiInfo.ElapsedTime / 60) % 60, guiInfo.ElapsedTime % 60); | |
133 stringreplace(text, "$2", "%.4i:%.2i", guiInfo.ElapsedTime / 60, guiInfo.ElapsedTime % 60); | |
134 stringreplace(text, "$3", "%.2i", guiInfo.ElapsedTime / 3600); | |
135 stringreplace(text, "$4", "%.2i", (guiInfo.ElapsedTime / 60) % 60); | |
136 stringreplace(text, "$5", "%.2i", guiInfo.ElapsedTime % 60); | |
137 stringreplace(text, "$6", "%.2i:%.2i:%.2i", guiInfo.RunningTime / 3600, | |
138 (guiInfo.RunningTime / 60) % 60, guiInfo.RunningTime % 60); | |
139 stringreplace(text, "$7", "%.4i:%.2i", guiInfo.RunningTime / 60, guiInfo.RunningTime % 60); | |
140 stringreplace(text, "$8", "%i:%.2i:%.2i", guiInfo.ElapsedTime / 3600, | |
141 (guiInfo.ElapsedTime / 60) % 60, guiInfo.ElapsedTime % 60); | |
33555 | 142 stringreplace(text, "$v", "%3.2f", guiInfo.Volume); |
143 stringreplace(text, "$V", "%3.1f", guiInfo.Volume); | |
144 stringreplace(text, "$b", "%3.2f", guiInfo.Balance); | |
145 stringreplace(text, "$B", "%3.1f", guiInfo.Balance); | |
146 stringreplace(text, "$t", "%.2i", guiInfo.Track); | |
34163 | 147 stringreplace(text, "$o", "%s", acp(TranslateFilename(0, tmp, sizeof(tmp)))); |
33901 | 148 stringreplace(text, "$x", "%i", guiInfo.VideoWidth); |
149 stringreplace(text, "$y", "%i", guiInfo.VideoHeight); | |
33555 | 150 stringreplace(text, "$C", "%s", guiInfo.sh_video ? codecname : ""); |
23077 | 151 stringreplace(text, "$$", "$"); |
152 | |
153 if(!strcmp(text, "$p") || !strcmp(text, "$s") || !strcmp(text, "$e")) | |
154 { | |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33564
diff
changeset
|
155 if(guiInfo.Playing == GUI_STOP) stringreplace(text, NULL, "s"); |
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33564
diff
changeset
|
156 else if(guiInfo.Playing == GUI_PLAY) stringreplace(text, NULL, "p"); |
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33564
diff
changeset
|
157 else if(guiInfo.Playing == GUI_PAUSE) stringreplace(text, NULL, "e"); |
23077 | 158 } |
159 | |
33646 | 160 if(guiInfo.AudioChannels == 0) stringreplace(text, "$a", "n"); |
161 else if(guiInfo.AudioChannels == 1) stringreplace(text, "$a", "m"); | |
23077 | 162 else stringreplace(text, "$a", "t"); |
163 | |
33555 | 164 if(guiInfo.StreamType == 0) |
23077 | 165 stringreplace(text, "$T", "f"); |
33555 | 166 else if(guiInfo.StreamType == STREAMTYPE_DVD || guiInfo.StreamType == STREAMTYPE_DVDNAV) |
23077 | 167 stringreplace(text, "$T", "d"); |
168 else stringreplace(text, "$T", "u"); | |
169 | |
34163 | 170 stringreplace(text, "$f", acp(TranslateFilename(1, tmp, sizeof(tmp)))); |
171 stringreplace(text, "$F", acp(TranslateFilename(2, tmp, sizeof(tmp)))); | |
23077 | 172 |
173 return text; | |
174 } | |
175 | |
176 /* cuts text to buflen scrolling from right to left */ | |
177 static void scrolltext(char *text, unsigned int buflen, float *value) | |
178 { | |
30702 | 179 char *buffer = malloc(buflen + 1); |
23077 | 180 unsigned int x,i; |
181 if(*value < buflen) x = 0; | |
182 else x = *value - buflen; | |
183 memset(buffer, ' ', buflen); | |
184 for (i = (*value>=buflen) ? 0 : buflen - *value; i<buflen; i++) | |
185 { | |
186 if(x < strlen(text)) | |
187 buffer[i] = text[x]; | |
188 x++; | |
189 } | |
190 buffer[buflen] = 0; | |
191 *value += 1.0f; | |
192 if(*value >= strlen(text) + buflen) *value = 0.0f; | |
193 strcpy(text, buffer); | |
194 free(buffer); | |
195 } | |
196 | |
197 /* updates all dlabels and slabels */ | |
198 void renderinfobox(skin_t *skin, window_priv_t *priv) | |
199 { | |
200 unsigned int i; | |
201 if (!priv) return; | |
202 | |
203 /* repaint the area behind the text*/ | |
204 /* we have to do this for all labels here, because they may overlap in buggy skins ;( */ | |
205 | |
206 for (i=0; i<skin->widgetcount; i++) | |
207 if((skin->widgets[i]->type == tyDlabel) || (skin->widgets[i]->type == tySlabel)) | |
208 { | |
209 if(skin->widgets[i]->window == priv->type) | |
210 render(skin->desktopbpp, | |
211 &priv->img, | |
212 find_background(skin, skin->widgets[i]), | |
213 skin->widgets[i]->x, | |
214 skin->widgets[i]->y, | |
215 skin->widgets[i]->x, | |
216 skin->widgets[i]->y, | |
217 skin->widgets[i]->length, | |
218 skin->widgets[i]->font->chars[0]->height, | |
219 1); | |
220 } | |
221 | |
222 /* load all slabels and dlabels */ | |
223 for (i=0; i<skin->widgetcount; i++) | |
224 { | |
225 widget *item = skin->widgets[i]; | |
226 if(item->window != priv->type) continue; | |
227 if((i == skin->widgetcount) || (item->type == tyDlabel) || (item->type == tySlabel)) | |
228 { | |
229 char *text = generatetextfromlabel(item); | |
230 unsigned int current, c; | |
231 int offset = 0; | |
232 unsigned int textlen; | |
233 if(!text) continue; | |
234 textlen = strlen(text); | |
235 | |
236 /* render(win, win->background, gui->skin->widgets[i]->x, gui->skin->widgets[i]->y, | |
237 gui->skin->widgets[i]->x, gui->skin->widgets[i]->y, | |
238 gui->skin->widgets[i]->length, gui->skin->widgets[i]->font->chars[0]->height,1); */ | |
239 | |
240 /* calculate text size */ | |
241 for (current=0; current<textlen; current++) | |
242 { | |
243 for (c=0; c<item->font->charcount; c++) | |
244 if(item->font->chars[c]->c == text[current]) | |
245 { | |
246 offset += item->font->chars[c]->width; | |
247 break; | |
248 } | |
249 } | |
250 | |
251 /* labels can be scrolled if they are to big */ | |
252 if((item->type == tyDlabel) && (item->length < offset)) | |
253 { | |
254 int tomuch = (offset - item->length) / (offset /textlen); | |
255 scrolltext(text, textlen - tomuch - 1, &skin->widgets[i]->value); | |
256 textlen = strlen(text); | |
257 } | |
258 | |
259 /* align the text */ | |
260 if(item->align == 1) | |
261 offset = (item->length-offset) / 2; | |
262 else if(item->align == 2) | |
263 offset = item->length-offset; | |
264 else | |
265 offset = 0; | |
266 | |
267 if(offset < 0) offset = 0; | |
268 | |
269 /* render the text */ | |
270 for (current=0; current<textlen; current++) | |
271 { | |
272 for (c=0; c<item->font->charcount; c++) | |
273 { | |
274 char_t *cchar = item->font->chars[c]; | |
275 if(cchar->c == *(text + current)) | |
276 { | |
277 render(skin->desktopbpp, | |
278 &priv->img, | |
279 item->font->image, | |
280 item->x + offset, | |
281 item->y, | |
282 cchar->x, | |
283 cchar->y, | |
284 (cchar->width + offset > item->length) ? item->length - offset : cchar->width, | |
285 cchar->height, | |
286 1); | |
287 offset += cchar->width; | |
288 break; | |
289 } | |
290 } | |
291 } | |
292 free(text); | |
293 } | |
294 } | |
295 } | |
296 | |
297 /******************************************************************/ | |
298 /* WIDGET related functions */ | |
299 /******************************************************************/ | |
300 | |
301 void renderwidget(skin_t *skin, image *dest, widget *item, int state) | |
302 { | |
303 image *img = NULL; | |
304 int height; | |
305 int y; | |
306 | |
307 if(!dest) return; | |
308 if((item->type == tyButton) || (item->type == tyHpotmeter) || (item->type == tyPotmeter)) | |
309 img = item->bitmap[0]; | |
310 | |
311 if(!img) return; | |
312 | |
313 y = item->y; | |
314 if(item->type == tyPotmeter) | |
315 { | |
316 height = img->height / item->phases; | |
317 y = height * (int)(item->value * item->phases / 100); | |
318 if(y > img->height-height) | |
319 y = img->height - height; | |
320 } | |
321 else | |
322 { | |
323 height = img->height / 3; | |
324 y = state * height; | |
325 } | |
326 | |
327 /* redraw background */ | |
328 if(item->type == tyButton) | |
329 render(skin->desktopbpp, dest, find_background(skin,item), item->x, item->y, item->x, item->y, img->width, height, 1); | |
330 | |
331 if((item->type == tyHpotmeter) || (item->type == tyPotmeter)) | |
332 { | |
333 /* repaint the area behind the slider */ | |
334 render(skin->desktopbpp, dest, find_background(skin, item), item->wx, item->wy, item->wx, item->wy, item->wwidth, item->height, 1); | |
335 item->x = item->value * (item->wwidth-item->width) / 100 + item->wx; | |
336 if((item->x + item->width) > (item->wx + item->wwidth)) | |
337 item->x = item->wx + item->wwidth - item->width; | |
338 if(item->x < item->wx) | |
339 item->x = item->wx; | |
340 /* workaround for blue */ | |
341 if(item->type == tyHpotmeter) | |
342 height = (item->height < img->height / 3) ? item->height : img->height / 3; | |
343 } | |
344 render(skin->desktopbpp, dest, img, item->x, item->y, 0, y, img->width, height, 1); | |
345 } |