=== modified file 'grub-core/gfxmenu/gui_list.c' --- grub-core/gfxmenu/gui_list.c 2010-10-16 20:16:52 +0000 +++ grub-core/gfxmenu/gui_list.c 2011-04-10 18:20:42 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include struct grub_gui_list_impl { @@ -35,9 +36,11 @@ int icon_width; int icon_height; + int item_width; int item_height; int item_padding; int item_icon_space; + int item_icon_padding; int item_spacing; grub_font_t item_font; grub_font_t selected_item_font; @@ -53,14 +56,19 @@ grub_gfxmenu_box_t scrollbar_thumb; int scrollbar_width; + int horizontal; + int first_shown_index; int need_to_recreate_boxes; char *theme_dir; char *menu_box_pattern; char *selected_item_box_pattern; + char *item_box_pattern; grub_gfxmenu_box_t menu_box; grub_gfxmenu_box_t selected_item_box; + grub_gfxmenu_box_t item_box; + int box_icon_only; grub_gfxmenu_icon_manager_t icon_manager; @@ -91,15 +99,27 @@ get_num_shown_items (list_impl_t self) { int boxpad = self->item_padding; - int item_vspace = self->item_spacing; + int item_space = self->item_spacing; int item_height = self->item_height; + int item_width = self->item_width; grub_gfxmenu_box_t box = self->menu_box; int box_top_pad = box->get_top_pad (box); int box_bottom_pad = box->get_bottom_pad (box); - - return (self->bounds.height + item_vspace - 2 * boxpad - - box_top_pad - box_bottom_pad) / (item_height + item_vspace); + int box_left_pad = box->get_left_pad (box); + int box_right_pad = box->get_right_pad (box); + + grub_gfxmenu_box_t itembox = self->item_box; + + if(self->horizontal) + return (self->bounds.width + item_space - 2 * boxpad + - box_left_pad - box_right_pad) / (grub_max(item_width, + self->icon_width + 2 * self->item_icon_padding) + item_space + + itembox->get_left_pad(itembox) + itembox->get_right_pad(itembox)); + else + return (self->bounds.height + item_space - 2 * boxpad + - box_top_pad - box_bottom_pad) / (item_height + item_space + + itembox->get_top_pad(itembox) + itembox->get_bottom_pad(itembox)); } static int @@ -115,6 +135,10 @@ self->selected_item_box_pattern, self->theme_dir); + grub_gui_recreate_box (&self->item_box, + self->item_box_pattern, + self->theme_dir); + self->need_to_recreate_boxes = 0; } @@ -183,29 +207,48 @@ static void draw_scrollbar (list_impl_t self, int value, int extent, int min, int max, - int rightx, int topy, int height) + int x1, int y1, int length) { + /* x1 and y1 have now their special meanings: + * if vertical: x1 = right, y1 = top + * if horizontal: x1 = left, y1 = bottom */ grub_gfxmenu_box_t frame = self->scrollbar_frame; grub_gfxmenu_box_t thumb = self->scrollbar_thumb; int frame_vertical_pad = (frame->get_top_pad (frame) + frame->get_bottom_pad (frame)); int frame_horizontal_pad = (frame->get_left_pad (frame) + frame->get_right_pad (frame)); - int tracktop = topy + frame->get_top_pad (frame); - int tracklen = height - frame_vertical_pad; - frame->set_content_size (frame, self->scrollbar_width, tracklen); - int thumby = tracktop + tracklen * (value - min) / (max - min); - int thumbheight = tracklen * extent / (max - min) + 1; - thumb->set_content_size (thumb, - self->scrollbar_width - frame_horizontal_pad, - thumbheight - (thumb->get_top_pad (thumb) - + thumb->get_bottom_pad (thumb))); - frame->draw (frame, - rightx - (self->scrollbar_width + frame_horizontal_pad), - topy); - thumb->draw (thumb, - rightx - (self->scrollbar_width - frame->get_right_pad (frame)), - thumby); + if(self->horizontal == 0) { + int tracktop = y1 + frame->get_top_pad (frame); + int tracklen = length - frame_vertical_pad; + frame->set_content_size (frame, self->scrollbar_width, tracklen); + int thumby = tracktop + tracklen * (value - min) / (max - min); + int thumbheight = tracklen * extent / (max - min) + 1; + thumb->set_content_size (thumb, + self->scrollbar_width - frame_horizontal_pad, + thumbheight - (thumb->get_top_pad (thumb) + + thumb->get_bottom_pad (thumb))); + frame->draw (frame, + x1 - (self->scrollbar_width + frame_horizontal_pad), + y1); + thumb->draw (thumb, + x1 - (self->scrollbar_width - frame->get_right_pad (frame)), + thumby); + } else { + int trackleft = x1 + frame->get_left_pad (frame); + int tracklen = length - frame_horizontal_pad; + frame->set_content_size (frame, tracklen, self->scrollbar_width); + int thumbx = trackleft + tracklen * (value - min) / (max - min); + int thumbwidth = tracklen * extent / (max - min) + 1; + thumb->set_content_size (thumb, + thumbwidth - (thumb->get_left_pad (thumb) + + thumb->get_right_pad (thumb)), + self->scrollbar_width - frame_vertical_pad); + frame->draw (frame, x1, + y1 - (self->scrollbar_width + frame_vertical_pad)); + thumb->draw (thumb, thumbx, + y1 - (self->scrollbar_width - frame->get_bottom_pad (frame))); + } } /* Draw the list of items. */ @@ -217,24 +260,44 @@ int boxpad = self->item_padding; int icon_text_space = self->item_icon_space; - int item_vspace = self->item_spacing; + int item_space = self->item_spacing; + + int horizontal = self->horizontal; int ascent = grub_font_get_ascent (self->item_font); int descent = grub_font_get_descent (self->item_font); + int icon_width = self->icon_width + 2 * self->item_icon_padding; + int icon_height = self->icon_height + 2 * self->item_icon_padding; + int item_width = icon_width; // TODO: for both horizontal and vertical int item_height = self->item_height; - + make_selected_item_visible (self); grub_gfxmenu_box_t selbox = self->selected_item_box; + grub_gfxmenu_box_t itembox = self->item_box; int sel_leftpad = selbox->get_left_pad (selbox); int sel_toppad = selbox->get_top_pad (selbox); - int item_top = sel_toppad; + int item_leftpad = selbox->get_left_pad (itembox); + int item_toppad = selbox->get_top_pad (itembox); + int max_leftpad = grub_max(sel_leftpad, item_leftpad); + int max_toppad = grub_max(sel_toppad, item_toppad); + + int item_left = max_leftpad; + int item_top = max_toppad; + int menu_index; int visible_index; struct grub_video_rect oviewport; grub_video_get_viewport (&oviewport.x, &oviewport.y, &oviewport.width, &oviewport.height); + if (horizontal) { + int new_width = grub_min(num_shown_items, self->view->menu->size) + * (grub_max(icon_width,item_width) + 2 * item_leftpad + item_space) + - item_space - 1 + 2 * grub_abs(sel_leftpad-item_leftpad) + 2 * boxpad; + oviewport.x += grub_max(0, self->bounds.width - new_width) / 2 - grub_abs(sel_leftpad-item_leftpad) / 2; + oviewport.width = new_width; + } grub_video_set_viewport (oviewport.x + boxpad, oviewport.y + boxpad, oviewport.width - 2 * boxpad, @@ -246,20 +309,45 @@ { int is_selected = (menu_index == self->view->selected); - if (is_selected) - { - selbox->set_content_size (selbox, oviewport.width - 2 * boxpad - 2, - item_height - 1); - selbox->draw (selbox, 0, - item_top - sel_toppad); - } + if (is_selected) { + if (horizontal == 0) + selbox->set_content_size (selbox, + (self->box_icon_only?icon_width: + (int)(oviewport.width - 2 * boxpad - 2)), + item_height - 1); + else + selbox->set_content_size (selbox, item_width - 1, + (self->box_icon_only?icon_height: + (int)(oviewport.height - 2 * boxpad - 2))); + selbox->draw (selbox, item_left - sel_leftpad, item_top - sel_toppad); + } else if (itembox) { + if (horizontal == 0) + itembox->set_content_size (itembox, + (self->box_icon_only?icon_width: + (int)(oviewport.width - 2 * boxpad - 2)), + item_height - 1); + else + itembox->set_content_size (itembox, item_width - 1, + (self->box_icon_only?icon_height: + (int)(oviewport.height - 2 * boxpad - 2))); + itembox->draw (itembox, item_left - item_leftpad, item_top - item_toppad); + } struct grub_video_bitmap *icon; - if ((icon = get_item_icon (self, menu_index)) != 0) - grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, - sel_leftpad, - item_top + (item_height - self->icon_height) / 2, - 0, 0, self->icon_width, self->icon_height); + if ((icon = get_item_icon (self, menu_index)) != 0) { + if (horizontal == 0) + grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, + item_left + self->item_icon_padding, + item_top + self->item_icon_padding + + (item_height - self->icon_height) / 2, + 0, 0, self->icon_width, self->icon_height); + else + grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, + item_left + self->item_icon_padding + + (item_width - icon_width) / 2, + item_top + self->item_icon_padding, + 0, 0, self->icon_width, self->icon_height); + } const char *item_title = grub_menu_get_entry (self->view->menu, menu_index)->title; @@ -271,15 +359,24 @@ ((is_selected && self->selected_item_color_set) ? self->selected_item_color : self->item_color); - grub_font_draw_string (item_title, - font, - grub_gui_map_color (text_color), - sel_leftpad + self->icon_width + icon_text_space, - (item_top + (item_height - (ascent + descent)) - / 2 + ascent)); - - item_top += item_height + item_vspace; + if (horizontal == 0) { + grub_font_draw_string (item_title, font, + grub_gui_map_color (text_color), + icon_width + icon_text_space, + item_top + (item_height - (ascent + descent)) / 2 + ascent); + + item_top += item_height + item_space; + } else { + grub_font_draw_string (item_title, font, + grub_gui_map_color (text_color), + (item_left + (item_width - + grub_font_get_string_width(font, item_title)) / 2), + item_top + item_toppad + icon_height + icon_text_space + ascent); + + item_left += item_width + item_space + 2 * item_leftpad; + } } + grub_video_set_viewport (oviewport.x, oviewport.y, oviewport.width, @@ -332,10 +429,13 @@ draw_scrollbar (self, self->first_shown_index, num_shown_items, 0, self->view->menu->size, - self->bounds.width - box_right_pad - + self->scrollbar_width, - box_top_pad, - self->bounds.height - box_top_pad - box_bottom_pad); + (self->horizontal?box_left_pad: + (int)(self->bounds.width - box_right_pad + self->scrollbar_width)), + (!self->horizontal?box_top_pad: + (int)(self->bounds.height - box_bottom_pad - self->scrollbar_width)), + (self->horizontal? + (self->bounds.width - box_left_pad - box_right_pad): + (self->bounds.height - box_top_pad - box_bottom_pad))); } grub_gui_restore_viewport (&vpsave); @@ -377,7 +477,7 @@ if (check_boxes (self)) { int boxpad = self->item_padding; - int item_vspace = self->item_spacing; + int item_space = self->item_spacing; int item_height = self->item_height; int num_items = 3; @@ -386,24 +486,48 @@ int box_top_pad = box->get_top_pad (box); int box_right_pad = box->get_right_pad (box); int box_bottom_pad = box->get_bottom_pad (box); - unsigned width_s; + + unsigned sel_size; grub_gfxmenu_box_t selbox = self->selected_item_box; int sel_toppad = selbox->get_top_pad (selbox); - - *width = grub_font_get_string_width (self->item_font, "Typical OS"); - width_s = grub_font_get_string_width (self->selected_item_font, - "Typical OS"); - if (*width < width_s) - *width = width_s; - - *width += 2 * boxpad + box_left_pad + box_right_pad; - - /* Set the menu box height to fit the items. */ - *height = (item_height * num_items - + item_vspace * (num_items - 1) - + 2 * boxpad - + box_top_pad + box_bottom_pad + sel_toppad); + int sel_bottompad = selbox->get_bottom_pad (selbox); + + grub_gfxmenu_box_t itembox = self->item_box; + int item_toppad = itembox->get_top_pad (itembox); + int item_bottompad = itembox->get_bottom_pad (itembox); + + unsigned max_toppad = grub_max(sel_toppad, item_toppad); + unsigned max_bottompad = grub_max(sel_bottompad, item_bottompad); + + if (self->horizontal == 0) { + *width = grub_font_get_string_width (self->item_font, "Typical OS"); + sel_size = grub_font_get_string_width (self->selected_item_font, + "Typical OS"); + if (*width < sel_size) *width = sel_size; + + *width += 2 * boxpad + box_left_pad + box_right_pad; + + /* Set the menu box height to fit the items. */ + *height = (item_height * num_items + + item_space * (num_items - 1) + + 2 * boxpad + + box_top_pad + box_bottom_pad + sel_toppad); + } else { + *height = grub_font_get_ascent (self->item_font) + - grub_font_get_descent (self->item_font); + sel_size = grub_font_get_ascent (self->selected_item_font) + - grub_font_get_descent (self->selected_item_font); + if (*height < sel_size && self->selected_item_font) *height = sel_size; + if (*height + self->item_icon_space < max_bottompad) *height = max_bottompad; + else *height += max_bottompad; + + *height += self->icon_height + box_top_pad + box_bottom_pad + + (2 * (boxpad + self->item_icon_padding)) + + max_toppad + self->item_icon_space; + /* Set the menu box width to fit the items. ie: set to full width */ + *width = self->bounds.width; + } } else { @@ -458,6 +582,10 @@ self->icon_width, self->icon_height); } + else if (grub_strcmp (name, "item_width") == 0) + { + self->item_width = grub_strtol (value, 0, 10); + } else if (grub_strcmp (name, "item_height") == 0) { self->item_height = grub_strtol (value, 0, 10); @@ -470,6 +598,10 @@ { self->item_icon_space = grub_strtol (value, 0, 10); } + else if (grub_strcmp (name, "item_icon_padding") == 0) + { + self->item_icon_padding = grub_strtol (value, 0, 10); + } else if (grub_strcmp (name, "item_spacing") == 0) { self->item_spacing = grub_strtol (value, 0, 10); @@ -490,6 +622,16 @@ grub_free (self->selected_item_box_pattern); self->selected_item_box_pattern = value ? grub_strdup (value) : 0; } + else if (grub_strcmp (name, "item_pixmap_style") == 0) + { + self->need_to_recreate_boxes = 1; + grub_free (self->item_box_pattern); + self->item_box_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "item_pixmap_icon_only") == 0) + { + self->box_icon_only = grub_strcmp (value, "false") != 0; + } else if (grub_strcmp (name, "scrollbar_frame") == 0) { self->need_to_recreate_scrollbar = 1; @@ -524,6 +666,11 @@ else self->id = 0; } + else if (grub_strcmp (name, "horizontal") == 0) + { + self->horizontal = grub_strcmp (value, "false") != 0; + if(self->horizontal) grub_env_set("orientation", "horizontal"); + } return grub_errno; } @@ -578,9 +725,11 @@ self->icon_width = 32; self->icon_height = 32; + self->item_width = 42; // Only applies to horizontal lists TODO: do for both and appropriate default value self->item_height = 42; self->item_padding = 14; self->item_icon_space = 4; + self->item_icon_padding = 0; self->item_spacing = 16; self->item_font = default_font; self->selected_item_font = 0; /* Default to using the item_font. */ @@ -604,6 +753,10 @@ self->selected_item_box_pattern = 0; self->menu_box = grub_gfxmenu_create_box (0, 0); self->selected_item_box = grub_gfxmenu_create_box (0, 0); + self->item_box = grub_gfxmenu_create_box (0, 0); + self->box_icon_only = 0; + + self->horizontal = 0; self->icon_manager = grub_gfxmenu_icon_manager_new (); if (! self->icon_manager) === modified file 'grub-core/gfxmenu/icon_manager.c' --- grub-core/gfxmenu/icon_manager.c 2009-11-21 16:48:05 +0000 +++ grub-core/gfxmenu/icon_manager.c 2011-04-09 13:10:49 +0000 @@ -257,7 +257,7 @@ /* Try each class in succession. */ icon = 0; - for (c = entry->classes->next; c && ! icon; c = c->next) + for (c = entry->classes; c && ! icon; c = c->next) icon = get_icon_by_class (mgr, c->name); return icon; } === modified file 'grub-core/normal/menu.c' --- grub-core/normal/menu.c 2011-04-08 10:12:02 +0000 +++ grub-core/normal/menu.c 2011-04-10 18:13:14 +0000 @@ -349,6 +349,8 @@ struct grub_term_output *term; int gfxmenu = 0; + grub_env_set("orientation", "vertical"); + FOR_ACTIVE_TERM_OUTPUTS(term) if (grub_strcmp (term->name, "gfxterm") == 0) { @@ -580,22 +582,6 @@ menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_KEY_UP: - case GRUB_TERM_CTRL | 'p': - case '^': - if (current_entry > 0) - current_entry--; - menu_set_chosen_entry (current_entry); - break; - - case GRUB_TERM_CTRL | 'n': - case GRUB_TERM_KEY_DOWN: - case 'v': - if (current_entry < menu->size - 1) - current_entry++; - menu_set_chosen_entry (current_entry); - break; - case GRUB_TERM_CTRL | 'g': case GRUB_TERM_KEY_PPAGE: if (current_entry < GRUB_MENU_PAGE_SIZE) @@ -614,14 +600,6 @@ menu_set_chosen_entry (current_entry); break; - case '\n': - case '\r': - case GRUB_TERM_KEY_RIGHT: - case GRUB_TERM_CTRL | 'f': - menu_fini (); - *auto_boot = 0; - return current_entry; - case '\e': if (nested) { @@ -656,6 +634,62 @@ *auto_boot = 0; return i; } + + if (grub_strcmp(grub_env_get("orientation"), "horizontal") == 0) { + switch(c) { + case GRUB_TERM_KEY_LEFT: + case GRUB_TERM_CTRL | 'p': + case '<': + if (current_entry > 0) + current_entry--; + menu_set_chosen_entry (current_entry); + break; + + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_RIGHT: + case '>': + if (current_entry < menu->size - 1) + current_entry++; + menu_set_chosen_entry (current_entry); + break; + + case '\n': + case '\r': + case GRUB_TERM_CTRL | 'f': + menu_fini (); + *auto_boot = 0; + return current_entry; + + } + } else { + switch(c) { + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': + case '^': + if (current_entry > 0) + current_entry--; + menu_set_chosen_entry (current_entry); + break; + + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: + case 'v': + if (current_entry < menu->size - 1) + current_entry++; + menu_set_chosen_entry (current_entry); + break; + + case '\n': + case '\r': + case GRUB_TERM_KEY_RIGHT: + case GRUB_TERM_CTRL | 'f': + menu_fini (); + *auto_boot = 0; + return current_entry; + + } + } + } break; }