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
-
-
-
- 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
-
- 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
-
-
-
- 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):