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 void skinlist_set_cfg(enum screen_type screen
,
49 struct listitem_viewport_cfg
*cfg
)
51 if (listcfg
[screen
] != cfg
)
54 screens
[screen
].scroll_stop(&listcfg
[screen
]->selected_item_vp
.vp
);
55 listcfg
[screen
] = cfg
;
60 static bool skinlist_is_configured(enum screen_type screen
,
61 struct gui_synclist
*list
)
63 return (listcfg
[screen
] != NULL
) &&
64 (!list
|| (list
&& list
->selected_size
== 1));
66 static int current_drawing_line
;
67 static int offset_to_item(int offset
, bool wrap
)
69 int item
= current_drawing_line
+ offset
;
70 if (!current_list
|| current_list
->nb_items
== 0)
77 item
= (item
+ current_list
->nb_items
) % current_list
->nb_items
;
79 else if (item
>= current_list
->nb_items
&& !wrap
)
82 item
= item
% current_list
->nb_items
;
86 int skinlist_get_item_number()
88 return current_drawing_line
;
91 const char* skinlist_get_item_text(int offset
, bool wrap
, char* buf
, size_t buf_size
)
93 int item
= offset_to_item(offset
, wrap
);
94 if (item
< 0 || !current_list
)
96 const char* ret
= current_list
->callback_get_item_name(
97 item
, current_list
->data
, buf
, buf_size
);
98 return P2STR((unsigned char*)ret
);
101 enum themable_icons
skinlist_get_item_icon(int offset
, bool wrap
)
103 int item
= offset_to_item(offset
, wrap
);
104 if (item
< 0 || !current_list
|| current_list
->callback_get_item_icon
== NULL
)
106 return current_list
->callback_get_item_icon(item
, current_list
->data
);
109 static bool is_selected
= false;
110 bool skinlist_is_selected_item(void)
115 int skinlist_get_line_count(enum screen_type screen
, struct gui_synclist
*list
)
117 struct viewport
*parent
= (list
->parent
[screen
]);
118 if (!skinlist_is_configured(screen
, list
))
120 if (listcfg
[screen
]->tile
== true)
122 int rows
= (parent
->height
/ listcfg
[screen
]->height
);
123 int cols
= (parent
->width
/ listcfg
[screen
]->width
);
127 return (parent
->height
/ listcfg
[screen
]->height
);
130 static int current_item
;
131 static int current_nbitems
;
132 static bool needs_scrollbar
[NB_SCREENS
];
133 bool skinlist_needs_scrollbar(enum screen_type screen
)
135 return needs_scrollbar
[screen
];
138 void skinlist_get_scrollbar(int* nb_item
, int* first_shown
, int* last_shown
)
140 if (!skinlist_is_configured(0, NULL
))
148 *nb_item
= current_item
;
150 *last_shown
= current_nbitems
;
154 bool skinlist_draw(struct screen
*display
, struct gui_synclist
*list
)
156 int cur_line
, display_lines
;
157 const int screen
= display
->screen_type
;
158 struct viewport
*parent
= (list
->parent
[screen
]);
160 const int list_start_item
= list
->start_item
[screen
];
162 if (!skinlist_is_configured(screen
, list
))
165 wps
.display
= display
;
166 wps
.data
= listcfg
[screen
]->data
;
167 display_lines
= skinlist_get_line_count(screen
, list
);
168 label
= listcfg
[screen
]->label
;
169 display
->set_viewport(parent
);
170 display
->clear_viewport();
171 current_item
= list
->selected_item
;
172 current_nbitems
= list
->nb_items
;
173 needs_scrollbar
[screen
] = list
->nb_items
> display_lines
;
175 for (cur_line
= 0; cur_line
< display_lines
; cur_line
++)
177 struct skin_element
* viewport
;
178 struct skin_viewport
* skin_viewport
= NULL
;
179 if (list_start_item
+cur_line
+1 > list
->nb_items
)
181 current_drawing_line
= list_start_item
+cur_line
;
182 is_selected
= list
->show_selection_marker
&&
183 list_start_item
+cur_line
== list
->selected_item
;
185 for (viewport
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), listcfg
[screen
]->data
->tree
);
187 viewport
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), viewport
->next
))
189 int origional_x
, origional_y
;
190 int origional_w
, origional_h
;
191 skin_viewport
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), viewport
->data
);
192 char *viewport_label
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), skin_viewport
->label
);
193 if (viewport
->children
== 0 || !viewport_label
||
194 (skin_viewport
->label
&& strcmp(label
, viewport_label
))
199 memcpy(&listcfg
[screen
]->selected_item_vp
, skin_viewport
, sizeof(struct skin_viewport
));
200 skin_viewport
= &listcfg
[screen
]->selected_item_vp
;
202 origional_x
= skin_viewport
->vp
.x
;
203 origional_y
= skin_viewport
->vp
.y
;
204 origional_w
= skin_viewport
->vp
.width
;
205 origional_h
= skin_viewport
->vp
.height
;
206 if (listcfg
[screen
]->tile
)
208 int cols
= (parent
->width
/ listcfg
[screen
]->width
);
209 int col
= (cur_line
)%cols
;
210 int row
= (cur_line
)/cols
;
212 skin_viewport
->vp
.x
= parent
->x
+ listcfg
[screen
]->width
*col
+ origional_x
;
213 skin_viewport
->vp
.y
= parent
->y
+ listcfg
[screen
]->height
*row
+ origional_y
;
217 skin_viewport
->vp
.x
= parent
->x
+ origional_x
;
218 skin_viewport
->vp
.y
= parent
->y
+ origional_y
+
219 (listcfg
[screen
]->height
*cur_line
);
221 display
->set_viewport(&skin_viewport
->vp
);
222 #ifdef HAVE_LCD_BITMAP
223 /* Set images to not to be displayed */
224 struct skin_token_list
*imglist
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), wps
.data
->images
);
227 struct wps_token
*token
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), imglist
->token
);
228 struct gui_img
*img
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), token
->value
.data
);
230 imglist
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), imglist
->next
);
233 struct skin_element
** children
= SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), viewport
->children
);
234 skin_render_viewport(SKINOFFSETTOPTR(get_skin_buffer(wps
.data
), (intptr_t)children
[0]),
235 &wps
, skin_viewport
, SKIN_REFRESH_ALL
);
236 #ifdef HAVE_LCD_BITMAP
237 wps_display_images(&wps
, &skin_viewport
->vp
);
239 /* force disableing scroll because it breaks later */
242 display
->scroll_stop(&skin_viewport
->vp
);
243 skin_viewport
->vp
.x
= origional_x
;
244 skin_viewport
->vp
.y
= origional_y
;
245 skin_viewport
->vp
.width
= origional_w
;
246 skin_viewport
->vp
.height
= origional_h
;
250 display
->set_viewport(parent
);
251 display
->update_viewport();
252 current_drawing_line
= list
->selected_item
;
253 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
254 /* Abuse the callback to force the sbs to update */
255 send_event(LCD_EVENT_ACTIVATION
, NULL
);