Create  Edit  FrontPage  Index  Search  Changes  History  RSS  Login

tut-gtk2-colorsel-buttons

Color Button

ColorButtons01.png

Gtk::ColorButton widget is a member of the so called family of Selectors widgets. In the Gtk documentation you will find them under the heading Selectors (File/Font/Color/Input Devices). Gtk::ColorButton is used to interactively set foreground or background colour to widgets. Here is a Ruby version of a C Gtk+ program that allows user to dynamically change the foreground colour of the text on a label. After clicking the blue button on "Color Buttons" window above the following "Color Dialog" window opens. User dials (selects) the colour (in our case red). After clicking on the "OK" button, the colour dialogue widget ("w" in the callback block (see "label.modify_fg(Gtk::STATE_NORMAL, w.color)") sets the colour of the label in the calling window.

The colour button itself displays the selected colour in a rectangular block set as a the child widget of the button. You can see an example of this in the figure above on the right, and the figure below is the dialogue that allows user to enter in the color value or browse for a choice on the colour wheel. The colour wheel is provided so the is not required to know the numeric values of the colours. Note by user we do not mean the programmer.

color = Gdk::Color.parse("#003366")
cbutton = Gtk::ColorButton.new(color)

More often than not you will want to set the initial colour of the Gtk::ColorButton. This is done in two steps. First you need to create a Gdk::Color object with either Gdk::Color.parse("#RRGGBB") or with Gdk::Color.new(red, green, blue). Note that parse is a hex triple where each RR, GG, and BB can range from 00-FF, however parameters of the Gdk::Color.new(red, green, blue) can range from 0 to 65535. The second step is to create the Gtk::ColorButton.new(color=nil). Nil tells us that the color object parameter is optional. In that case the rectangular widget in the Gtk::ColorButton will be black.

In the example program we use Gdk::Color.parse, so let us briefly look at this method:

Gdk::Color.parse(spec)
Parses a textual specification of a color and fill in the red, green, and blue fields of a Gdk::Color structure. The color is not allocated, you must call Gdk::Colormap#alloc_color yourself. The text string can be in any of the forms accepted by XParseColor; these include name for a color from rgb.txt, such as "DarkSlateGray", or a hex specification such as "#305050". If spec can't be parsed, the ArgumentError will be occured.
  • spec: the string specifying the color.
  • Returns: the Gdk::Color

ColorSelDialog.png
The above action (colour selection) results in changing the colour of the text on the label below.
ColorButtons02.png

#!/usr/bin/env ruby
require 'gtk2'

window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
window.set_title  "Color Buttons"
window.border_width = 10
window.signal_connect('delete_event') { Gtk.main_quit }
window.set_size_request(250, -1)

# Create a Gdk::Color object you use either:
color = Gdk::Color.parse("#003366")

cbutton = Gtk::ColorButton.new(color)
label   = Gtk::Label.new("Look at my color")
cbutton.title = "Select color for your widget"

label.modify_fg(Gtk::STATE_NORMAL, color)

# Obtain the selected color and change a desired widget
# (label). The {{ color_set }} signal is emitted when
# the user selects a color. When handling this signal,
# use {{ Gtk::ColorButton#color }} and
# {{ Gtk::ColorButton#alpha }} to find out which color
# was selected in the ColorSelectionDialog.

cbutton.signal_connect('color_set') do |w|
  label.modify_fg(Gtk::STATE_NORMAL, w.color)
end

hbox = Gtk::HBox.new(true, 5)
hbox.pack_start(cbutton, false, true, 0)
hbox.pack_start(label,   false, true, 0)
vbox = Gtk::VBox.new(true, 5)
vbox.pack_start(hbox, false, true, 0)

window.add(vbox)
window.show_all
Gtk.main

Modifying the foreground colour of a widget

To modify the foreground colour of a widget you need to identify the state in which the widget is in. Our widget is Label, and most often this widget is found in normal state "Gtk::STATE_NORMAL". However "Labels" can also be selected (highlighted) by a user, in that case widget would be in "Gtk::STATE_SELECTED". As you can see in the code the colour of the text on our Label object is changed by the following code: Gtk::Widget#modify_fg(state, color). Where "state" parameter is one of the GtkStateType constants, as described earlier, and the "color" parameter is a "Gdk::Color" object you can obtain by either Gdk::Color.parse("#RRGGBB") or Gdk::Color.new(red, green, blue).

color = Gdk::Color.new(0, 12345, 34567)
Gtk::Widget#modify_fg(Gtk::STATE_NORMAL, color)

NOTE: red, green and blue colour values in the first class method called "parse" are 0-256 (00-FF), but in the constructor "new" the same colour values are between 0 and 65535.

GtkStateType
This constant indicates the current state of a widget; the state determines how the widget is drawn. The GtkStateType is also used to identify different colours in a Gtk::Style for drawing, so states can be used for sub-parts of a widget as well as entire widgets.
  • STATE_NORMAL - State during normal operation.
  • STATE_ACTIVE - State of a currently active widget, such as a depressed button.
  • STATE_PRELIGHT - State indicating that the mouse pointer is over the widget and the widget will respond to mouse clicks.
  • STATE_SELECTED - State of a selected item, such the selected row in a list.
  • STATE_INSENSITIVE - State indicating that the widget is unresponsive to user actions.
Following is a different example from the original Japanese tutorial page:


ColorButtons-jp-070-29.png

#!/usr/bin/env ruby

require 'gtk2'

def area_event(area, e)
      if Gdk::EventButton === e
             colorsel_d = Gtk::ColorSelectionDialog.new("Select background color")
             color = area.modifier_style.bg(Gtk::STATE_NORMAL)
             colorsel = colorsel_d.colorsel
             colorsel.previous_color = color
             colorsel.current_color = color

             colorsel.has_palette = true
             colorsel.has_opacity_control = true
             colorsel.signal_connect("color_changed") do |w|
                     ncolor = w.current_color
                     area.modify_bg(Gtk::STATE_NORMAL, ncolor)
             end
             unless colorsel_d.run == Gtk::ColorSelectionDialog::RESPONSE_OK
                     area.modify_bg(Gtk::STATE_NORMAL, color)
             end
             colorsel_d.destroy
             true
     else
             false
     end
end

window = Gtk::Window.new
window.title = "Color Selection test"
window.resizable = true

window.signal_connect("delete_event") do
     Gtk.main_quit
     true
end

drawingarea = Gtk::DrawingArea.new
drawingarea.modify_bg(Gtk::STATE_NORMAL, Gdk::Color.new(0, 0, 65535))

window.set_size_request(200, 200)
drawingarea.set_events(Gdk::Event::BUTTON_PRESS_MASK)
drawingarea.signal_connect("event") {|w, e| area_event(w, e)}

window.add(drawingarea)
window.show_all

Gtk.main
Last modified:2009/01/26 05:30:37
Keyword(s):
References:[tut-gtk] [tut-gtk2-selchoose] [tut-gtk2-btt]