Mercurial > mplayer.hg
annotate libmenu/menu_list.c @ 25227:75837c33484b
Mark more m_option_t uses as const
author | reimar |
---|---|
date | Sun, 02 Dec 2007 15:46:44 +0000 |
parents | 476d4922566a |
children | 96d0992c7920 |
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; | |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
81 mpriv->disp_lines = (dh + mpriv->vspace - th) / (mpriv->vspace + vo_font->height); |
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
82 if(mpriv->disp_lines < 4) { |
8197 | 83 th = 0; |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
84 mpriv->disp_lines = (dh + mpriv->vspace) / ( vo_font->height + mpriv->vspace); |
8197 | 85 } |
86 // Too smoll | |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
87 if(mpriv->disp_lines < 1) return; |
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
88 need_h = mpriv->disp_lines*(mpriv->vspace + vo_font->height) - mpriv->vspace; |
8197 | 89 |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
90 start = sidx - (mpriv->disp_lines/2); |
8197 | 91 if(start < 0) start = 0; |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
92 end = start + mpriv->disp_lines; |
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; |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
95 if(end - start < mpriv->disp_lines) |
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
96 start = end - mpriv->disp_lines < 0 ? 0 : end - mpriv->disp_lines; |
8197 | 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 } |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
103 } else { |
8197 | 104 m = mpriv->menu; |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
105 mpriv->disp_lines = count; |
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
106 } |
8197 | 107 |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
108 bg_w = need_w+2*mpriv->minb; |
8197 | 109 if(th > 0) { |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
110 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
|
111 int tw,th2; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
112 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
|
113 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
|
114 menu_draw_box(mpi,mpriv->title_bg,mpriv->title_bg_alpha, |
18204 | 115 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
|
116 } |
8197 | 117 menu_draw_text_full(mpi,mpriv->title, |
118 x < 0 ? mpi->w / 2 : x, | |
119 dy+y,dw,0, | |
120 mpriv->vspace,1, | |
121 MENU_TEXT_TOP|MENU_TEXT_HCENTER, | |
122 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_HCENTER :MENU_TEXT_LEFT)); | |
123 dy += th; | |
124 } | |
125 | |
126 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
|
127 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
|
128 if(m == mpriv->current) { |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
129 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
|
130 menu_draw_box(mpi,mpriv->ptr_bg,mpriv->ptr_bg_alpha, |
18204 | 131 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
|
132 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
|
133 if(ptr_l > 0) |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
134 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
|
135 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
|
136 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
|
137 mpriv->vspace,0, |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17980
diff
changeset
|
138 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
|
139 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
|
140 } 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
|
141 menu_draw_box(mpi,mpriv->item_bg,mpriv->item_bg_alpha, |
18204 | 142 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
|
143 bg_w,vo_font->height + mpriv->vspace); |
8197 | 144 menu_draw_text_full(mpi,m->txt, |
145 x < 0 ? (mpi->w - need_w) / 2 + ptr_l : x + ptr_l, | |
146 dy+y,dw-ptr_l,dh - dy, | |
147 mpriv->vspace,0, | |
148 MENU_TEXT_TOP|MENU_TEXT_LEFT, | |
149 MENU_TEXT_TOP|MENU_TEXT_LEFT); | |
150 dy += vo_font->height + mpriv->vspace; | |
151 } | |
152 | |
153 } | |
154 | |
155 void menu_list_read_cmd(menu_t* menu,int cmd) { | |
156 switch(cmd) { | |
157 case MENU_CMD_UP: | |
17980 | 158 while(mpriv->current->prev) { |
159 mpriv->current = mpriv->current->prev; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
160 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
161 } |
17980 | 162 for( ; mpriv->current->next != NULL ; mpriv->current = mpriv->current->next) |
163 /* NOTHING */; | |
164 if(!mpriv->current->hide) return; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
165 while(mpriv->current->prev) { |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
166 mpriv->current = mpriv->current->prev; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
167 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
168 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
169 break; |
8197 | 170 case MENU_CMD_DOWN: |
17980 | 171 while(mpriv->current->next) { |
172 mpriv->current = mpriv->current->next; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
173 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
174 } |
17980 | 175 mpriv->current = mpriv->menu; |
176 if(!mpriv->current->hide) return; | |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
177 while(mpriv->current->next) { |
8197 | 178 mpriv->current = mpriv->current->next; |
17946
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
179 if(!mpriv->current->hide) return; |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
180 } |
0afe12256464
Allow hiding list elements and disableing the pointer.
albeu
parents:
17945
diff
changeset
|
181 break; |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
182 case MENU_CMD_LEFT: |
8197 | 183 case MENU_CMD_CANCEL: |
184 menu->show = 0; | |
185 menu->cl = 1; | |
186 break; | |
187 } | |
188 } | |
189 | |
190 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
|
191 if(c < 256 && isalnum(c)) { |
8197 | 192 list_entry_t* e = mpriv->current; |
193 if(e->txt[0] == c) e = e->next; | |
194 for( ; e ; e = e->next) { | |
195 if(e->txt[0] == c) { | |
196 mpriv->current = e; | |
197 return; | |
198 } | |
199 } | |
200 for(e = mpriv->menu ; e ; e = e->next) { | |
201 if(e->txt[0] == c) { | |
202 mpriv->current = e; | |
203 return; | |
204 } | |
205 } | |
206 } else | |
207 menu_dflt_read_key(menu,c); | |
208 } | |
209 | |
210 void menu_list_read_key(menu_t* menu,int c,int jump_to) { | |
211 list_entry_t* m; | |
212 int i; | |
213 switch(c) { | |
214 case KEY_HOME: | |
215 mpriv->current = mpriv->menu; | |
216 break; | |
217 case KEY_END: | |
218 for(m = mpriv->current ; m && m->next ; m = m->next) | |
219 /**/; | |
220 if(m) | |
221 mpriv->current = m; | |
222 break; | |
223 case KEY_PAGE_UP: | |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
224 for(i = 0, m = mpriv->current ; m && m->prev && i < mpriv->disp_lines ; m = m->prev, i++) |
8197 | 225 /**/; |
226 if(m) | |
227 mpriv->current = m; | |
228 break; | |
229 case KEY_PAGE_DOWN: | |
24979
476d4922566a
Make page up and down with proper page size instead of always 10 rows.
ulion
parents:
19431
diff
changeset
|
230 for(i = 0, m = mpriv->current ; m && m->next && i < mpriv->disp_lines ; m = m->next, i++) |
8197 | 231 /**/; |
232 if(m) | |
233 mpriv->current = m; | |
234 break; | |
235 default: | |
236 if(jump_to) | |
237 menu_list_jump_to_key(menu,c); | |
238 else | |
239 menu_dflt_read_key(menu,c); | |
240 } | |
241 } | |
242 | |
243 void menu_list_add_entry(menu_t* menu,list_entry_t* entry) { | |
244 list_entry_t* l; | |
245 mpriv->count++; | |
246 | |
247 if(mpriv->menu == NULL) { | |
248 mpriv->menu = mpriv->current = entry; | |
249 return; | |
250 } | |
251 | |
252 for(l = mpriv->menu ; l->next != NULL ; l = l->next) | |
253 /* NOP */; | |
254 l->next = entry; | |
255 entry->prev = l; | |
256 } | |
257 | |
258 void menu_list_init(menu_t* menu) { | |
259 if(!mpriv) | |
260 mpriv = calloc(1,sizeof(struct menu_priv_s)); | |
261 | |
262 } | |
263 | |
264 void menu_list_uninit(menu_t* menu,free_entry_t free_func) { | |
265 list_entry_t *i,*j; | |
266 | |
267 if(!free_func) free_func = (free_entry_t)free; | |
268 | |
269 for(i = mpriv->menu ; i != NULL ; ) { | |
270 j = i->next; | |
271 free_func(i); | |
272 i = j; | |
273 } | |
274 | |
275 mpriv->menu = mpriv->current = NULL; | |
276 | |
277 } | |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
278 |