Custom widget
Most toolkits usually provide only the most common widgets like buttons, text widgets, sliders etc. No toolkit can provide all possible widgets. Programmers must create such widgets by themselves. They do it by using the drawing tools provided by the toolkit. There are two possibilities. A programmer can modify or enhance an existing widget. Or he can create a custom widget from scratch.Burning widget
This is an example of a widget, that we create from scratch. This widget can be found in various media burning applications, like Nero Burning ROM.custom.rb
#!/usr/bin/rubyWe put a
# ZetCode Ruby GTK tutorial
#
# This example creates a burning
# custom widget
#
# author: jan bodnar
# website: zetcode.com
# last edited: June 2009
require 'gtk2'
class Burning < Gtk::DrawingArea
def initialize(parent)
@parent = parent
super()
@num = [ "75", "150", "225", "300",
"375", "450", "525", "600", "675" ]
set_size_request 1, 30
signal_connect "expose-event" do
expose
end
end
def expose
cr = window.create_cairo_context
draw_widget cr
end
def draw_widget cr
cr.set_line_width 0.8
cr.select_font_face("Courier",
Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL)
cr.set_font_size 11
width = allocation.width
@cur_width = @parent.get_cur_value
step = (width / 10.0).round
till = (width / 750.0) * @cur_width
full = (width / 750.0) * 700
if @cur_width >= 700
cr.set_source_rgb(1.0, 1.0, 0.72)
cr.rectangle(0, 0, full, 30)
cr.clip
cr.paint
cr.reset_clip
cr.set_source_rgb(1.0, 0.68, 0.68)
cr.rectangle(full, 0, till-full, 30)
cr.clip
cr.paint
cr.reset_clip
else
cr.set_source_rgb 1.0, 1.0, 0.72
cr.rectangle 0, 0, till, 30
cr.clip
cr.paint
cr.reset_clip
end
cr.set_source_rgb(0.35, 0.31, 0.24)
for i in (1..@num.length)
cr.move_to i*step, 0
cr.line_to i*step, 5
cr.stroke
te = cr.text_extents @num[i-1]
cr.move_to i*step-te.width/2, 15
cr.text_path @num[i-1]
cr.stroke
end
end
end
class RubyApp < Gtk::Window
def initialize
super
set_title "Burning"
signal_connect "destroy" do
Gtk.main_quit
end
set_size_request 350, 200
set_window_position Gtk::Window::POS_CENTER
@cur_value = 0
vbox = Gtk::VBox.new false, 2
scale = Gtk::HScale.new
scale.set_range 0, 750
scale.set_digits 0
scale.set_size_request 160, 35
scale.set_value @cur_value
scale.signal_connect "value-changed" do |w|
on_changed(w)
end
fix = Gtk::Fixed.new
fix.put scale, 50, 50
vbox.pack_start fix
@burning = Burning.new(self)
vbox.pack_start @burning, false, false, 0
add vbox
show_all
end
def on_changed widget
@cur_value = widget.value
@burning.queue_draw
end
def get_cur_value
return @cur_value
end
end
Gtk.init
window = RubyApp.new
Gtk.main
DrawingArea
on the bottom of the window and draw the entire widget manually. All the important code resides in the draw_widget
which is called from the expose
method of the Burning class. This widget shows graphically the total capacity of a medium and the free space available to us. The widget is controlled by a scale widget. The minimum value of our custom widget is 0, the maximum is 750. If we reach value 700, we began drawing in red colour. This normally indicates overburning. @num = [ "75", "150", "225", "300",These numbers are shown on the burning widget. They show the capacity of the medium.
"375", "450", "525", "600", "675" ]
@cur_width = @parent.get_cur_valueFrom the parent widget, we get the current value of the scale widget.
till = (width / 750.0) * @cur_widthWe use the
full = (width / 750.0) * 700
width
variable to do the transformations. Between the values of the scale and the custom widget's measures. Note that we use floating point values. We get greater precision in drawing. The till
parameter determines the total size to be drawn. This value comes from the slider widget. It is a proportion of the whole area. The full
parameter determines the point, where we begin to draw in red color. cr.set_source_rgb(1.0, 1.0, 0.72)We draw a yellow rectangle up to point, where the medium is full.
cr.rectangle(0, 0, full, 30)
cr.clip
cr.paint
cr.reset_clip
te = cr.text_extents @num[i-1]This code here draws the numbers on the burning widget. We calculate the text extents to position the text correctly.
cr.move_to i*step-te.width/2, 15
cr.text_path @num[i-1]
cr.stroke
def on_changed widgetWe get the value from the scale widget, store it in the
@cur_value = widget.value
@burning.queue_draw
end
@cur_value
variable for later use. We redraw the burning widget. Figure: Burning widget
In this chapter, we created a custom widget in GTK and Ruby programming language.
No comments:
Post a Comment