1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2011 by Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
33 #include "screen_access.h"
35 #include "scrollbar.h"
40 #include "statusbar-skinned.h"
41 #include "skin_engine/skin_engine.h"
42 #include "skin_engine/skin_display.h"
43 #include "appevents.h"
45 static struct listitem_viewport_cfg
*listcfg
[NB_SCREENS
] = {NULL
};
46 static struct gui_synclist
*current_list
;
48 static int current_row
;
49 static int current_column
;
51 void skinlist_set_cfg(enum screen_type screen
,
52 struct listitem_viewport_cfg
*cfg
)
54 if (listcfg
[screen
] != cfg
)
57 screens
[screen
].scroll_stop(&listcfg
[screen
]->selected_item_vp
.vp
);
58 listcfg
[screen
] = cfg
;
65 static bool skinlist_is_configured(enum screen_type screen
,
66 struct gui_synclist
*list
)
68 return (listcfg
[screen
] != NULL
) &&
69 (!list
|| (list
&& list
->selected_size
== 1));
71 static int current_drawing_line
;
72 static int offset_to_item(int offset
, bool wrap
)
74 int item
= current_drawing_line
+ offset
;
75 if (!current_list
|| current_list
->nb_items
== 0)
82 item
= (item
+ current_list
->nb_items
) % current_list
->nb_items
;
84 else if (item
>= current_list
->nb_items
&& !wrap
)
87 item
= item
% current_list
->nb_items
;
91 int skinlist_get_item_number()
93 return current_drawing_line
;
96 int skinlist_get_item_row()
101 int skinlist_get_item_column()
103 return current_column
;
107 const char* skinlist_get_item_text(int offset
, bool wrap
, char* buf
, size_t buf_size
)
109 int item
= offset_to_item(offset
, wrap
);
110 if (item
< 0 || !current_list
)
112 const char* ret
= current_list
->callback_get_item_name(
113 item
, current_list
->data
, buf
, buf_size
);
114 return P2STR((unsigned char*)ret
);
117 enum themable_icons
skinlist_get_item_icon(int offset
, bool wrap
)
119 int item
= offset_to_item(offset
, wrap
);
120 if (item
< 0 || !current_list
|| current_list
->callback_get_item_icon
== NULL
)
122 return current_list
->callback_get_item_icon(item
, current_list
->data
);
125 static bool is_selected
= false;
126 bool skinlist_is_selected_item(void)
131 int skinlist_get_line_count(enum screen_type screen
, struct gui_synclist
*list
)
133 struct viewport
*parent
= (list
->parent
[screen
]);
134 if (!skinlist_is_configured(screen
, list
))
136 if (listcfg
[screen
]->tile
== true)
138 int rows
= (parent
->height
/ listcfg
[screen
]->height
);
139 int cols
= (parent
->width
/ listcfg
[screen
]->width
);
143 return (parent
->height
/ listcfg
[screen
]->height
);
146 static int current_item
;
147 static int current_nbitems
;
148 static bool needs_scrollbar
[NB_SCREENS
];
149 bool skinlist_needs_scrollbar(enum screen_type screen
)
151 return needs_scrollbar
[screen
];
154 void skinlist_get_scrollbar(int* nb_item
, int* first_shown
, int* last_shown
)
156 if (!skinlist_is_configured(0, NULL
))
164 *nb_item
= current_item
;
166 *last_shown
= current_nbitems
;
170 bool skinlist_get_item(struct screen
*display
, struct gui_synclist
*list
, int x
, int y
, int *item
)
172 const int screen
= display
->screen_type
;
173 if (!skinlist_is_configured(screen
, list
))
176 int row
= y
/ listcfg
[screen
]->height
;
177 int column
= x
/ listcfg
[screen
]->width
;
178 struct viewport
*parent
= (list
->parent
[screen
]);
179 int cols
= (parent
->width
/ listcfg
[screen
]->width
);
180 *item
= row
* cols
+ column
;
184 bool skinlist_draw(struct screen
*display
, struct gui_synclist
*list
)
186 int cur_line
, display_lines
;
187 const int screen
= display
->screen_type
;
188 struct viewport
*parent
= (list
->parent
[screen
]);
190 const int list_start_item
= list
->start_item
[screen
];
192 if (!skinlist_is_configured(screen
, list
))
196 wps
.display
= display
;
197 wps
.data
= listcfg
[screen
]->data
;
198 display_lines
= skinlist_get_line_count(screen
, list
);
199 label
= (char *)SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), listcfg
[screen
]->label
);
200 display
->set_viewport(parent
);
201 display
->clear_viewport();
202 current_item
= list
->selected_item
;
203 current_nbitems
= list
->nb_items
;
204 needs_scrollbar
[screen
] = list
->nb_items
> display_lines
;
206 for (cur_line
= 0; cur_line
< display_lines
; cur_line
++)
208 struct skin_element
* viewport
;
209 struct skin_viewport
* skin_viewport
= NULL
;
210 if (list_start_item
+cur_line
+1 > list
->nb_items
)
212 current_drawing_line
= list_start_item
+cur_line
;
213 is_selected
= list
->show_selection_marker
&&
214 list_start_item
+cur_line
== list
->selected_item
;
216 for (viewport
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), listcfg
[screen
]->data
->tree
);
218 viewport
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), viewport
->next
))
220 int original_x
, original_y
;
221 skin_viewport
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), viewport
->data
);
222 char *viewport_label
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), skin_viewport
->label
);
223 if (viewport
->children
== 0 || !viewport_label
||
224 (skin_viewport
->label
&& strcmp(label
, viewport_label
))
229 memcpy(&listcfg
[screen
]->selected_item_vp
, skin_viewport
, sizeof(struct skin_viewport
));
230 skin_viewport
= &listcfg
[screen
]->selected_item_vp
;
232 original_x
= skin_viewport
->vp
.x
;
233 original_y
= skin_viewport
->vp
.y
;
234 if (listcfg
[screen
]->tile
)
236 int cols
= (parent
->width
/ listcfg
[screen
]->width
);
237 current_column
= (cur_line
)%cols
;
238 current_row
= (cur_line
)/cols
;
240 skin_viewport
->vp
.x
= parent
->x
+ listcfg
[screen
]->width
*current_column
+ original_x
;
241 skin_viewport
->vp
.y
= parent
->y
+ listcfg
[screen
]->height
*current_row
+ original_y
;
246 current_row
= cur_line
;
247 skin_viewport
->vp
.x
= parent
->x
+ original_x
;
248 skin_viewport
->vp
.y
= parent
->y
+ original_y
+
249 (listcfg
[screen
]->height
*cur_line
);
251 display
->set_viewport(&skin_viewport
->vp
);
252 #ifdef HAVE_LCD_BITMAP
253 /* Set images to not to be displayed */
254 struct skin_token_list
*imglist
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), wps
.data
->images
);
257 struct wps_token
*token
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), imglist
->token
);
258 struct gui_img
*img
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), token
->value
.data
);
260 imglist
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), imglist
->next
);
263 struct skin_element
** children
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), viewport
->children
);
264 skin_render_viewport(SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), (intptr_t)children
[0]),
265 &wps
, skin_viewport
, SKIN_REFRESH_ALL
);
266 #ifdef HAVE_LCD_BITMAP
267 wps_display_images(&wps
, &skin_viewport
->vp
);
269 /* force disableing scroll because it breaks later */
272 display
->scroll_stop(&skin_viewport
->vp
);
273 skin_viewport
->vp
.x
= original_x
;
274 skin_viewport
->vp
.y
= original_y
;
280 display
->set_viewport(parent
);
281 display
->update_viewport();
282 current_drawing_line
= list
->selected_item
;