código refurbishado. cambié textos a inglés (por alguna razón). cambio del tipo y botones en la ventana. etc..
This commit is contained in:
parent
45e645fcbf
commit
d00e6aa7f3
@ -14,234 +14,273 @@ if gtk.pygtk_version < (2,3,90):
|
||||
print "PyGtk 2.3.90 or later required for this example"
|
||||
raise SystemExit
|
||||
|
||||
class HelloWorld:
|
||||
pixbuf = None
|
||||
imagen = gtk.Image()
|
||||
ruta = "/home/mauro/Imágenes/art/4995443800_e68125ac35_o.jpg"
|
||||
conffile = "/home/mauro/git/greeter.gconf-defaults"
|
||||
layout = "zoom" #wallpaper, centered, scaled, stretched, zoom
|
||||
class App:
|
||||
path = "/usr/share/images/desktop-base/moreblue-orbit-gdm.svg"
|
||||
disp = "stretched"
|
||||
conffile = "/etc/gdm3/greeter.gconf-defaults"
|
||||
image = gtk.Image()
|
||||
screenw = -1
|
||||
screenh = -1
|
||||
|
||||
def dibujar_imagen(self):
|
||||
imagen_cargada = gtk.gdk.pixbuf_new_from_file(self.ruta)
|
||||
ancho_img = imagen_cargada.get_width()
|
||||
alto_img = imagen_cargada.get_height()
|
||||
# redraw the screen thumbnail with currently selected file and disposition
|
||||
def redraw(self):
|
||||
|
||||
ratio_disp = float(self.wscreen)/float(self.hscreen)
|
||||
ratio_imag = float(ancho_img)/float(alto_img)
|
||||
# new pixbuf from current path
|
||||
readimg = gtk.gdk.pixbuf_new_from_file(self.path)
|
||||
imgw = readimg.get_width()
|
||||
imgh = readimg.get_height()
|
||||
|
||||
ancho_img_scaled = None
|
||||
alto_img_scaled = None
|
||||
# calculate selected image and screen proportions (width-to-height ratio)
|
||||
disp_ratio = float(self.screenw)/float(self.screenh)
|
||||
img_ratio = float(imgw)/float(imgh)
|
||||
|
||||
self.pixbuf.fill(0x88888888)
|
||||
self.pixbuf.saturate_and_pixelate(self.pixbuf, 0.0, True)
|
||||
# actual width of the image on the screen thumbnail
|
||||
thumbw = -1
|
||||
thumbh = -1
|
||||
|
||||
# create an pixbuf for the thumbn, and fill it with a "background" pattern
|
||||
thumbpixbuf = gtk.gdk.Pixbuf( gtk.gdk.COLORSPACE_RGB, True, 8,
|
||||
int(self.screenw/4.0),
|
||||
int(self.screenh/4.0) )
|
||||
thumbpixbuf.fill(0x88888888)
|
||||
thumbpixbuf.saturate_and_pixelate(thumbpixbuf, 0.0, True)
|
||||
|
||||
if self.layout == "zoom":
|
||||
if ratio_disp > ratio_imag:
|
||||
ancho_img_scaled = self.wscreen/4.0
|
||||
alto_img_scaled = alto_img*((self.wscreen/4.0)/ancho_img)
|
||||
# switch between the different disposition styles
|
||||
if self.disp == "zoom":
|
||||
|
||||
# if display wider than image, scale image to fit screen width
|
||||
if disp_ratio > img_ratio:
|
||||
thumbw = int(self.screenw/4.0)
|
||||
thumbh = int(imgh*((self.screenw/4.0)/imgw))
|
||||
|
||||
# else scale image to fit screen height
|
||||
else:
|
||||
alto_img_scaled = self.hscreen/4.0
|
||||
ancho_img_scaled = ancho_img*((self.hscreen/4.0)/alto_img)
|
||||
thumbh = int(self.screenh/4.0)
|
||||
thumbw = int(imgw*((self.screenh/4.0)/imgh))
|
||||
|
||||
# scale previously loaded image and copy to the screen thumbnail pixbuf
|
||||
readimg = readimg.scale_simple(thumbw,thumbh,gtk.gdk.INTERP_BILINEAR)
|
||||
readimg.copy_area( int((thumbw-self.screenw/4.0)/2),
|
||||
int((thumbh-self.screenh/4.0)/2),
|
||||
int(self.screenw/4), int(self.screenh/4),
|
||||
thumbpixbuf, 0, 0)
|
||||
|
||||
imagen_cargada = imagen_cargada.scale_simple(int(ancho_img_scaled),
|
||||
int(alto_img_scaled),
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
imagen_cargada.copy_area( int((ancho_img_scaled-self.wscreen/4.0)/2),
|
||||
int((alto_img_scaled-self.hscreen/4.0)/2),
|
||||
int(self.wscreen/4), int(self.hscreen/4),
|
||||
self.pixbuf, 0, 0)
|
||||
elif self.layout == "scaled":
|
||||
scale_x = (self.wscreen/4.0)/ancho_img
|
||||
scale_y = (self.hscreen/4.0)/alto_img
|
||||
|
||||
ancho_img_scaled = ancho_img*min(scale_x, scale_y)
|
||||
alto_img_scaled = alto_img*min(scale_x, scale_y)
|
||||
elif self.disp == "scaled":
|
||||
|
||||
imagen_cargada = imagen_cargada.scale_simple(int(ancho_img_scaled),
|
||||
int(alto_img_scaled),
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
imagen_cargada.copy_area( 0, 0, ancho_img_scaled, alto_img_scaled,
|
||||
self.pixbuf,
|
||||
int((self.wscreen/4-ancho_img_scaled)/2),
|
||||
int((self.hscreen/4-alto_img_scaled)/2))
|
||||
elif self.layout == "centered":
|
||||
imagen_cargada = imagen_cargada.scale_simple(int(ancho_img/4),
|
||||
int(alto_img/4),
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
# with the "scaled" disposition, image is scaled
|
||||
# so that it fits entirely onscreen
|
||||
xscale = (self.screenw/4.0)/imgw
|
||||
yscale = (self.screenh/4.0)/imgh
|
||||
|
||||
x0 = (self.wscreen-ancho_img)/8
|
||||
y0 = (self.hscreen-alto_img)/8
|
||||
thumbw = int(imgw*min(xscale, yscale))
|
||||
thumbh = int(imgh*min(yscale, yscale))
|
||||
|
||||
readimg = readimg.scale_simple(thumbw,thumbh,gtk.gdk.INTERP_BILINEAR)
|
||||
readimg.copy_area( 0, 0, thumbw, thumbh, thumbpixbuf,
|
||||
int((self.screenw/4-thumbw)/2),
|
||||
int((self.screenh/4-thumbh)/2))
|
||||
|
||||
|
||||
elif self.disp == "centered":
|
||||
|
||||
imagen_cargada.copy_area( max(-x0,0), max(-y0,0),
|
||||
min(self.wscreen/4,ancho_img/4),
|
||||
min(self.hscreen/4,alto_img/4),
|
||||
self.pixbuf, max(x0,0), max(y0,0))
|
||||
print "copy_area(" + str(max(-x0,0)) + "," + str(max(-y0,0)) + "," \
|
||||
+ str(min(self.wscreen/4,ancho_img/4)) + "," \
|
||||
+ str(min(self.hscreen/4,alto_img/4)) + ",self.pixbuf," \
|
||||
+ str(max(x0,0)) + "," + str(max(y0,0)) + ") " + str(x0) + " "\
|
||||
+ str(y0) + " " + str(ancho_img) + " " + str(alto_img)
|
||||
elif self.layout == "stretched":
|
||||
imagen_cargada = imagen_cargada.scale_simple(self.wscreen/4,
|
||||
self.hscreen/4,
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
imagen_cargada.copy_area( 0, 0,self.wscreen/4, self.hscreen/4,
|
||||
self.pixbuf, 0, 0)
|
||||
# scale image to 1/4 its original size
|
||||
# (the screen thumbnail is 1/4 of the real screen size)
|
||||
readimg = readimg.scale_simple( int(imgw/4), int(imgh/4),
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
|
||||
# the visible area coordinates of the image
|
||||
# (if negative, the image is bigger than the screen)
|
||||
x0 = int((self.screenw-imgw)/8)
|
||||
y0 = int((self.screenh-imgh)/8)
|
||||
|
||||
readimg.copy_area( max(-x0,0), max(-y0,0),
|
||||
int(min(self.screenw/4,imgw/4)),
|
||||
int(min(self.screenh/4,imgh/4)),
|
||||
thumbpixbuf, max(x0,0), max(y0,0))
|
||||
|
||||
|
||||
elif self.disp == "stretched":
|
||||
|
||||
# in this case, simply stretch image so that both width and height
|
||||
# are the same as the screen's
|
||||
readimg = readimg.scale_simple( int(self.screenw/4),
|
||||
int(self.screenh/4),
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
readimg.copy_area( 0, 0, int(self.screenw/4), int(self.screenh/4),
|
||||
thumbpixbuf, 0, 0)
|
||||
|
||||
|
||||
elif self.layout == "wallpaper":
|
||||
imagen_cargada = imagen_cargada.scale_simple(int(ancho_img/4),
|
||||
int(alto_img/4),
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
elif self.disp == "wallpaper":
|
||||
|
||||
# scale image to 1/4 as in centered
|
||||
readimg = readimg.scale_simple( int(imgw/4),
|
||||
int(imgh/4),
|
||||
gtk.gdk.INTERP_BILINEAR)
|
||||
|
||||
# copy image as tiles until we fill the entire screen
|
||||
x0=0
|
||||
while( x0 < self.wscreen ):
|
||||
while( x0 < self.screenw ):
|
||||
y0=0
|
||||
while( y0 < self.hscreen):
|
||||
imagen_cargada.copy_area( 0, 0,
|
||||
min(self.wscreen/4-x0,ancho_img/4),
|
||||
min(self.hscreen/4-y0,alto_img/4),
|
||||
self.pixbuf, x0, y0)
|
||||
y0 += alto_img/4
|
||||
x0 += ancho_img/4
|
||||
|
||||
self.imagen.set_from_pixbuf(self.pixbuf)
|
||||
while( y0 < self.screenh):
|
||||
readimg.copy_area( 0, 0,
|
||||
int(min(self.screenw/4-x0,imgw/4)),
|
||||
int(min(self.screenh/4-y0,imgh/4)),
|
||||
thumbpixbuf, x0, y0)
|
||||
y0 += imgh/4
|
||||
x0 += imgw/4
|
||||
|
||||
# finally draw the gtk.Image from the pixbuf
|
||||
self.image.set_from_pixbuf(thumbpixbuf)
|
||||
|
||||
def get_screen_size(self):
|
||||
# read GDM3 configuration file, and set correspondig variables
|
||||
def read_config( self ):
|
||||
|
||||
with open( self.conffile, 'r') as conf:
|
||||
|
||||
for line in conf:
|
||||
m1 = re.match(r"\s*/desktop/gnome/background/picture_filename\s+((?:\S*(?:(?<=\\)\s)*)+)", line)
|
||||
m2 = re.match(r"\s*/desktop/gnome/background/picture_options\s+(\w+)", line)
|
||||
|
||||
if m1:
|
||||
print "Image file option read: " + m1.group(1)
|
||||
self.path = m1.group(1)
|
||||
|
||||
elif m2:
|
||||
print "Image disposition option read: " + m2.group(1)
|
||||
self.disp = m2.group(1)
|
||||
|
||||
# save GDM3 options file, replacing the options with the current ones
|
||||
def save_config( self, widget=None ):
|
||||
|
||||
with open(self.conffile, 'r') as conf:
|
||||
out = ""
|
||||
|
||||
for line in conf:
|
||||
m1 = re.match(r"\s*/desktop/gnome/background/picture_filename\s+((?:\S*(?:(?<=\\)\s)*)+)", line)
|
||||
m2 = re.match(r"\s*/desktop/gnome/background/picture_options\s+(\w+)", line)
|
||||
|
||||
# if the current line matchs the picture_filename option, replace
|
||||
# it with a new one containing the current value of path
|
||||
if m1:
|
||||
out += "/desktop/gnome/background/picture_filename " \
|
||||
+ self.path + "\n"
|
||||
|
||||
# else if it macthes the picture_options option, put the
|
||||
# value of disp instead
|
||||
elif m2:
|
||||
out += "/desktop/gnome/background/picture_options "\
|
||||
+ self.disp + "\n"
|
||||
|
||||
# else copy the line as-is
|
||||
else:
|
||||
out += line
|
||||
|
||||
# save the file putting in there the value of out
|
||||
with open(self.conffile, 'w') as f:
|
||||
f.write(out)
|
||||
print "Configuration file saved."
|
||||
|
||||
# close event. don't know if or what it should do
|
||||
def close(self, widget, event, data=None):
|
||||
return
|
||||
|
||||
# response event. should save setting if "apply", exit if "close"
|
||||
def response( self, widget, response):
|
||||
|
||||
if response == gtk.RESPONSE_CLOSE or response == gtk.RESPONSE_DELETE_EVENT:
|
||||
gtk.main_quit()
|
||||
|
||||
elif response == gtk.RESPONSE_APPLY:
|
||||
self.save_config()
|
||||
|
||||
# current image path changed callback. should redraw the screen thumbnail
|
||||
def path_changed( self, widget, response):
|
||||
|
||||
if response == gtk.RESPONSE_ACCEPT:
|
||||
self.path = widget.get_filename()
|
||||
self.redraw()
|
||||
|
||||
# current disposition option changed callback. should redraw
|
||||
def disp_changed( self, widget):
|
||||
self.disp = widget.get_active_text()
|
||||
self.redraw()
|
||||
|
||||
# initialization function. called upon instantiating a new App object
|
||||
def __init__ (self):
|
||||
|
||||
# obtain the root screen width and height
|
||||
(status,output)=commands.getstatusoutput('xwininfo -root|grep "geometry"')
|
||||
m1 = re.match(r".*geometry\s([0-9]+)x([0-9]+)\+.*", output)
|
||||
if m1:
|
||||
return (int(m1.group(1)), int(m1.group(2)))
|
||||
return (-1, -1)
|
||||
self.screenw = int(m1.group(1))
|
||||
self.screenh = int(m1.group(2))
|
||||
else:
|
||||
print "Error obtaining screen size. Defaulting to 1024x768."
|
||||
print "Verify that the xwininfo command is available in your system."
|
||||
self.screenw = 1024
|
||||
self.screenh = 768
|
||||
|
||||
# read config file to set path and disp accordingly, then redraw
|
||||
self.read_config()
|
||||
self.redraw()
|
||||
|
||||
# This is a callback function. The data arguments are ignored
|
||||
# in this example. More on callbacks below.
|
||||
def hello(self, widget, data=None):
|
||||
print "Hello World"
|
||||
|
||||
def delete_event(self, widget, event, data=None):
|
||||
#print "delete event occurred"
|
||||
# Change FALSE to TRUE and the main window will not be destroyed
|
||||
# with a "delete_event".
|
||||
return False
|
||||
|
||||
def destroy(self, widget, data=None):
|
||||
print "destroy signal occurred"
|
||||
gtk.main_quit()
|
||||
|
||||
def imagen_seleccionada( self, widget, response):
|
||||
if response == gtk.RESPONSE_ACCEPT:
|
||||
self.ruta = widget.get_filename()
|
||||
self.dibujar_imagen()
|
||||
|
||||
def layout_cambiado( self, widget):
|
||||
self.layout = widget.get_active_text()
|
||||
self.dibujar_imagen()
|
||||
|
||||
def leer_conf( self ):
|
||||
with open(self.conffile, 'r') as conf:
|
||||
for linea in conf:
|
||||
m1 = re.match(r"\s*/desktop/gnome/background/picture_filename\s+((?:\S*(?:(?<=\\)\s)*)+)", linea)
|
||||
m2 = re.match(r"\s*/desktop/gnome/background/picture_options\s+(\w+)", linea)
|
||||
if m1:
|
||||
print "imagen encontrada. " + m1.group(1)
|
||||
self.ruta = m1.group(1)
|
||||
elif m2:
|
||||
print "configuración encontrada: " + m2.group(1)
|
||||
self.layout = m2.group(1)
|
||||
|
||||
def guardar_conf( self, widget ):
|
||||
with open(self.conffile, 'r') as conf:
|
||||
salida = ""
|
||||
for linea in conf:
|
||||
m1 = re.match(r"\s*/desktop/gnome/background/picture_filename\s+((?:\S*(?:(?<=\\)\s)*)+)", linea)
|
||||
m2 = re.match(r"\s*/desktop/gnome/background/picture_options\s+(\w+)", linea)
|
||||
if m1:
|
||||
salida += "/desktop/gnome/background/picture_filename " + self.ruta + "\n"
|
||||
elif m2:
|
||||
salida += "/desktop/gnome/background/picture_options " + self.layout + "\n"
|
||||
else:
|
||||
salida += linea
|
||||
|
||||
with open(self.conffile, 'w') as f:
|
||||
f.write(salida)
|
||||
print "Se ha guardado la nueva configuración."
|
||||
|
||||
def __init__(self):
|
||||
|
||||
(self.wscreen, self.hscreen) = self.get_screen_size()
|
||||
|
||||
self.leer_conf()
|
||||
|
||||
self.pixbuf = gtk.gdk.Pixbuf( gtk.gdk.COLORSPACE_RGB, True, 8,
|
||||
int(self.wscreen/4.0),
|
||||
int(self.hscreen/4.0) )
|
||||
# create a new window
|
||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||
# self.window.set_size_request(400,600)
|
||||
|
||||
# The data passed to the callback
|
||||
# function is NULL and is ignored in the callback function.
|
||||
self.window.connect("delete_event", self.delete_event)
|
||||
|
||||
# Here we connect the "destroy" event to a signal handler.
|
||||
# This event occurs when we call gtk_widget_destroy() on the window,
|
||||
# or if we return FALSE in the "delete_event" callback.
|
||||
self.window.connect("destroy", self.destroy)
|
||||
|
||||
# Sets the border width of the window.
|
||||
self.window.set_border_width(10)
|
||||
|
||||
self.label = gtk.Label("<big><b>Elija la imagen nueva a mostrar</b></big>\n\
|
||||
La imagen actualmente configurada es /home/mauro.")
|
||||
self.label.set_use_markup(True)
|
||||
self.window = gtk.Dialog( "Change GDM3 background",
|
||||
None,
|
||||
gtk.DIALOG_NO_SEPARATOR)
|
||||
# add "apply" anc "close" buttons
|
||||
self.window.add_buttons( gtk.STOCK_APPLY, gtk.RESPONSE_APPLY,
|
||||
gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
|
||||
|
||||
# Creates a new button with the label "Hello World".
|
||||
self.button = gtk.Button("Hello World")
|
||||
|
||||
self.button.connect("clicked", self.guardar_conf)
|
||||
#self.button.connect_object("clicked", gtk.Widget.destroy, self.window)
|
||||
|
||||
self.vbox = gtk.VBox();
|
||||
self.hbox = gtk.HBox();
|
||||
self.window.connect("close", self.close)
|
||||
self.window.connect("response", self.response)
|
||||
|
||||
self.dibujar_imagen()
|
||||
|
||||
self.filechooserdialog = gtk.FileChooserDialog("Elija un archivo",
|
||||
self.window,
|
||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
|
||||
self.filechooserbutton = gtk.FileChooserButton(self.filechooserdialog)
|
||||
self.filechooserdialog.connect("response", self.imagen_seleccionada)
|
||||
# file chooser dialog and button
|
||||
self.filedialog = gtk.FileChooserDialog( "Choose a file", self.window,
|
||||
gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
|
||||
self.filebutton = gtk.FileChooserButton(self.filedialog)
|
||||
self.filedialog.connect( "response", self.path_changed)
|
||||
|
||||
# disposition selection combo
|
||||
self.combo = gtk.combo_box_new_text()
|
||||
self.combo.append_text("zoom")
|
||||
self.combo.append_text("centered")
|
||||
self.combo.append_text("stretched")
|
||||
self.combo.append_text("scaled")
|
||||
self.combo.append_text("wallpaper")
|
||||
self.combo.connect("changed", self.layout_cambiado)
|
||||
self.combo.connect( "changed", self.disp_changed)
|
||||
|
||||
self.vbox.pack_start(self.label)
|
||||
self.vbox.pack_start(self.imagen)
|
||||
self.vbox.pack_start(self.filechooserbutton)
|
||||
self.vbox.pack_start(self.hbox)
|
||||
self.hbox.pack_start(self.combo)
|
||||
self.hbox.pack_start(self.button)
|
||||
|
||||
self.vbox.show()
|
||||
self.filechooserbutton.show()
|
||||
self.hbox.show()
|
||||
self.label.show()
|
||||
self.imagen.show()
|
||||
self.combo.show()
|
||||
|
||||
self.window.add(self.vbox)
|
||||
while self.combo.get_active_text() != self.disp:
|
||||
self.combo.set_active( self.combo.get_active() + 1 )
|
||||
|
||||
self.filedialog.set_filename(self.path)
|
||||
|
||||
# The final step is to display this newly created widget.
|
||||
self.button.show()
|
||||
|
||||
# and the window
|
||||
#self.window.set_border_width(4)
|
||||
|
||||
# aux hbox
|
||||
self.hbox = gtk.HBox()
|
||||
self.hbox.pack_start(self.filebutton)
|
||||
self.hbox.pack_end(self.combo)
|
||||
self.hbox.set_border_width(5)
|
||||
|
||||
# image frame
|
||||
self.frame = gtk.Frame()
|
||||
self.frame.set_shadow_type(gtk.SHADOW_IN)
|
||||
self.frame.set_border_width(6)
|
||||
self.frame.add(self.image)
|
||||
|
||||
# the window vbox
|
||||
self.window.vbox.pack_start(self.frame)
|
||||
self.window.vbox.pack_start(self.hbox)
|
||||
|
||||
self.frame.show()
|
||||
self.image.show()
|
||||
self.filebutton.show()
|
||||
self.combo.show()
|
||||
self.hbox.show()
|
||||
self.window.show()
|
||||
|
||||
def main(self):
|
||||
@ -250,5 +289,5 @@ La imagen actualmente configurada es /home/mauro.")
|
||||
gtk.main()
|
||||
|
||||
if __name__ == "__main__":
|
||||
hello = HelloWorld()
|
||||
hello.main()
|
||||
app = App()
|
||||
app.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user