Active Topics

 


Reply
Thread Tools
Khertan's Avatar
Posts: 1,012 | Thanked: 817 times | Joined on Jul 2007 @ France
#41
Yep i use cairo drawing but on label ... my try to display a gtk.treeview is unsuccessfull at this time ...
 
darethehair's Avatar
Posts: 273 | Thanked: 104 times | Joined on Mar 2007 @ Manitoba, Canada
#42
khertan:

If you feel even more daring, perhaps sometime you can attempt an applet that draws a graphic (say, a sphere or rectangle, using Cairo), then adds a PyGTK button...?
__________________
There is nothing more dangerous than a bored cat.
 
Posts: 1,038 | Thanked: 737 times | Joined on Nov 2005 @ Helsinki
#43
Hmm.. someone needs to make an example applet with cairo and mouse click handling so that we can start simulating button behavior by using pixmaps/vectors.
 
mece's Avatar
Posts: 1,111 | Thanked: 1,985 times | Joined on Aug 2009 @ Åbo, Finland
#44
Originally Posted by konttori View Post
Hmm.. someone needs to make an example applet with cairo and mouse click handling so that we can start simulating button behavior by using pixmaps/vectors.
Hmm, I actually did that today, so I can write something up. I'll put it here first, and then you can tell me how it's the wrong method

In the meanwhile, can someone tell me how I can get a gtk.Label inside an EventBox to be upon a transparent surface? I can only seem to get it either invisible or with black background. Worked around it design wise, though, but would be nice to know how to do it.
__________________
Class .. : Meddler, Thread watcher, Developer, Helper
Humor .. : [********--] Alignment: Pacifist
Patience : [*****-----] Weapon(s): N900, N950, Metal music
Agro ... : [----------] Relic(s) : N95, NGage, Tamyia Wild One

Try Tweed Suit for your hardcore twittering needs
http://twitter.com/mece66
I like my coffee black, like my metal.
 
mece's Avatar
Posts: 1,111 | Thanked: 1,985 times | Joined on Aug 2009 @ Åbo, Finland
#45
Ok I wrote an example widget with images for buttons.

I attatched the images if you want to test it out. simply save this code to a .py file, and copy the image files either to
/home/user/buttons/
or wherever you want, but change the imagedir variable in the code to point at the right place.

Code:
# hildon home widget, png button example

import hildondesktop
import gtk
import cairo

imagepath = "/home/user/comic-widget/images/"

