Mercurial > mplayer.hg
annotate libmenu/menu_list.c @ 24290:ca7ee5c1b88d
Support for selecting language via packet 28.
Also allows to select default teletext language.
It will be used if language is not specified by network provider
via packet 28.
author | voroshil |
---|---|
date | Fri, 31 Aug 2007 16:53:27 +0000 |
parents | ac69ba536915 |
children | 476d4922566a |
rev | line source |
---|---|
8197 | 1 |
2 #include <stdlib.h> | |
3 #include <stdio.h> | |
4 #include <ctype.h> | |
8623
440301fef3fe
Added/reordered #includes to silence warnings about "implicit declaration".
rathann
parents:
8197
diff
changeset
|
5 #include <string.h> |
8197 | 6 |
16862 | 7 #include "config.h" |
8197 | 8 |
19431
ac69ba536915
Explicitly include libmpcodecs/img_format.h and libvo/fastmemcpy.h.
diego
parents:
18204
diff
changeset
|
9 #include "libmpcodecs/img_format.h" |
ac69ba536915
Explicitly include libmpcodecs/img_format.h and libvo/fastmemcpy.h.
diego
parents:
18204
diff
changeset
|
10 #include "libmpcodecs/mp_image.h" |
8197 | 11 |
12 #include "m_struct.h" | |
13 #include "menu.h" | |
14 | |
16862 | 15 #include "libvo/font_load.h" |
16 #include "osdep/keycodes.h" | |
8197 | 17 |
18 #define IMPL 1 | |
19 #include "menu_list.h" | |
20 | |
21 #define mpriv (menu->priv) | |
22 | |
23 void menu_list_draw(menu_t* menu,mp_image_t* mpi) { | |
24 int x = mpriv->x; | |
25 int y = mpriv->y; | |
26 int i; | |
27 int h = mpriv->h; | |
28 int w = mpriv->w; | |
29 int dh = 0,dw = 0; | |
30 int dy = 0; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
31 int need_h = 0,need_w = 0,ptr_l,sidx = 0; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
32 int th,count = 0; |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
33 int bg_w; |
8197 | 34 list_entry_t* m; |
35 | |
36 if(mpriv->count < 1) | |
37 return; | |
38 | |
39 if(h <= 0) h = mpi->height; | |
40 if(w <= 0) w = mpi->width; | |
41 dh = h - 2*mpriv->minb; | |
42 dw = w - 2*mpriv->minb; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
43 ptr_l = mpriv->ptr ? menu_text_length(mpriv->ptr) : 0; |
8197 | 44 // mpi is too small |
45 if(h - vo_font->height <= 0 || w - ptr_l <= 0 || dw <= 0 || dh <= 0) | |
46 return; | |
47 | |
48 th = menu_text_num_lines(mpriv->title,dw) * (mpriv->vspace + vo_font->height) + mpriv->vspace; | |
49 | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
50 // the selected item is hidden, find a visible one |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
51 if(mpriv->current->hide) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
52 // try the next |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
53 for(m = mpriv->current->next ; m ; m = m->next) |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
54 if(!m->hide) break; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
55 if(!m) // or the previous |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
56 for(m = mpriv->current->prev ; m ; m = m->prev) |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
57 if(!m->hide) break; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
58 if(m) mpriv->current = m; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
59 else ptr_l = 0; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
60 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
61 |
8197 | 62 for(i = 0, m = mpriv->menu ; m ; m = m->next, i++) { |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
63 int ll; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
64 if(m->hide) continue; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
65 ll = menu_text_length(m->txt); |
8197 | 66 if(ptr_l + ll > need_w) need_w = ptr_l + ll; |
67 if(m == mpriv->current) sidx = i; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
68 count++; |
8197 | 69 } |
70 if(need_w > dw) need_w = dw; | |
71 if(x > 0) | |
72 x += mpriv->minb; | |
73 if(y > 0) | |
74 y += mpriv->minb; | |
75 else | |
76 y = mpriv->minb; | |
77 | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
78 need_h = count * (mpriv->vspace + vo_font->height) - mpriv->vspace; |
8197 | 79 if( need_h + th > dh) { |
80 int start,end; | |
81 int maxl = (dh + mpriv->vspace - th) / (mpriv->vspace + vo_font->height); | |
82 if(maxl < 4) { | |
83 th = 0; | |
84 maxl = (dh + mpriv->vspace) / ( vo_font->height + mpriv->vspace); | |
85 } | |
86 // Too smoll | |
87 if(maxl < 1) return; | |
88 need_h = maxl*(mpriv->vspace + vo_font->height) - mpriv->vspace; | |
89 | |
90 start = sidx - (maxl/2); | |
91 if(start < 0) start = 0; | |
92 end = start + maxl; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
93 if(end > count) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
94 end = count; |
8197 | 95 if(end - start < maxl) |
96 start = end - maxl < 0 ? 0 : end - maxl; | |
97 } | |
98 m = mpriv->menu; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
99 for(i = 0 ; m->next && i < start ; ) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
100 if(!m->hide) i++; |
8197 | 101 m = m->next; |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
102 } |
8197 | 103 } else |
104 m = mpriv->menu; | |
105 | |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
106 bg_w = need_w+2*mpriv->minb; |
8197 | 107 if(th > 0) { |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
108 if(mpriv->title_bg >= 0) { |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
109 int tw,th2; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
110 menu_text_size(mpriv->title,dw,mpriv->vspace,1,&tw,&th2); |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
111 if(tw+2*mpriv->minb > bg_w) bg_w = tw+2*mpriv->minb; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
112 menu_draw_box(mpi,mpriv->title_bg,mpriv->title_bg_alpha, |
18204 | 113 x < 0 ? (mpi->w-bg_w)/2 : x-mpriv->minb,dy+y-mpriv->vspace/2,bg_w,th); |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
114 } |
8197 | 115 menu_draw_text_full(mpi,mpriv->title, |
116 x < 0 ? mpi->w / 2 : x, | |
117 dy+y,dw,0, | |
118 mpriv->vspace,1, | |
119 MENU_TEXT_TOP|MENU_TEXT_HCENTER, | |
120 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_HCENTER :MENU_TEXT_LEFT)); | |
121 dy += th; | |
122 } | |
123 | |
124 for( ; m != NULL && dy + vo_font->height < dh ; m = m->next ) { | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
125 if(m->hide) continue; |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
126 if(m == mpriv->current) { |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
127 if(mpriv->ptr_bg >= 0) |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
128 menu_draw_box(mpi,mpriv->ptr_bg,mpriv->ptr_bg_alpha, |
18204 | 129 x < 0 ? (mpi->w-bg_w)/2 : x-mpriv->minb,dy+y-mpriv->vspace/2, |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
130 bg_w,vo_font->height + mpriv->vspace); |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
131 if(ptr_l > 0) |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
132 menu_draw_text_full(mpi,mpriv->ptr, |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
133 x < 0 ? (mpi->w - need_w) / 2 + ptr_l : x, |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
134 dy+y,dw,dh - dy, |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
135 mpriv->vspace,0, |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
136 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_RIGHT :MENU_TEXT_LEFT) , |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
137 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_RIGHT :MENU_TEXT_LEFT)); |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
138 } else if(mpriv->item_bg >= 0) |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
139 menu_draw_box(mpi,mpriv->item_bg,mpriv->item_bg_alpha, |
18204 | 140 x < 0 ? (mpi->w-bg_w)/2 : x-mpriv->minb,dy+y-mpriv->vspace/2, |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
141 bg_w,vo_font->height + mpriv->vspace); |
8197 | 142 menu_draw_text_full(mpi,m->txt, |
143 x < 0 ? (mpi->w - need_w) / 2 + ptr_l : x + ptr_l, | |
144 dy+y,dw-ptr_l,dh - dy, | |
145 mpriv->vspace,0, | |
146 MENU_TEXT_TOP|MENU_TEXT_LEFT, | |
147 MENU_TEXT_TOP|MENU_TEXT_LEFT); | |
148 dy += vo_font->height + mpriv->vspace; | |
149 } | |
150 | |
151 } | |
152 | |
153 void menu_list_read_cmd(menu_t* menu,int cmd) { | |
154 switch(cmd) { | |
155 case MENU_CMD_UP: | |
17980 | 156 while(mpriv->current->prev) { |
157 mpriv->current = mpriv->current->prev; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
158 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
159 } |
17980 | 160 for( ; mpriv->current->next != NULL ; mpriv->current = mpriv->current->next) |
161 /* NOTHING */; | |
162 if(!mpriv->current->hide) return; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
163 while(mpriv->current->prev) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
164 mpriv->current = mpriv->current->prev; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
165 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
166 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
167 break; |
8197 | 168 case MENU_CMD_DOWN: |
17980 | 169 while(mpriv->current->next) { |
170 mpriv->current = mpriv->current->next; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
171 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
172 } |
17980 | 173 mpriv->current = mpriv->menu; |
174 if(!mpriv->current->hide) return; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
175 while(mpriv->current->next) { |
8197 | 176 mpriv->current = mpriv->current->next; |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
177 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
178 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
179 break; |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
180 case MENU_CMD_LEFT: |
8197 | 181 case MENU_CMD_CANCEL: |
182 menu->show = 0; | |
183 menu->cl = 1; | |
184 break; | |
185 } | |
186 } | |
187 | |
188 void menu_list_jump_to_key(menu_t* menu,int c) { | |
10935
ec8a1e6443d5
Fix long-known bug with handling 'down key' in lists.
lumag
parents:
9380
diff
changeset
|
189 if(c < 256 && isalnum(c)) { |
8197 | 190 list_entry_t* e = mpriv->current; |
191 if(e->txt[0] == c) e = e->next; | |
192 for( ; e ; e = e->next) { | |
193 if(e->txt[0] == c) { | |
194 mpriv->current = e; | |
195 return; | |
196 } | |
197 } | |
198 for(e = mpriv->menu ; e ; e = e->next) { | |
199 if(e->txt[0] == c) { | |
200 mpriv->current = e; | |
201 return; | |
202 } | |
203 } | |
204 } else | |
205 menu_dflt_read_key(menu,c); | |
206 } | |
207 | |
208 void menu_list_read_key(menu_t* menu,int c,int jump_to) { | |
209 list_entry_t* m; | |
210 int i; | |
211 switch(c) { | |
212 case KEY_HOME: | |
213 mpriv->current = mpriv->menu; | |
214 break; | |
215 case KEY_END: | |
216 for(m = mpriv->current ; m && m->next ; m = m->next) | |
217 /**/; | |
218 if(m) | |
219 mpriv->current = m; | |
220 break; | |
221 case KEY_PAGE_UP: | |
222 for(i = 0, m = mpriv->current ; m && m->prev && i < 10 ; m = m->prev, i++) | |
223 /**/; | |
224 if(m) | |
225 mpriv->current = m; | |
226 break; | |
227 case KEY_PAGE_DOWN: | |
228 for(i = 0, m = mpriv->current ; m && m->next && i < 10 ; m = m->next, i++) | |
229 /**/; | |
230 if(m) | |
231 mpriv->current = m; | |
232 break; | |
233 default: | |
234 if(jump_to) | |
235 menu_list_jump_to_key(menu,c); | |
236 else | |
237 menu_dflt_read_key(menu,c); | |
238 } | |
239 } | |
240 | |
241 void menu_list_add_entry(menu_t* menu,list_entry_t* entry) { | |
242 list_entry_t* l; | |
243 mpriv->count++; | |
244 | |
245 if(mpriv->menu == NULL) { | |
246 mpriv->menu = mpriv->current = entry; | |
247 return; | |
248 } | |
249 | |
250 for(l = mpriv->menu ; l->next != NULL ; l = l->next) | |
251 /* NOP */; | |
252 l->next = entry; | |
253 entry->prev = l; | |
254 } | |
255 | |
256 void menu_list_init(menu_t* menu) { | |
257 if(!mpriv) | |
258 mpriv = calloc(1,sizeof(struct menu_priv_s)); | |
259 | |
260 } | |
261 | |
262 void menu_list_uninit(menu_t* menu,free_entry_t free_func) { | |
263 list_entry_t *i,*j; | |
264 | |
265 if(!free_func) free_func = (free_entry_t)free; | |
266 | |
267 for(i = mpriv->menu ; i != NULL ; ) { | |
268 j = i->next; | |
269 free_func(i); | |
270 i = j; | |
271 } | |
272 | |
273 mpriv->menu = mpriv->current = NULL; | |
274 | |
275 } | |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
276 |