1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
#!/usr/bin/env ruby
=begin
composited-windows.rb - Sample script translated from http://library.gnome.org/devel/gdk/unstable/gdk-Windows.html#composited-window-example
Copyright (c) 2008 Ruby-GNOME2 Project Team
This program is licenced under the same licence as Ruby-GNOME2.
=end
require 'gtk3'
if str = Gtk.check_version(2, 12, 0)
puts "This sample requires GTK+ 2.12.0 or later."
puts str
exit
end
unless Gdk.cairo_available?
puts "This sample requires Cairo support."
exit
end
Gtk.init
# Make the widgets
button = Gtk::Button.new("A Button")
event = Gtk::EventBox.new
window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
# Put a red background on the window
window.modify_bg(Gtk::STATE_NORMAL, Gdk::Color.parse("red"))
# Set the colourmap for the event box. Must be done before the event box is realised.
event.colormap = event.screen.rgba_colormap
# Set our event box to have a fully-transparent background
# drawn on it. Currently there is no way to simply tell GTK+
# that "transparency" is the background colour for a widget.
event.app_paintable = true
event.signal_connect('draw') do |widget, event|
# This function simply draws a transparency onto a widget on the area
# for which it receives expose events. This is intended to give the
# event box a "transparent" background.
#
# In order for this to work properly, the widget must have an RGBA
# colourmap. The widget should also be set as app-paintable since it
# doesn't make sense for GTK+ to draw a background if we are drawing it
# (and because GTK+ might actually replace our transparency with its
# default background colour).
#
cr = widget.window.create_cairo_context
cr.operator = Cairo::OPERATOR_CLEAR
cr.gdk_region(event.region)
cr.fill
false
end
# Put them inside one another
window.border_width = 10
window.add(event)
event.add(button)
# Realize and show everything
window.show_all
# Set the event box GdkWindow to be composited.
# Obviously must be performed after event box is realised.
event.window.composited = true
# Set up the compositing handler.
# Note that we do _after_ so that the normal (red) background is drawn
# by gtk before our compositing occurs.
#
window.signal_connect_after('draw') do |widget, event|
# This function performs the actual compositing of the event box onto
# the already-existing background of the window at 50% normal opacity.
#
# In this case we do not want app-paintable to be set on the widget
# since we want it to draw its own (red) background. Because of this,
# however, we must ensure that we use #signal_connect_after so that
# this handler is called after the red has been drawn. If it was
# called before then GTK would just blindly paint over our work.
#
# Note: if the child window has children, then you need a cairo 1.16
# feature to make this work correctly.
#
# get our child (in this case, the event box)
child = widget.child
# create a cairo context to draw to the window
cr = widget.window.create_cairo_context
# the source data is the (composited) event box
# NOTICE: next line generates a GTK warning, it is maybe a GTK problem, it is tracked
# at http://bugzilla.gnome.org/show_bug.cgi?id=526965
cr.set_source_pixmap(child.window, child.allocation.x, child.allocation.y)
# draw no more than our expose event intersects our child
region = Gdk::Region.new(Gdk::Rectangle.new(child.allocation.x, child.allocation.y, child.allocation.width, child.allocation.height))
region.intersect(event.region)
cr.gdk_region(region)
cr.clip
# composite, with a 50% opacity
cr.operator = Cairo::OPERATOR_OVER
cr.paint(0.5)
false
end
Gtk.main
|