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>
7 * This file is part of MPlayer.
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.
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.
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
28 #include "gui/interface.h"
31 extern char *codecname
;
32 #define MAX_LABELSIZE 250
34 static void render(int bitsperpixel
, image
*dst
, image
*src
, int x
, int y
, int sx
, int sy
, int sw
, int sh
, int transparent
)
37 int bpp
= bitsperpixel
/ 8;
38 int offset
= (dst
->width
* bpp
* y
) + (x
* bpp
);
39 int soffset
= (src
->width
* bpp
* sy
) + (sx
* bpp
);
44 for(c
=0; c
< (sw
* bpp
); c
+= bpp
)
48 if(!transparent
|| (((src
->data
+ soffset
+ (i
* src
->width
* bpp
) + c
)[0] != 0x1f)
49 && ((src
->data
+ soffset
+ (i
* src
->width
* bpp
) + c
)[1] != 0x7c)))
50 memcpy(dst
->data
+ offset
+ c
, src
->data
+ soffset
+ (i
* src
->width
* bpp
) + c
, bpp
);
54 if(!transparent
|| *((unsigned int *) (src
->data
+ soffset
+ (i
* src
->width
* bpp
) + c
)) != 0x00ff00ff)
55 memcpy(dst
->data
+ offset
+ c
, src
->data
+ soffset
+ (i
* src
->width
* bpp
) + c
, bpp
);
58 offset
+= (dst
->width
* bpp
);
62 static image
*find_background(skin_t
*skin
, widget
*item
)
65 for (i
=0; i
< skin
->windowcount
; i
++)
66 if(skin
->windows
[i
]->type
== item
->window
)
67 return skin
->windows
[i
]->base
->bitmap
[0];
71 /******************************************************************/
72 /* FONT related functions */
73 /******************************************************************/
75 /* returns the pos of s2 inside s1 or -1 if s1 doesn't contain s2 */
76 static int strpos(char *s1
, const char* s2
)
79 for (i
=0; i
< strlen(s1
); i
++)
83 if(strlen(s1
+ i
) >= strlen(s2
))
85 for (x
=0; x
<strlen(s2
); x
++)
86 if(s1
[i
+ x
] != s2
[x
]) break;
87 if(x
== strlen(s2
)) return i
;
94 /* replaces all occurences of what in dest with format */
95 static void stringreplace(char *dest
, const char *what
, const char *format
, ... )
97 char tmp
[MAX_LABELSIZE
];
100 va_start(va
, format
);
101 vsnprintf(tmp
, MAX_LABELSIZE
, format
, va
);
103 /* no search string == replace the entire string */
106 memcpy(dest
, tmp
, strlen(tmp
));
107 dest
[strlen(tmp
)] = 0;
110 while((offset
= strpos(dest
, what
)) != -1)
112 memmove(dest
+ offset
+ strlen(tmp
), dest
+ offset
+ strlen(what
), strlen(dest
+ offset
+ strlen(what
)) + 1);
113 memcpy(dest
+ offset
, tmp
, strlen(tmp
));
117 /* replaces the chars with special meaning with the associated data from the player info struct */
118 static char *generatetextfromlabel(widget
*item
)
120 char *text
= malloc(MAX_LABELSIZE
);
121 char tmp
[MAX_LABELSIZE
];
128 strcpy(text
, item
->label
);
129 if(item
->type
== tySlabel
) return text
;
130 stringreplace(text
, "$1", "%.2i:%.2i:%.2i", guiIntfStruct
.TimeSec
/ 3600,
131 (guiIntfStruct
.TimeSec
/ 60) % 60, guiIntfStruct
.TimeSec
% 60);
132 stringreplace(text
, "$2", "%.4i:%.2i", guiIntfStruct
.TimeSec
/ 60, guiIntfStruct
.TimeSec
% 60);
133 stringreplace(text
, "$3", "%.2i", guiIntfStruct
.TimeSec
/ 3600);
134 stringreplace(text
, "$4", "%.2i", (guiIntfStruct
.TimeSec
/ 60) % 60);
135 stringreplace(text
, "$5", "%.2i", guiIntfStruct
.TimeSec
% 60);
136 stringreplace(text
, "$6", "%.2i:%.2i:%.2i", guiIntfStruct
.LengthInSec
/ 3600,
137 (guiIntfStruct
.LengthInSec
/ 60) % 60, guiIntfStruct
.LengthInSec
% 60);
138 stringreplace(text
, "$7", "%.4i:%.2i", guiIntfStruct
.LengthInSec
/ 60, guiIntfStruct
.LengthInSec
% 60);
139 stringreplace(text
, "$8", "%i:%.2i:%.2i", guiIntfStruct
.TimeSec
/ 3600,
140 (guiIntfStruct
.TimeSec
/ 60) % 60, guiIntfStruct
.TimeSec
% 60);
141 stringreplace(text
, "$v", "%3.2f", guiIntfStruct
.Volume
);
142 stringreplace(text
, "$V", "%3.1f", guiIntfStruct
.Volume
);
143 stringreplace(text
, "$b", "%3.2f", guiIntfStruct
.Balance
);
144 stringreplace(text
, "$B", "%3.1f", guiIntfStruct
.Balance
);
145 stringreplace(text
, "$t", "%.2i", guiIntfStruct
.Track
);
146 stringreplace(text
, "$o", "%s", guiIntfStruct
.Filename
);
147 stringreplace(text
, "$x", "%i", guiIntfStruct
.MovieWidth
);
148 stringreplace(text
, "$y", "%i", guiIntfStruct
.MovieHeight
);
149 stringreplace(text
, "$C", "%s", guiIntfStruct
.sh_video
? codecname
: "");
150 stringreplace(text
, "$$", "$");
152 if(!strcmp(text
, "$p") || !strcmp(text
, "$s") || !strcmp(text
, "$e"))
154 if(guiIntfStruct
.Playing
== 0) stringreplace(text
, NULL
, "s");
155 else if(guiIntfStruct
.Playing
== 1) stringreplace(text
, NULL
, "p");
156 else if(guiIntfStruct
.Playing
== 2) stringreplace(text
, NULL
, "e");
159 if(guiIntfStruct
.AudioType
== 0) stringreplace(text
, "$a", "n");
160 else if(guiIntfStruct
.AudioType
== 1) stringreplace(text
, "$a", "m");
161 else stringreplace(text
, "$a", "t");
163 if(guiIntfStruct
.StreamType
== 0)
164 stringreplace(text
, "$T", "f");
165 #ifdef CONFIG_DVDREAD
166 else if(guiIntfStruct
.StreamType
== STREAMTYPE_DVD
|| guiIntfStruct
.StreamType
== STREAMTYPE_DVDNAV
)
167 stringreplace(text
, "$T", "d");
169 else stringreplace(text
, "$T", "u");
171 if(guiIntfStruct
.Filename
)
173 for (i
=0; i
<strlen(guiIntfStruct
.Filename
); i
++)
174 tmp
[i
] = tolower(guiIntfStruct
.Filename
[i
]);
175 stringreplace(text
, "$f", tmp
);
177 for (i
=0; i
<strlen(guiIntfStruct
.Filename
); i
++)
178 tmp
[i
] = toupper(guiIntfStruct
.Filename
[i
]);
179 stringreplace(text
, "$F", tmp
);
185 /* cuts text to buflen scrolling from right to left */
186 static void scrolltext(char *text
, unsigned int buflen
, float *value
)
188 char *buffer
= (char *) malloc(buflen
+ 1);
190 if(*value
< buflen
) x
= 0;
191 else x
= *value
- buflen
;
192 memset(buffer
, ' ', buflen
);
193 for (i
= (*value
>=buflen
) ? 0 : buflen
- *value
; i
<buflen
; i
++)
201 if(*value
>= strlen(text
) + buflen
) *value
= 0.0f
;
202 strcpy(text
, buffer
);
206 /* updates all dlabels and slabels */
207 void renderinfobox(skin_t
*skin
, window_priv_t
*priv
)
212 /* repaint the area behind the text*/
213 /* we have to do this for all labels here, because they may overlap in buggy skins ;( */
215 for (i
=0; i
<skin
->widgetcount
; i
++)
216 if((skin
->widgets
[i
]->type
== tyDlabel
) || (skin
->widgets
[i
]->type
== tySlabel
))
218 if(skin
->widgets
[i
]->window
== priv
->type
)
219 render(skin
->desktopbpp
,
221 find_background(skin
, skin
->widgets
[i
]),
226 skin
->widgets
[i
]->length
,
227 skin
->widgets
[i
]->font
->chars
[0]->height
,
231 /* load all slabels and dlabels */
232 for (i
=0; i
<skin
->widgetcount
; i
++)
234 widget
*item
= skin
->widgets
[i
];
235 if(item
->window
!= priv
->type
) continue;
236 if((i
== skin
->widgetcount
) || (item
->type
== tyDlabel
) || (item
->type
== tySlabel
))
238 char *text
= generatetextfromlabel(item
);
239 unsigned int current
, c
;
241 unsigned int textlen
;
243 textlen
= strlen(text
);
245 /* render(win, win->background, gui->skin->widgets[i]->x, gui->skin->widgets[i]->y,
246 gui->skin->widgets[i]->x, gui->skin->widgets[i]->y,
247 gui->skin->widgets[i]->length, gui->skin->widgets[i]->font->chars[0]->height,1); */
249 /* calculate text size */
250 for (current
=0; current
<textlen
; current
++)
252 for (c
=0; c
<item
->font
->charcount
; c
++)
253 if(item
->font
->chars
[c
]->c
== text
[current
])
255 offset
+= item
->font
->chars
[c
]->width
;
260 /* labels can be scrolled if they are to big */
261 if((item
->type
== tyDlabel
) && (item
->length
< offset
))
263 int tomuch
= (offset
- item
->length
) / (offset
/textlen
);
264 scrolltext(text
, textlen
- tomuch
- 1, &skin
->widgets
[i
]->value
);
265 textlen
= strlen(text
);
270 offset
= (item
->length
-offset
) / 2;
271 else if(item
->align
== 2)
272 offset
= item
->length
-offset
;
276 if(offset
< 0) offset
= 0;
278 /* render the text */
279 for (current
=0; current
<textlen
; current
++)
281 for (c
=0; c
<item
->font
->charcount
; c
++)
283 char_t
*cchar
= item
->font
->chars
[c
];
284 if(cchar
->c
== *(text
+ current
))
286 render(skin
->desktopbpp
,
293 (cchar
->width
+ offset
> item
->length
) ? item
->length
- offset
: cchar
->width
,
296 offset
+= cchar
->width
;
306 /******************************************************************/
307 /* WIDGET related functions */
308 /******************************************************************/
310 void renderwidget(skin_t
*skin
, image
*dest
, widget
*item
, int state
)
317 if((item
->type
== tyButton
) || (item
->type
== tyHpotmeter
) || (item
->type
== tyPotmeter
))
318 img
= item
->bitmap
[0];
323 if(item
->type
== tyPotmeter
)
325 height
= img
->height
/ item
->phases
;
326 y
= height
* (int)(item
->value
* item
->phases
/ 100);
327 if(y
> img
->height
-height
)
328 y
= img
->height
- height
;
332 height
= img
->height
/ 3;
336 /* redraw background */
337 if(item
->type
== tyButton
)
338 render(skin
->desktopbpp
, dest
, find_background(skin
,item
), item
->x
, item
->y
, item
->x
, item
->y
, img
->width
, height
, 1);
340 if((item
->type
== tyHpotmeter
) || (item
->type
== tyPotmeter
))
342 /* repaint the area behind the slider */
343 render(skin
->desktopbpp
, dest
, find_background(skin
, item
), item
->wx
, item
->wy
, item
->wx
, item
->wy
, item
->wwidth
, item
->height
, 1);
344 item
->x
= item
->value
* (item
->wwidth
-item
->width
) / 100 + item
->wx
;
345 if((item
->x
+ item
->width
) > (item
->wx
+ item
->wwidth
))
346 item
->x
= item
->wx
+ item
->wwidth
- item
->width
;
347 if(item
->x
< item
->wx
)
349 /* workaround for blue */
350 if(item
->type
== tyHpotmeter
)
351 height
= (item
->height
< img
->height
/ 3) ? item
->height
: img
->height
/ 3;
353 render(skin
->desktopbpp
, dest
, img
, item
->x
, item
->y
, 0, y
, img
->width
, height
, 1);