Mercurial > mplayer.hg
annotate libmenu/menu_list.c @ 17952:7ad7d20cfadc
H264: when fixed_fps is set the framerate is expressed in fields per second, so it must be halved
author | nicodvb |
---|---|
date | Sat, 25 Mar 2006 23:07:28 +0000 |
parents | 0afe12256464 |
children | 05b65e0b8d6f |
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 |
9 #include "img_format.h" | |
10 #include "mp_image.h" | |
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; |
8197 | 33 list_entry_t* m; |
34 | |
35 if(mpriv->count < 1) | |
36 return; | |
37 | |
38 if(h <= 0) h = mpi->height; | |
39 if(w <= 0) w = mpi->width; | |
40 dh = h - 2*mpriv->minb; | |
41 dw = w - 2*mpriv->minb; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
42 ptr_l = mpriv->ptr ? menu_text_length(mpriv->ptr) : 0; |
8197 | 43 // mpi is too small |
44 if(h - vo_font->height <= 0 || w - ptr_l <= 0 || dw <= 0 || dh <= 0) | |
45 return; | |
46 | |
47 th = menu_text_num_lines(mpriv->title,dw) * (mpriv->vspace + vo_font->height) + mpriv->vspace; | |
48 | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
49 // the selected item is hidden, find a visible one |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
50 if(mpriv->current->hide) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
51 // try the next |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
52 for(m = mpriv->current->next ; m ; m = m->next) |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
53 if(!m->hide) break; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
54 if(!m) // or the previous |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
55 for(m = mpriv->current->prev ; m ; m = m->prev) |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
56 if(!m->hide) break; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
57 if(m) mpriv->current = m; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
58 else ptr_l = 0; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
59 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
60 |
8197 | 61 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
|
62 int ll; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
63 if(m->hide) continue; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
64 ll = menu_text_length(m->txt); |
8197 | 65 if(ptr_l + ll > need_w) need_w = ptr_l + ll; |
66 if(m == mpriv->current) sidx = i; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
67 count++; |
8197 | 68 } |
69 if(need_w > dw) need_w = dw; | |
70 if(x > 0) | |
71 x += mpriv->minb; | |
72 if(y > 0) | |
73 y += mpriv->minb; | |
74 else | |
75 y = mpriv->minb; | |
76 | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
77 need_h = count * (mpriv->vspace + vo_font->height) - mpriv->vspace; |
8197 | 78 if( need_h + th > dh) { |
79 int start,end; | |
80 int maxl = (dh + mpriv->vspace - th) / (mpriv->vspace + vo_font->height); | |
81 if(maxl < 4) { | |
82 th = 0; | |
83 maxl = (dh + mpriv->vspace) / ( vo_font->height + mpriv->vspace); | |
84 } | |
85 // Too smoll | |
86 if(maxl < 1) return; | |
87 need_h = maxl*(mpriv->vspace + vo_font->height) - mpriv->vspace; | |
88 | |
89 start = sidx - (maxl/2); | |
90 if(start < 0) start = 0; | |
91 end = start + maxl; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
92 if(end > count) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
93 end = count; |
8197 | 94 if(end - start < maxl) |
95 start = end - maxl < 0 ? 0 : end - maxl; | |
96 } | |
97 m = mpriv->menu; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
98 for(i = 0 ; m->next && i < start ; ) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
99 if(!m->hide) i++; |
8197 | 100 m = m->next; |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
101 } |
8197 | 102 } else |
103 m = mpriv->menu; | |
104 | |
105 if(th > 0) { | |
106 menu_draw_text_full(mpi,mpriv->title, | |
107 x < 0 ? mpi->w / 2 : x, | |
108 dy+y,dw,0, | |
109 mpriv->vspace,1, | |
110 MENU_TEXT_TOP|MENU_TEXT_HCENTER, | |
111 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_HCENTER :MENU_TEXT_LEFT)); | |
112 dy += th; | |
113 } | |
114 | |
115 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
|
116 if(m->hide) continue; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
117 if(ptr_l > 0 && m == mpriv->current) |
8197 | 118 menu_draw_text_full(mpi,mpriv->ptr, |
119 x < 0 ? (mpi->w - need_w) / 2 + ptr_l : x, | |
120 dy+y,dw,dh - dy, | |
121 mpriv->vspace,0, | |
122 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_RIGHT :MENU_TEXT_LEFT) , | |
123 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_RIGHT :MENU_TEXT_LEFT)); | |
124 menu_draw_text_full(mpi,m->txt, | |
125 x < 0 ? (mpi->w - need_w) / 2 + ptr_l : x + ptr_l, | |
126 dy+y,dw-ptr_l,dh - dy, | |
127 mpriv->vspace,0, | |
128 MENU_TEXT_TOP|MENU_TEXT_LEFT, | |
129 MENU_TEXT_TOP|MENU_TEXT_LEFT); | |
130 dy += vo_font->height + mpriv->vspace; | |
131 } | |
132 | |
133 } | |
134 | |
135 void menu_list_read_cmd(menu_t* menu,int cmd) { | |
136 switch(cmd) { | |
137 case MENU_CMD_UP: | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
138 if(!mpriv->current->prev) { |
8197 | 139 for( ; mpriv->current->next != NULL ; mpriv->current = mpriv->current->next) |
140 /* NOTHING */; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
141 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
142 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
143 while(mpriv->current->prev) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
144 mpriv->current = mpriv->current->prev; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
145 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
146 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
147 break; |
8197 | 148 case MENU_CMD_DOWN: |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
149 if(!mpriv->current->next) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
150 mpriv->current = mpriv->menu; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
151 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
152 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
153 while(mpriv->current->next) { |
8197 | 154 mpriv->current = mpriv->current->next; |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
155 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
156 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
157 break; |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
158 case MENU_CMD_LEFT: |
8197 | 159 case MENU_CMD_CANCEL: |
160 menu->show = 0; | |
161 menu->cl = 1; | |
162 break; | |
163 } | |
164 } | |
165 | |
166 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
|
167 if(c < 256 && isalnum(c)) { |
8197 | 168 list_entry_t* e = mpriv->current; |
169 if(e->txt[0] == c) e = e->next; | |
170 for( ; e ; e = e->next) { | |
171 if(e->txt[0] == c) { | |
172 mpriv->current = e; | |
173 return; | |
174 } | |
175 } | |
176 for(e = mpriv->menu ; e ; e = e->next) { | |
177 if(e->txt[0] == c) { | |
178 mpriv->current = e; | |
179 return; | |
180 } | |
181 } | |
182 } else | |
183 menu_dflt_read_key(menu,c); | |
184 } | |
185 | |
186 void menu_list_read_key(menu_t* menu,int c,int jump_to) { | |
187 list_entry_t* m; | |
188 int i; | |
189 switch(c) { | |
190 case KEY_HOME: | |
191 mpriv->current = mpriv->menu; | |
192 break; | |
193 case KEY_END: | |
194 for(m = mpriv->current ; m && m->next ; m = m->next) | |
195 /**/; | |
196 if(m) | |
197 mpriv->current = m; | |
198 break; | |
199 case KEY_PAGE_UP: | |
200 for(i = 0, m = mpriv->current ; m && m->prev && i < 10 ; m = m->prev, i++) | |
201 /**/; | |
202 if(m) | |
203 mpriv->current = m; | |
204 break; | |
205 case KEY_PAGE_DOWN: | |
206 for(i = 0, m = mpriv->current ; m && m->next && i < 10 ; m = m->next, i++) | |
207 /**/; | |
208 if(m) | |
209 mpriv->current = m; | |
210 break; | |
211 default: | |
212 if(jump_to) | |
213 menu_list_jump_to_key(menu,c); | |
214 else | |
215 menu_dflt_read_key(menu,c); | |
216 } | |
217 } | |
218 | |
219 void menu_list_add_entry(menu_t* menu,list_entry_t* entry) { | |
220 list_entry_t* l; | |
221 mpriv->count++; | |
222 | |
223 if(mpriv->menu == NULL) { | |
224 mpriv->menu = mpriv->current = entry; | |
225 return; | |
226 } | |
227 | |
228 for(l = mpriv->menu ; l->next != NULL ; l = l->next) | |
229 /* NOP */; | |
230 l->next = entry; | |
231 entry->prev = l; | |
232 } | |
233 | |
234 void menu_list_init(menu_t* menu) { | |
235 if(!mpriv) | |
236 mpriv = calloc(1,sizeof(struct menu_priv_s)); | |
237 | |
238 } | |
239 | |
240 void menu_list_uninit(menu_t* menu,free_entry_t free_func) { | |
241 list_entry_t *i,*j; | |
242 | |
243 if(!free_func) free_func = (free_entry_t)free; | |
244 | |
245 for(i = mpriv->menu ; i != NULL ; ) { | |
246 j = i->next; | |
247 free_func(i); | |
248 i = j; | |
249 } | |
250 | |
251 mpriv->menu = mpriv->current = NULL; | |
252 | |
253 } | |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
254 |