class ExamplePlugin(hildondesktop.HomePluginItem):
	def __init__(self):
		hildondesktop.HomePluginItem.__init__(self)
		self.set_size_request(96, 97) # make the widget a nice size. 
		# Interestingly, having the exactly correct amount of space, makes it not work properly, hence the 1 pixel extra.
		self.vbox = gtk.VBox()
		self.hbox = gtk.HBox() # Horisontally arranged box to put your buttons in
		self.hbox.set_size_request(96, 48)
		screen = self.get_screen()
		colormap = screen.get_rgba_colormap()
		self.set_colormap(colormap)
		self.set_app_paintable(True)
		self.label = gtk.Label()
		self.label.set_markup("<small>Buttons</small>")

		# The event boxes.
		self.e_text = gtk.EventBox()
		self.e_text.set_name('text')
		self.e_text.set_size_request(96, 48)
		self.e_next = gtk.EventBox()
		self.e_next.set_name('next') #  The name is nice to have if you want to link it to a file name for example.
		self.e_next.set_size_request(48, 48) # I have 48x48px buttons :)
		self.e_prev = gtk.EventBox()
		self.e_prev.set_name('prev')
		self.e_prev.set_size_request(48, 48)

		# Add the label:
		self.e_text.add(self.label)

		# Preload som images an throw them in a dict. 
		# I don't know if this actually helps make things snappy, but it was the simplest way I could think of.

		self.images = { 'next0':cairo.ImageSurface.create_from_png(imagepath + "next0-48x48.png"),
					'next1':cairo.ImageSurface.create_from_png(imagepath + "next1-48x48.png"),
					'prev0':cairo.ImageSurface.create_from_png(imagepath + "prev0-48x48.png"),
					'prev1':cairo.ImageSurface.create_from_png(imagepath + "prev1-48x48.png") }

		#*****************************************************************
		# now here's the important part: make some events.
		# I have the same event for release and leave because my event handler checks if it was a real click or a bailout
		self.e_next.set_events(gtk.gdk.BUTTON_PRESS_MASK|gtk.gdk.BUTTON_RELEASE_MASK|gtk.gdk.LEAVE_NOTIFY)
		self.e_next.connect("button-press-event", self.button_press)
		self.e_next.connect("button-release-event", self.button_release)
		self.e_next.connect("leave-notify-event", self.button_release)

		self.e_prev.set_events(gtk.gdk.BUTTON_PRESS_MASK|gtk.gdk.BUTTON_RELEASE_MASK|gtk.gdk.LEAVE_NOTIFY)
		self.e_prev.connect("button-press-event", self.button_press)
		self.e_prev.connect("button-release-event", self.button_release)
		self.e_prev.connect("leave-notify-event", self.button_release)

		# now let's put those eventboxes in the hbox
		self.vbox.pack_end(self.hbox,False,False,0)
		self.vbox.pack_end(self.e_text,False,False,0)
		self.hbox.pack_start(self.e_prev,False,False,0) # No padding for me, since I have a tight squeeze to get the buttons in.
		self.hbox.pack_end(self.e_next,False,False,0) 
		self.hbox.show_all()
		
		#now add the stuff to the widget, and show it. (it's empty though)
		
		self.vbox.show_all()
		self.add(self.vbox)

	#now some functions.

	#expose function, runs automagically when the widget feels exposed.

	def do_expose_event(widget, event):
		cr = widget.window.cairo_create() # create a cairo thingamabob
		widget.draw(widget.e_prev,0) # call my show button function, first arg is where to put image, and second is which image.
		widget.draw(widget.e_next,0) # again for the other image

		# paint some background. 
		cr.set_operator(cairo.OPERATOR_SOURCE)
		region = gtk.gdk.region_rectangle(event.area) # limit what to color
		cr.region(region)
		# bg_color=gtk.gdk.color_parse('#000000')
		cr.set_source_rgba (0.0, 0.0, 0.0, 0.5)	# Black, with 50% opacity. Nice!
		cr.fill_preserve() # lets fill it with that.


		return False

	# Function that draws a button preloaded in the images dictionary.
	def draw(self, target, postfix):
		cr_e = target.window.cairo_create()
		cr_e.set_source_rgba(0.0, 0.0, 0.0, 0.5) # If you, like I do, have transparency in your buttons,
		cr_e.set_operator(cairo.OPERATOR_SOURCE) #  you need to paint the background first.
		cr_e.paint()

		cr_e.set_operator(cairo.OPERATOR_OVER) # Not sure about this, but it works.
		# Now I have set it up so that the key in the dict to cairo imagesurface object is the name of the eventbox + a number.
		# 0 for idle, 1 for pressed..
		cr_e.set_source_surface(self.images[target.get_name() + str(postfix)], 0, 0) # here's where the magic is done
		cr_e.paint()

	# now the event handlers
	# I don't want to do anything other than switch image on press down.
	def button_press(self, widget, event):
		# this is needed because the second click can trigger a _2BUTTON_PRESS
		# and the third a _3BUTTON_PRESS, along with the regular BUTTON_PRESS
		# and I only want to switch images once.
		if not event.type == gtk.gdk.BUTTON_PRESS: 
			return False
		self.draw(widget, "1") #call the draw function, switch to image 1 which means pressed


	# then the button_release event.
	def button_release(self, widget, event):
		#check if it was released or moved out.
		if event.type == gtk.gdk.BUTTON_RELEASE:
			# here is where you actually do whatever the button is for. I'll print something.
			print "Success! The button was clicked!"

		else: 
			# if you want to do something with a button click that was bailed from, that would be here.
			print "You almost clicked that button, but then you dragged away at the last minute!"
		# then call the draw function, regardless of the type of release.
		# I think is nice to do it after the action, so that you get a visual queue
		# when the thing that should be done is done. At least it's nice in my widget.
		self.draw(widget, "0")

