9 #include "libmpcodecs/img_format.h"
10 #include "libmpcodecs/mp_image.h"
15 #include "libvo/font_load.h"
16 #include "osdep/keycodes.h"
19 #include "menu_list.h"
21 #define mpriv (menu->priv)
23 void menu_list_draw(menu_t
* menu
,mp_image_t
* mpi
) {
31 int need_h
= 0,need_w
= 0,ptr_l
,sidx
= 0;
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
;
43 ptr_l
= mpriv
->ptr
? menu_text_length(mpriv
->ptr
) : 0;
45 if(h
- vo_font
->height
<= 0 || w
- ptr_l
<= 0 || dw
<= 0 || dh
<= 0)
48 th
= menu_text_num_lines(mpriv
->title
,dw
) * (mpriv
->vspace
+ vo_font
->height
) + mpriv
->vspace
;
50 // the selected item is hidden, find a visible one
51 if(mpriv
->current
->hide
) {
53 for(m
= mpriv
->current
->next
; m
; m
= m
->next
)
55 if(!m
) // or the previous
56 for(m
= mpriv
->current
->prev
; m
; m
= m
->prev
)
58 if(m
) mpriv
->current
= m
;
62 for(i
= 0, m
= mpriv
->menu
; m
; m
= m
->next
, i
++) {
65 ll
= menu_text_length(m
->txt
);
66 if(ptr_l
+ ll
> need_w
) need_w
= ptr_l
+ ll
;
67 if(m
== mpriv
->current
) sidx
= i
;
70 if(need_w
> dw
) need_w
= dw
;
78 need_h
= count
* (mpriv
->vspace
+ vo_font
->height
) - mpriv
->vspace
;
79 if( need_h
+ th
> dh
) {
81 int maxl
= (dh
+ mpriv
->vspace
- th
) / (mpriv
->vspace
+ vo_font
->height
);
84 maxl
= (dh
+ mpriv
->vspace
) / ( vo_font
->height
+ mpriv
->vspace
);
88 need_h
= maxl
*(mpriv
->vspace
+ vo_font
->height
) - mpriv
->vspace
;
90 start
= sidx
- (maxl
/2);
91 if(start
< 0) start
= 0;
95 if(end
- start
< maxl
)
96 start
= end
- maxl
< 0 ? 0 : end
- maxl
;
99 for(i
= 0 ; m
->next
&& i
< start
; ) {
106 bg_w
= need_w
+2*mpriv
->minb
;
108 if(mpriv
->title_bg
>= 0) {
110 menu_text_size(mpriv
->title
,dw
,mpriv
->vspace
,1,&tw
,&th2
);
111 if(tw
+2*mpriv
->minb
> bg_w
) bg_w
= tw
+2*mpriv
->minb
;
112 menu_draw_box(mpi
,mpriv
->title_bg
,mpriv
->title_bg_alpha
,
113 x
< 0 ? (mpi
->w
-bg_w
)/2 : x
-mpriv
->minb
,dy
+y
-mpriv
->vspace
/2,bg_w
,th
);
115 menu_draw_text_full(mpi
,mpriv
->title
,
116 x
< 0 ? mpi
->w
/ 2 : x
,
119 MENU_TEXT_TOP
|MENU_TEXT_HCENTER
,
120 MENU_TEXT_TOP
|(x
< 0 ? MENU_TEXT_HCENTER
:MENU_TEXT_LEFT
));
124 for( ; m
!= NULL
&& dy
+ vo_font
->height
< dh
; m
= m
->next
) {
125 if(m
->hide
) continue;
126 if(m
== mpriv
->current
) {
127 if(mpriv
->ptr_bg
>= 0)
128 menu_draw_box(mpi
,mpriv
->ptr_bg
,mpriv
->ptr_bg_alpha
,
129 x
< 0 ? (mpi
->w
-bg_w
)/2 : x
-mpriv
->minb
,dy
+y
-mpriv
->vspace
/2,
130 bg_w
,vo_font
->height
+ mpriv
->vspace
);
132 menu_draw_text_full(mpi
,mpriv
->ptr
,
133 x
< 0 ? (mpi
->w
- need_w
) / 2 + ptr_l
: x
,
136 MENU_TEXT_TOP
|(x
< 0 ? MENU_TEXT_RIGHT
:MENU_TEXT_LEFT
) ,
137 MENU_TEXT_TOP
|(x
< 0 ? MENU_TEXT_RIGHT
:MENU_TEXT_LEFT
));
138 } else if(mpriv
->item_bg
>= 0)
139 menu_draw_box(mpi
,mpriv
->item_bg
,mpriv
->item_bg_alpha
,
140 x
< 0 ? (mpi
->w
-bg_w
)/2 : x
-mpriv
->minb
,dy
+y
-mpriv
->vspace
/2,
141 bg_w
,vo_font
->height
+ mpriv
->vspace
);
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
,
146 MENU_TEXT_TOP
|MENU_TEXT_LEFT
,
147 MENU_TEXT_TOP
|MENU_TEXT_LEFT
);
148 dy
+= vo_font
->height
+ mpriv
->vspace
;
153 void menu_list_read_cmd(menu_t
* menu
,int cmd
) {
156 while(mpriv
->current
->prev
) {
157 mpriv
->current
= mpriv
->current
->prev
;
158 if(!mpriv
->current
->hide
) return;
160 for( ; mpriv
->current
->next
!= NULL
; mpriv
->current
= mpriv
->current
->next
)
162 if(!mpriv
->current
->hide
) return;
163 while(mpriv
->current
->prev
) {
164 mpriv
->current
= mpriv
->current
->prev
;
165 if(!mpriv
->current
->hide
) return;
169 while(mpriv
->current
->next
) {
170 mpriv
->current
= mpriv
->current
->next
;
171 if(!mpriv
->current
->hide
) return;
173 mpriv
->current
= mpriv
->menu
;
174 if(!mpriv
->current
->hide
) return;
175 while(mpriv
->current
->next
) {
176 mpriv
->current
= mpriv
->current
->next
;
177 if(!mpriv
->current
->hide
) return;
181 case MENU_CMD_CANCEL
:
188 void menu_list_jump_to_key(menu_t
* menu
,int c
) {
189 if(c
< 256 && isalnum(c
)) {
190 list_entry_t
* e
= mpriv
->current
;
191 if(e
->txt
[0] == c
) e
= e
->next
;
192 for( ; e
; e
= e
->next
) {
198 for(e
= mpriv
->menu
; e
; e
= e
->next
) {
205 menu_dflt_read_key(menu
,c
);
208 void menu_list_read_key(menu_t
* menu
,int c
,int jump_to
) {
213 mpriv
->current
= mpriv
->menu
;
216 for(m
= mpriv
->current
; m
&& m
->next
; m
= m
->next
)
222 for(i
= 0, m
= mpriv
->current
; m
&& m
->prev
&& i
< 10 ; m
= m
->prev
, i
++)
228 for(i
= 0, m
= mpriv
->current
; m
&& m
->next
&& i
< 10 ; m
= m
->next
, i
++)
235 menu_list_jump_to_key(menu
,c
);
237 menu_dflt_read_key(menu
,c
);
241 void menu_list_add_entry(menu_t
* menu
,list_entry_t
* entry
) {
245 if(mpriv
->menu
== NULL
) {
246 mpriv
->menu
= mpriv
->current
= entry
;
250 for(l
= mpriv
->menu
; l
->next
!= NULL
; l
= l
->next
)
256 void menu_list_init(menu_t
* menu
) {
258 mpriv
= calloc(1,sizeof(struct menu_priv_s
));
262 void menu_list_uninit(menu_t
* menu
,free_entry_t free_func
) {
265 if(!free_func
) free_func
= (free_entry_t
)free
;
267 for(i
= mpriv
->menu
; i
!= NULL
; ) {
273 mpriv
->menu
= mpriv
->current
= NULL
;