Mercurial > mplayer.hg
comparison libmenu/menu_list.c @ 8197:b31caec933e9
OSD menus initial version
author | albeu |
---|---|
date | Thu, 14 Nov 2002 23:47:11 +0000 |
parents | |
children | 440301fef3fe |
comparison
equal
deleted
inserted
replaced
8196:419bdbfdb660 | 8197:b31caec933e9 |
---|---|
1 | |
2 #include <stdlib.h> | |
3 #include <stdio.h> | |
4 #include <ctype.h> | |
5 | |
6 #include "../config.h" | |
7 | |
8 #include "img_format.h" | |
9 #include "mp_image.h" | |
10 | |
11 #include "m_struct.h" | |
12 #include "menu.h" | |
13 | |
14 #include "../libvo/font_load.h" | |
15 #include "../linux/keycodes.h" | |
16 | |
17 #define IMPL 1 | |
18 #include "menu_list.h" | |
19 | |
20 #define mpriv (menu->priv) | |
21 | |
22 void menu_list_draw(menu_t* menu,mp_image_t* mpi) { | |
23 int x = mpriv->x; | |
24 int y = mpriv->y; | |
25 int i; | |
26 int h = mpriv->h; | |
27 int w = mpriv->w; | |
28 int dh = 0,dw = 0; | |
29 int dy = 0; | |
30 int need_h = 0,need_w = 0,ptr_l = menu_text_length(mpriv->ptr) + 10,sidx = 0; | |
31 int th; | |
32 list_entry_t* m; | |
33 | |
34 if(mpriv->count < 1) | |
35 return; | |
36 | |
37 if(h <= 0) h = mpi->height; | |
38 if(w <= 0) w = mpi->width; | |
39 dh = h - 2*mpriv->minb; | |
40 dw = w - 2*mpriv->minb; | |
41 ptr_l = menu_text_length(mpriv->ptr); | |
42 // mpi is too small | |
43 if(h - vo_font->height <= 0 || w - ptr_l <= 0 || dw <= 0 || dh <= 0) | |
44 return; | |
45 | |
46 th = menu_text_num_lines(mpriv->title,dw) * (mpriv->vspace + vo_font->height) + mpriv->vspace; | |
47 | |
48 for(i = 0, m = mpriv->menu ; m ; m = m->next, i++) { | |
49 int ll = menu_text_length(m->txt); | |
50 if(ptr_l + ll > need_w) need_w = ptr_l + ll; | |
51 if(m == mpriv->current) sidx = i; | |
52 } | |
53 if(need_w > dw) need_w = dw; | |
54 if(x > 0) | |
55 x += mpriv->minb; | |
56 if(y > 0) | |
57 y += mpriv->minb; | |
58 else | |
59 y = mpriv->minb; | |
60 | |
61 need_h = mpriv->count * (mpriv->vspace + vo_font->height) - mpriv->vspace; | |
62 if( need_h + th > dh) { | |
63 int start,end; | |
64 int maxl = (dh + mpriv->vspace - th) / (mpriv->vspace + vo_font->height); | |
65 if(maxl < 4) { | |
66 th = 0; | |
67 maxl = (dh + mpriv->vspace) / ( vo_font->height + mpriv->vspace); | |
68 } | |
69 // Too smoll | |
70 if(maxl < 1) return; | |
71 need_h = maxl*(mpriv->vspace + vo_font->height) - mpriv->vspace; | |
72 | |
73 start = sidx - (maxl/2); | |
74 if(start < 0) start = 0; | |
75 end = start + maxl; | |
76 if(end > mpriv->count) { | |
77 end = mpriv->count; | |
78 if(end - start < maxl) | |
79 start = end - maxl < 0 ? 0 : end - maxl; | |
80 } | |
81 m = mpriv->menu; | |
82 for(i = 0 ; m->next && i < start ; i++) | |
83 m = m->next; | |
84 } else | |
85 m = mpriv->menu; | |
86 | |
87 if(th > 0) { | |
88 menu_draw_text_full(mpi,mpriv->title, | |
89 x < 0 ? mpi->w / 2 : x, | |
90 dy+y,dw,0, | |
91 mpriv->vspace,1, | |
92 MENU_TEXT_TOP|MENU_TEXT_HCENTER, | |
93 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_HCENTER :MENU_TEXT_LEFT)); | |
94 dy += th; | |
95 } | |
96 | |
97 for( ; m != NULL && dy + vo_font->height < dh ; m = m->next ) { | |
98 if(m == mpriv->current) | |
99 menu_draw_text_full(mpi,mpriv->ptr, | |
100 x < 0 ? (mpi->w - need_w) / 2 + ptr_l : x, | |
101 dy+y,dw,dh - dy, | |
102 mpriv->vspace,0, | |
103 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_RIGHT :MENU_TEXT_LEFT) , | |
104 MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_RIGHT :MENU_TEXT_LEFT)); | |
105 menu_draw_text_full(mpi,m->txt, | |
106 x < 0 ? (mpi->w - need_w) / 2 + ptr_l : x + ptr_l, | |
107 dy+y,dw-ptr_l,dh - dy, | |
108 mpriv->vspace,0, | |
109 MENU_TEXT_TOP|MENU_TEXT_LEFT, | |
110 MENU_TEXT_TOP|MENU_TEXT_LEFT); | |
111 dy += vo_font->height + mpriv->vspace; | |
112 } | |
113 | |
114 } | |
115 | |
116 void menu_list_read_cmd(menu_t* menu,int cmd) { | |
117 switch(cmd) { | |
118 case MENU_CMD_UP: | |
119 if(mpriv->current->prev) { | |
120 mpriv->current = mpriv->current->prev; | |
121 } else { | |
122 for( ; mpriv->current->next != NULL ; mpriv->current = mpriv->current->next) | |
123 /* NOTHING */; | |
124 } break; | |
125 case MENU_CMD_DOWN: | |
126 if(mpriv->current->next) { | |
127 mpriv->current = mpriv->current->next; | |
128 } else { | |
129 mpriv->current = mpriv->menu; | |
130 } break; | |
131 case MENU_CMD_CANCEL: | |
132 menu->show = 0; | |
133 menu->cl = 1; | |
134 break; | |
135 } | |
136 } | |
137 | |
138 void menu_list_jump_to_key(menu_t* menu,int c) { | |
139 if(isalnum(c)) { | |
140 list_entry_t* e = mpriv->current; | |
141 if(e->txt[0] == c) e = e->next; | |
142 for( ; e ; e = e->next) { | |
143 if(e->txt[0] == c) { | |
144 mpriv->current = e; | |
145 return; | |
146 } | |
147 } | |
148 for(e = mpriv->menu ; e ; e = e->next) { | |
149 if(e->txt[0] == c) { | |
150 mpriv->current = e; | |
151 return; | |
152 } | |
153 } | |
154 } else | |
155 menu_dflt_read_key(menu,c); | |
156 } | |
157 | |
158 void menu_list_read_key(menu_t* menu,int c,int jump_to) { | |
159 list_entry_t* m; | |
160 int i; | |
161 switch(c) { | |
162 case KEY_HOME: | |
163 mpriv->current = mpriv->menu; | |
164 break; | |
165 case KEY_END: | |
166 for(m = mpriv->current ; m && m->next ; m = m->next) | |
167 /**/; | |
168 if(m) | |
169 mpriv->current = m; | |
170 break; | |
171 case KEY_PAGE_UP: | |
172 for(i = 0, m = mpriv->current ; m && m->prev && i < 10 ; m = m->prev, i++) | |
173 /**/; | |
174 if(m) | |
175 mpriv->current = m; | |
176 break; | |
177 case KEY_PAGE_DOWN: | |
178 for(i = 0, m = mpriv->current ; m && m->next && i < 10 ; m = m->next, i++) | |
179 /**/; | |
180 if(m) | |
181 mpriv->current = m; | |
182 break; | |
183 default: | |
184 if(jump_to) | |
185 menu_list_jump_to_key(menu,c); | |
186 else | |
187 menu_dflt_read_key(menu,c); | |
188 } | |
189 } | |
190 | |
191 void menu_list_add_entry(menu_t* menu,list_entry_t* entry) { | |
192 list_entry_t* l; | |
193 mpriv->count++; | |
194 | |
195 if(mpriv->menu == NULL) { | |
196 mpriv->menu = mpriv->current = entry; | |
197 return; | |
198 } | |
199 | |
200 for(l = mpriv->menu ; l->next != NULL ; l = l->next) | |
201 /* NOP */; | |
202 l->next = entry; | |
203 entry->prev = l; | |
204 } | |
205 | |
206 void menu_list_init(menu_t* menu) { | |
207 if(!mpriv) | |
208 mpriv = calloc(1,sizeof(struct menu_priv_s)); | |
209 | |
210 } | |
211 | |
212 void menu_list_uninit(menu_t* menu,free_entry_t free_func) { | |
213 list_entry_t *i,*j; | |
214 | |
215 if(!free_func) free_func = (free_entry_t)free; | |
216 | |
217 for(i = mpriv->menu ; i != NULL ; ) { | |
218 j = i->next; | |
219 free_func(i); | |
220 i = j; | |
221 } | |
222 | |
223 mpriv->menu = mpriv->current = NULL; | |
224 | |
225 } |