# register the plugin.

hd_plugin_type = ExamplePlugin

# This bit below is so that you can run the widget standalone.
if __name__ == "__main__":
	import gobject
	gobject.type_register(hd_plugin_type)
	obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")
	obj.show_all()
	gtk.main()
Gaah! The code looks very confusing here. Copy it to your favorite editor and it will hopefully look nicer

Those of you who actually know pygtk, please point out the redundant or erroreous bits. Perhaps after a while it's good enough to be put in the wiki.

Oh an btw, this widget also illustrates the label issue I mentioned. If someone can show me how to make the label background be the same 50% opacity as the button part, then I'd be a happy camper
Attached Images
    
__________________
Class .. : Meddler, Thread watcher, Developer, Helper
Humor .. : [********--] Alignment: Pacifist
Patience : [*****-----] Weapon(s): N900, N950, Metal music
Agro ... : [----------] Relic(s) : N95, NGage, Tamyia Wild One

Try Tweed Suit for your hardcore twittering needs
http://twitter.com/mece66
I like my coffee black, like my metal.

Last edited by mece; 2010-01-29 at 21:12. Reason: label opacity question
 
Posts: 87 | Thanked: 46 times | Joined on Nov 2010 @ lisbon, portugal
#46
Hello.
I was trying to add more that one layout to the widget.

I was trying to accomplish something like:

< 1 IMAGE + 2 images (top/bottom) + 2 labels (top+bottom) >
by addind a HBOX (for 1 IMAGE) and 2 VBOX (one for the 2 images and another for the 2 labels) but it seems to be impossible to add more that one.

/usr/lib/hildon-desktop/helloworld.py:115: GtkWarning: Attempting to add a widget with type GtkVBox to a helloworld+HelloHomePlugin, but as a GtkBin subclass a helloworld+HelloHomePlugin can only contain one widget at a time; it already contains a widget of type GtkHBox


Any suggestions?

Thanks
 
nicolai's Avatar
Posts: 1,637 | Thanked: 4,424 times | Joined on Apr 2009 @ Germany
#47
The homeplugin is only a GtkContainer and can not take more than one
widget. If you want to put more widgets, use another hbox or vbox widget
and put your other boxes into this.

For a more complex layout you may have to use
several nesting boxes. Or maybe another layout container
like GtkTable.
 

The Following 2 Users Say Thank You to nicolai For This Useful Post:
Posts: 87 | Thanked: 46 times | Joined on Nov 2010 @ lisbon, portugal
#48
that's exactly what i was trying to do.
so it is possible to have a main hbox with several child h/vboxes ???
I confess that while testing (as i couldn't see any result) i have moved the show_all() of each box outside the main box container.
I will try again...

thanks
 
Posts: 87 | Thanked: 46 times | Joined on Nov 2010 @ lisbon, portugal
#49
just put it to work. Now the next problem. In te above example the draw() function is called on the widget context or trough an event in the ui. How would I call this function on a backend function (answering to a dbus signal for instance). My probelm and (I'm learing on the go) is that I don't know how to pass the ui context ( button press for instance ) of the widget
if I just call widget.draw(self.e_next, '1') outside those event handler I have an error specifying that widget is not a know object( or similar).
 
Posts: 87 | Thanked: 46 times | Joined on Nov 2010 @ lisbon, portugal
#50
when I call draw(self.e_fstatus,"1") from an dbus-signal call, it gives-me this error
File "/usr/lib/hildon-desktop/helloworld.py", line 185, in draw
cr_e = target.window.cairo_create()
AttributeError: 'NoneType' object has no attribute 'cairo_create'
in the draw() function I've added
print "DEBUG: button clicked!!!" + widget.get_name()
DEBUG: drawing 0
against what shoul be.
DEBUG: drawing fmtx
 
Reply


 
Forum Jump


All times are GMT. The time now is 09:46.