diff --git a/data/interface/wmain.ui b/data/interface/wmain.ui index 495623b..a58c4b7 100644 --- a/data/interface/wmain.ui +++ b/data/interface/wmain.ui @@ -629,7 +629,7 @@ 0 0 - 2 + 1 1 @@ -648,20 +648,6 @@ 1 - - - Preview menu - True - True - True - - - 1 - 1 - 1 - 1 - - diff --git a/data/interface/wmenu.ui b/data/interface/wmenu.ui index e6a5488..b2c744d 100644 --- a/data/interface/wmenu.ui +++ b/data/interface/wmenu.ui @@ -22,7 +22,13 @@ 1 10 - + + -100 + 100 + 1 + 10 + + 100 1 10 @@ -48,6 +54,7 @@ True False vertical + 6 True @@ -179,12 +186,13 @@ True False - Vertical position (%): + 1 + Vertical position (percent): 0 - 2 - 1 + 3 + 2 1 @@ -192,37 +200,41 @@ True True - title_position + title_vertical 2 - 1 - 2 - 1 + 2 + 3 + 2 1 - + True False + 1 + Horizontal position (percent): + + + 0 + 2 + 2 + 1 + + + + + True + True + title_horizontal + 2 2 2 - 1 - 1 - - - - - True - False - - - 3 - 2 - 1 + 2 1 @@ -273,7 +285,7 @@ - Set default background + Default background True True True @@ -332,7 +344,7 @@ - Set menus without sound + Menu without sound True True True @@ -378,20 +390,7 @@ True False - - - True - False - <b>Vertical</b> - True - - - 0 - 0 - 1 - 1 - - + 8 True @@ -400,19 +399,7 @@ True - 1 - 0 - 1 - 1 - - - - - True - False - - - 2 + 0 0 1 1 @@ -422,138 +409,13 @@ True False - <b>Margins (%)</b> + <b>Margins (percent)</b> True - 3 + 1 0 - 1 - 1 - - - - - True - False - - - 4 - 0 - 1 - 1 - - - - - True - False - - - 2 - 1 - 1 - 1 - - - - - True - False - - - 4 - 1 - 1 - 1 - - - - - True - False - - - 3 - 2 - 1 - 1 - - - - - True - False - - - 4 - 3 - 1 - 1 - - - - - True - False - - - 2 - 3 - 1 - 1 - - - - - Top - True - True - False - 0 - True - True - - - 0 - 1 - 1 - 1 - - - - - Middle - True - True - False - 0 - True - True - top - - - 0 - 2 - 1 - 1 - - - - - Bottom - True - True - False - 0 - True - True - top - - - 0 - 3 - 1 + 2 1 @@ -568,7 +430,7 @@ True - 1 + 0 1 1 1 @@ -586,7 +448,7 @@ left - 1 + 0 2 1 1 @@ -604,7 +466,7 @@ left - 1 + 0 3 1 1 @@ -619,9 +481,9 @@ True - 3 + 1 1 - 1 + 2 1 @@ -634,7 +496,7 @@ True - 2 + 1 2 1 1 @@ -649,7 +511,7 @@ True - 4 + 2 2 1 1 @@ -664,9 +526,9 @@ True - 3 + 1 3 - 1 + 2 1 @@ -752,7 +614,7 @@ True False 1 - Color for unselected titles: + Unselected titles: 0 @@ -766,7 +628,7 @@ True False 1 - Color for shadows: + Shadows: 0 @@ -780,7 +642,7 @@ True False 1 - Color for selected title: + Selected title: 2 @@ -794,7 +656,7 @@ True False 1 - Background color for titles: + Background color: 2 @@ -973,6 +835,7 @@ True True True + False @@ -987,6 +850,7 @@ True True True + False @@ -994,6 +858,18 @@ 1 + + + True + False + 0 + + + True + True + 2 + + Show titles as selected @@ -1006,7 +882,7 @@ False True - 2 + 3 @@ -1017,7 +893,7 @@ True False - <b>Preview controls</b> + <b>Preview</b> True @@ -1028,47 +904,6 @@ 6 - - - True - False - - - Preview menu - True - True - True - - - - True - True - 0 - - - - - Dynamic preview - True - True - False - 0 - True - - - - False - True - 1 - - - - - False - True - 7 - - False @@ -1093,6 +928,7 @@ 576 True False + diff --git a/src/devede/dvd_menu.py b/src/devede/dvd_menu.py index d3c3e0b..bea3a4b 100644 --- a/src/devede/dvd_menu.py +++ b/src/devede/dvd_menu.py @@ -15,23 +15,26 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see -from gi.repository import Gtk +import cairo +from gi.repository import Gtk,Gdk,GdkPixbuf import os import devede.configuration_data import devede.interface_manager class dvd_menu(devede.interface_manager.interface_manager): - def __init__(self): + def __init__(self,project): + + self.entry_vertical_margin = 2.0 + self.entry_separation = 2.0 devede.interface_manager.interface_manager.__init__(self) self.config = devede.configuration_data.configuration.get_config() + self.project = project self.default_background = os.path.join(self.config.pic_path,"backgrounds","default_bg.png") self.default_sound = os.path.join(self.config.pic_path,"silence.ogg") - self.add_toggle("dynamic_preview", self.config.menu_dynamic_preview) - self.add_colorbutton("title_color", (0,0,0,1), self.update_preview) self.add_colorbutton("title_shadow", (0,0,0,0), self.update_preview) self.add_colorbutton("unselected_color", (1,1,1,1), self.update_preview) @@ -41,70 +44,68 @@ class dvd_menu(devede.interface_manager.interface_manager): self.add_text("title_text", None, self.update_preview) - self.add_group("position_vertical", ["top", "middle", "bottom"], "middle", self.update_preview) self.add_group("position_horizontal", ["left", "center", "right"], "center", self.update_preview) self.add_float_adjustment("margin_left", 10.0, self.update_preview) self.add_float_adjustment("margin_top", 12.5, self.update_preview) self.add_float_adjustment("margin_right", 10.0, self.update_preview) self.add_float_adjustment("margin_bottom", 12.5, self.update_preview) - self.add_float_adjustment("title_position", 10.0, self.update_preview) + self.add_float_adjustment("title_horizontal", 0.0, self.update_preview) + self.add_float_adjustment("title_vertical", 10.0, self.update_preview) self.add_group("at_startup", ["menu_show_at_startup", "play_first_title_at_startup"], "menu_show_at_startup") - self.add_fontbutton("title_font", "Sans 14", self.update_preview) - self.add_fontbutton("entry_font", "Sans 12", self.update_preview) + self.add_fontbutton("title_font", "Sans 28", self.update_preview) + self.add_fontbutton("entry_font", "Sans 18", self.update_preview) self.add_filebutton("background_picture", self.default_background, self.update_preview) self.add_filebutton("background_music", self.default_sound, self.update_preview) + self.cached_menu_font = None + self.cached_menu_size = 0 + def update_preview(self,b=None): self.store_ui(self.builder) + self.sf = None # force to repaint the menu + self.wdrawing_area.queue_draw() def on_default_background_clicked(self,b): - + self.background_picture = self.default_background self.update_ui(self.builder) - + self.update_preview() + def on_no_sound_clicked(self,b): - + self.background_music = self.default_sound self.update_ui(self.builder) - def on_dynamic_preview_toggled(self,b): - - self.config.menu_dynamic_preview = self.wdynamic_preview.get_active() - if (self.config.menu_dynamic_preview): - self.wframe_preview.show_all() - self.wframe_preview_controls.show_all() - self.wpreview_menu.set_sensitive(False) - else: - self.wframe_preview.hide() - self.wframe_preview_controls.hide() - self.wpreview_menu.set_sensitive(True) - def show_configuration(self): self.builder = Gtk.Builder() self.builder.set_translation_domain(self.config.gettext_domain) + self.refresh_static_data() + self.builder.add_from_file(os.path.join(self.config.glade,"wmenu.ui")) self.builder.connect_signals(self) - self.wdynamic_preview = self.builder.get_object("dynamic_preview") self.wframe_preview = self.builder.get_object("frame_preview") self.wframe_preview_controls = self.builder.get_object("frame_preview_controls") self.wmenu = self.builder.get_object("menu") self.wpreview_menu = self.builder.get_object("preview_menu") - + self.wdrawing_area = self.builder.get_object("drawingarea_preview") + self.wcurrent_page = self.builder.get_object("current_page") + self.wshow_as_selected = self.builder.get_object("show_as_selected") + self.wshow_as_selected.connect("toggled",self.update_preview) self.wmenu.show_all() + self.pages = 0 self.update_ui(self.builder) self.save_ui() - self.on_dynamic_preview_toggled(None) def on_accept_clicked(self,b): @@ -115,6 +116,308 @@ class dvd_menu(devede.interface_manager.interface_manager): self.restore_ui() self.wmenu.destroy() - + + def on_preview_menu_clicked(self,b): - pass \ No newline at end of file + pass + + + def get_font_params(self,font_name): + + font_elements=font_name.split(" ") + + if (len(font_elements))<2: + fontname="Sans" + fontstyle=cairo.FONT_WEIGHT_NORMAL + fontslant=cairo.FONT_SLANT_NORMAL + fontsize=12 + else: + fontname="" + fontstyle=cairo.FONT_WEIGHT_NORMAL + fontslant=cairo.FONT_SLANT_NORMAL + for counter2 in range(len(font_elements)-1): + if font_elements[counter2]=="Bold": + fontstyle=cairo.FONT_WEIGHT_BOLD + elif font_elements[counter2]=="Italic": + fontslant=cairo.FONT_SLANT_ITALIC + else: + fontname+=" "+font_elements[counter2] + if fontname!="": + fontname=fontname[1:] + else: + fontname="Sans" + + try: + fontsize=float(font_elements[-1]) + except: + fontsize=12 + + return fontname,fontstyle,fontslant,fontsize + + def paint_arrow(self,xl,xr,y,arrow_type,left): + + if arrow_type == "menu_entry": + fgcolor = self.unselected_color + elif arrow_type == "menu_entry_selected": + fgcolor = self.selected_color + elif arrow_type == "menu_entry_activated": + fgcolor = ( 1.0 - self.selected_color[0], 1.0 - self.selected_color[1], 1.0 - self.selected_color[2] ) + else: + return + + fo=cairo.FontOptions() + fo.set_antialias(cairo.ANTIALIAS_NONE) + self.cr.set_font_options(fo) + self.cr.set_antialias(cairo.ANTIALIAS_NONE) + + x = (xl + xr) / 2.0 + h = (self.cached_menu_size / 2.0) - 1.0 + self.cr.set_source_rgba(fgcolor[0],fgcolor[1],fgcolor[2],fgcolor[3]) + self.cr.move_to(x,y-h) + if (left): + self.cr.line_to(x-self.cached_menu_size+2,y) + else: + self.cr.line_to(x+self.cached_menu_size-2,y) + self.cr.line_to(x,y+h) + self.cr.line_to(x,y-h) + self.cr.fill() + + fo=cairo.FontOptions() + fo.set_antialias(cairo.ANTIALIAS_DEFAULT) + self.cr.set_font_options(fo) + self.cr.set_antialias(cairo.ANTIALIAS_DEFAULT) + + + def write_text(self,text,text_type,xl,xr,y,alignment): + """ Renders a line of text, in the rectangle delimited by xl,y-h;xr,y+h, with the specified alignment """ + + if text == None: + return + + if text_type == "title": + fgcolor = self.title_color + bgcolor = self.title_shadow + hard_borders = False + font = self.title_font + elif text_type == "menu_entry": + fgcolor = self.unselected_color + bgcolor = self.shadow_color + hard_borders = True + font = self.entry_font + elif text_type == "menu_entry_selected": + fgcolor = self.selected_color + bgcolor = None + hard_borders = True + font = self.entry_font + elif text_type == "menu_entry_activated": + fgcolor = ( 1.0 - self.selected_color[0], 1.0 - self.selected_color[1], 1.0 - self.selected_color[2] ) + bgcolor = None + hard_borders = True + font = self.entry_font + else: + return + + if hard_borders: + fo=cairo.FontOptions() + fo.set_antialias(cairo.ANTIALIAS_NONE) + self.cr.set_font_options(fo) + self.cr.set_antialias(cairo.ANTIALIAS_NONE) + + (fontname, fontstyle, fontslant, fontsize) = self.get_font_params(font) + self.cr.select_font_face(fontname,fontslant, fontstyle) + self.cr.set_font_size(fontsize) + extents = self.cr.text_extents(text) + + if alignment == "left": + x = xl + elif alignment == "right": + x = xr - extents[2] + elif alignment == "center": + x = ((xl + xr) / 2.0) - (extents[2] / 2.0) + + if (bgcolor != None): + self.cr.move_to(x+extents[0]+2,y-(extents[3]/2.0)-extents[1]+2) + self.cr.set_source_rgba(bgcolor[0],bgcolor[1],bgcolor[2],bgcolor[3]) + self.cr.show_text(text) + + self.cr.move_to(x+extents[0],y-(extents[3]/2.0)-extents[1]) + self.cr.set_source_rgba(fgcolor[0],fgcolor[1],fgcolor[2],fgcolor[3]) + self.cr.show_text(text) + + if hard_borders: + fo=cairo.FontOptions() + fo.set_antialias(cairo.ANTIALIAS_DEFAULT) + self.cr.set_font_options(fo) + self.cr.set_antialias(cairo.ANTIALIAS_DEFAULT) + + + + def refresh_static_data(self): + """ This method sets data that can't be changed from the dvd settings window. + It must be called before painting a menu """ + + if self.config.PAL: + self.y=576.0 + else: + self.y=480.0 + + self.title_list = [] + counter = 0 + for element in self.project.get_all_files(): + if element.show_in_menu: + self.title_list.append( (element, counter) ) + counter += 1 + + self.sf = None + self.current_shown_page = 0 + + + def paint_menu(self,paint_background, paint_selected, paint_activated, page_number): + + if self.sf == None: + self.sf=cairo.ImageSurface(cairo.FORMAT_ARGB32,720,int(self.y)) + self.cr=cairo.Context(self.sf) + + if self.cached_menu_font != self.entry_font: + # memorize the font sizes + (fontname, fontstyle, fontslant, fontsize) = self.get_font_params(self.entry_font) + self.cr.select_font_face(fontname,fontslant, fontstyle) + self.cr.set_font_size(fontsize) + extents = self.cr.font_extents() + self.cached_menu_size = extents[2] + self.cached_menu_font = self.entry_font + + if paint_background: + extra_pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.background_picture) + extra_x = float(extra_pixbuf.get_width()) + extra_y = float(extra_pixbuf.get_height()) + + self.cr.save() + self.cr.scale(720.0/extra_x,self.y/extra_y) + + surface = Gdk.cairo_surface_create_from_pixbuf(extra_pixbuf,1,None) + self.cr.set_source_surface(surface,0,0) + self.cr.paint() + self.cr.restore() + hmargin = self.title_horizontal * 720.0 / 100.0 + self.write_text(self.title_text, "title", 0 + hmargin, 720 + hmargin, self.title_vertical * self.y / 100.0, "center") + else: + self.cr.set_source_rgb(1.0,1.0,1.0) + self.cr.paint() + + top_margin_p = self.y * self.margin_top / 100.0 + bottom_margin_p = self.y * self.margin_bottom / 100.0 + left_margin_p = 720.0 * self.margin_left / 100.0 + right_margin_p = 720.0 * self.margin_right / 100.0 + + entry_height = self.cached_menu_size + self.entry_vertical_margin * 2.0 + self.entry_separation + entries_per_page = int((self.y - top_margin_p - bottom_margin_p) / entry_height) + n_entries = len(self.title_list) + if (n_entries > entries_per_page): + paint_arrows = True + entries_per_page -= 1 + else: + paint_arrows = False + + self.pages = int(n_entries / entries_per_page) + if (n_entries == 0) or ((n_entries % entries_per_page) != 0): + self.pages += 1 + if (page_number >= self.pages) and (page_number > 0): + page_number -= 1 + + self.wcurrent_page.set_text(_("Page %(X)d of %(Y)d") % {"X":page_number+1 , "Y":self.pages}) + xl = left_margin_p + xr = 720.0 - right_margin_p + y = top_margin_p + entry_height/2.0 + for entry in self.title_list[page_number*entries_per_page:(page_number+1)*entries_per_page]: + text = entry[0].title_name + if paint_background: + self.paint_base(xl, xr, y, 0) + self.write_text(text, "menu_entry", xl, xr, y, self.position_horizontal) + if paint_selected: + self.write_text(text, "menu_entry_selected", xl, xr, y, self.position_horizontal) + if paint_activated: + self.write_text(text, "menu_entry_activated", xl, xr, y, self.position_horizontal) + y += entry_height + if paint_arrows: + if page_number == 0: + self.paint_base(xl, xr, y, 0) + if paint_background: + self.paint_arrow(xl, xr, y, "menu_entry", False) + if paint_selected: + self.paint_arrow(xl, xr, y, "menu_entry_selected", False) + if paint_activated: + self.paint_arrow(xl, xr, y, "menu_entry_activated", False) + elif page_number == (self.pages - 1): + self.paint_base(xl, xr, y, 0) + if paint_background: + self.paint_arrow(xl, xr, y, "menu_entry", True) + if paint_selected: + self.paint_arrow(xl, xr, y, "menu_entry_selected", True) + if paint_activated: + self.paint_arrow(xl, xr, y, "menu_entry_activated", True) + else: + self.paint_base(xl, xr, y, 1) + self.paint_base(xl, xr, y, 2) + med = (xl + xr) / 2.0 + if paint_background: + self.paint_arrow(med, xr, y, "menu_entry", False) + self.paint_arrow(xl, med, y, "menu_entry", True) + if paint_selected: + self.paint_arrow(med, xr, y, "menu_entry_selected", False) + self.paint_arrow(xl, med, y, "menu_entry_selected", True) + if paint_activated: + self.paint_arrow(med, xr, y, "menu_entry_activated", False) + self.paint_arrow(xl, med, y, "menu_entry_activated", True) + + def paint_base(self,xl, xr, y, type_b): + + height = self.cached_menu_size + self.entry_vertical_margin + radius = (height) / 2.0 + y -= radius + + if (type_b == 1): # half button, at left + xr = (xl+xr) / 2.0 + xr -= radius + elif (type_b == 2): # half button, at right + xl = (xl+xr) / 2.0 + xl += radius + + self.cr.set_source_rgba(self.background_color[0],self.background_color[1],self.background_color[2],self.background_color[3]) + self.cr.move_to(xl,y) + self.cr.line_to(xr,y) + self.cr.curve_to(xr+radius,y,xr+radius,y+height,xr,y+height) + self.cr.line_to(xl,y+height) + self.cr.curve_to(xl-radius,y+height,xl-radius,y,xl,y) + self.cr.fill() + + + def on_next_page_clicked(self,b): + + self.current_shown_page += 1 + if (self.current_shown_page == self.pages): + self.current_shown_page -= 1 + self.update_preview() + + def on_previous_page_clicked(self,b): + + self.current_shown_page -= 1 + if (self.current_shown_page < 0): + self.current_shown_page = 0 + self.update_preview() + + def on_drawingarea_preview_draw(self,widget,cr): + + """ Callback to repaint the menu preview window when it + sends the EXPOSE event """ + + if not self.config.menu_dynamic_preview: + return + + if (self.sf == None): + self.paint_menu(True, self.wshow_as_selected.get_active(), False, self.current_shown_page) + if (self.current_shown_page >= self.pages): + self.current_shown_page = self.pages + + cr.set_source_surface(self.sf) + cr.paint() diff --git a/src/devede/file_movie.py b/src/devede/file_movie.py index 0e40746..07a989b 100644 --- a/src/devede/file_movie.py +++ b/src/devede/file_movie.py @@ -257,7 +257,7 @@ class file_movie(devede.interface_manager.interface_manager): self.on_treeview_subtitles_cursor_changed(None) def on_aspect_classic_toggled(self,b): - + status = self.waspect_classic.get_active() if (status): self.wadd_black_bars_pic.set_from_file(os.path.join(self.config.pic_path,"to_classic_blackbars.png")) @@ -281,13 +281,13 @@ class file_movie(devede.interface_manager.interface_manager): self.builder = None def on_add_subtitles_clicked(self,b): - + subt = devede.ask_subtitles.ask_subtitles() if (subt.run()): self.wsubtitles_list.append([subt.filename, subt.encoding, subt.language, subt.put_upper]) def get_selected_subtitle(self): - + selection = self.wtreview_subtitles.get_selection() model, treeiter = selection.get_selected() @@ -297,13 +297,13 @@ class file_movie(devede.interface_manager.interface_manager): return ( (None, None) ) def on_del_subtitles_clicked(self,b): - + model, treeiter = self.get_selected_subtitle() if (model != None): model.remove(treeiter) def on_treeview_subtitles_cursor_changed(self,b): - + model, treeiter = self.get_selected_subtitle() if (model == None): self.wdel_subtitles.set_sensitive(False) diff --git a/src/devede/project.py b/src/devede/project.py index 4f83ff8..0874221 100644 --- a/src/devede/project.py +++ b/src/devede/project.py @@ -31,7 +31,7 @@ class devede_project: self.config = devede.configuration_data.configuration.get_config() self.disc_type = self.config.disc_type - self.menu = devede.dvd_menu.dvd_menu() + self.menu = devede.dvd_menu.dvd_menu(self) self.current_title = None @@ -54,7 +54,6 @@ class devede_project: self.wframe_menu = builder.get_object("frame_menu") self.wcreate_menu = builder.get_object("create_menu") self.wmenu_options = builder.get_object("menu_options") - self.wpreview_menu = builder.get_object("preview_menu") self.wadd_file = builder.get_object("add_file") @@ -123,6 +122,14 @@ class devede_project: return ( (None, -1, None, None) ) + def get_all_files(self): + + retval = [] + + for row in self.wfiles.get_model(): + retval.append(row.model[row.iter][0]) + return retval + def set_interface_status(self,b): @@ -137,7 +144,6 @@ class devede_project: status = self.wcreate_menu.get_active() self.wmenu_options.set_sensitive(status) - self.wpreview_menu.set_sensitive(status) (element, position, model, treeiter) = self.get_current_file() if (element == None):