summaryrefslogtreecommitdiffstats
path: root/bin/subtle-contrib/ruby/styler.rb
diff options
context:
space:
mode:
Diffstat (limited to 'bin/subtle-contrib/ruby/styler.rb')
-rw-r--r--bin/subtle-contrib/ruby/styler.rb859
1 files changed, 859 insertions, 0 deletions
diff --git a/bin/subtle-contrib/ruby/styler.rb b/bin/subtle-contrib/ruby/styler.rb
new file mode 100644
index 0000000..a3d6e58
--- /dev/null
+++ b/bin/subtle-contrib/ruby/styler.rb
@@ -0,0 +1,859 @@
+#!/usr/bin/ruby
+#
+# @file Styler
+#
+# @copyright (c) 2010-2011, Christoph Kappel <unexist@dorfelite.net>
+# @version $Id$
+#
+# This program can be distributed under the terms of the GNU GPLv2.
+# See the file COPYING for details.
+#
+# Styler is a helper to create or change subtle color themes
+#
+# http://subforge.org/projects/subtle-contrib/wiki/Styler
+#
+
+require 'singleton'
+
+begin
+ require 'subtle/subtlext'
+rescue LoadError
+ puts ">>> ERROR: Couldn't find subtlext"
+ exit
+end
+
+begin
+ require 'gtk2'
+rescue LoadError
+ puts <<EOF
+>>> ERROR: Couldn't find the gem `gtk2'
+>>> Please install it with following command:
+>>> gem install gtk2
+EOF
+ exit
+end
+
+# Check whether subtle is running
+unless(Subtlext::Subtle.running?)
+ puts ">>> WARNING: Couldn't find running subtle"
+ #exit
+end
+
+# Check for subtlext version
+major, minor, teeny = Subtlext::VERSION.split(".").map(&:to_i)
+if(major == 0 and minor == 10 and 2945 > teeny)
+ puts ">>> ERROR: styler needs at least subtle `0.10.2945' (found: %s)" % [
+ Subtlext::VERSION
+ ]
+ exit
+end
+
+# Styler class
+module Subtle # {{{
+ module Contrib # {{{
+ class ColorButton
+ DEFAULT_COLOR = '#000000'
+
+ attr_reader :value
+
+ ## initialize {{{
+ # Create a new color button
+ # @param [String] color Default color
+ ##
+
+ def initialize(color = DEFAULT_COLOR, &block)
+ @value = color
+ @original = color
+ @callback = nil
+
+ # Create color button
+ @button = Gtk::ColorButton.new(
+ Gdk::Color.parse(color)
+ )
+
+ # Signal handler
+ @button.signal_connect('color-set') do |button|
+ # Assemble hex color
+ @value = '#%02x%02x%02x' % [
+ factor_round((button.color.red.to_f / 65535), 255),
+ factor_round((button.color.green.to_f / 65535), 255),
+ factor_round((button.color.blue.to_f / 65535), 255)
+ ]
+
+ @callback.call(@value) unless(@callback.nil?)
+
+ Styler.instance.render
+ end
+ end # }}}
+
+ ## value= {{{
+ # Set value
+ # @param [Fixnum] value New value
+ ##
+
+ def value=(value)
+ @value = value
+ @button.set_color(Gdk::Color.parse(@value))
+ end # }}}
+
+ ## attach {{{
+ # Attach color button to table
+ # @param [Table] table A #Gtk::Table
+ # @param [Fixnum] x X slot
+ # @param [Fixnum] y Y slot
+ ##
+
+ def attach(table, x, y)
+ table.attach(@button, x, x + 1, y, y + 1, Gtk::FILL, Gtk::SHRINK)
+ end # }}}
+
+ ## reset {{{
+ # Reset color button to default color
+ ##
+
+ def reset
+ @value = @original
+ @button.set_color(Gdk::Color.parse(@original))
+ end # }}}
+
+ ## callback {{{
+ # Add event callback
+ ##
+
+ def callback(&block)
+ @callback = block
+ end # }}}
+
+ private
+
+ def factor_round(val, factor) # {{{
+ val = (val * factor + 0.5).floor
+ val = val > 0 ? val : 0 #< Min
+ val = val > factor ? factor : val #< Max
+
+ val
+ end # }}}
+ end
+
+ class SpinButton
+ attr_reader :value
+
+ ## initialize {{{
+ # Create a new spin button
+ # @param [Fixnum] value Default value
+ # @param [Fixnum] min Minimum value
+ # @param [Fixnum] max Maximum value
+ ##
+
+ def initialize(value = 0, min = 0, max = 100)
+ @value = value
+ @original = value
+ @callback = nil
+
+ # Create adjustment
+ adjustment = Gtk::Adjustment.new(value, min, max, 1, 5, 0)
+
+ # Create spin button
+ @spinner = Gtk::SpinButton.new(adjustment, 0, 0)
+ @spinner.set_size_request(40, -1)
+
+ # Signal handler
+ @spinner.signal_connect('value_changed') do |spinner|
+ @value = spinner.value_as_int
+
+ @callback.call(@value) unless(@callback.nil?)
+
+ Styler.instance.render
+ end
+ end # }}}
+
+ ## value= {{{
+ # Set value
+ # @param [Fixnum] value New value
+ ##
+
+ def value=(value)
+ @value = value
+ @spinner.value = value
+ end # }}}
+
+ ## attach {{{
+ # Attach spin button to table
+ # @param [Table] table A #Gtk::Table
+ # @param [Fixnum] x X slot
+ # @param [Fixnum] y Y slot
+ ##
+
+ def attach(table, x, y)
+ table.attach(@spinner, x, x + 1, y, y + 1, Gtk::FILL, Gtk::SHRINK)
+ end # }}}
+
+ ## reset {{{
+ # Reset spin button to default value
+ ##
+
+ def reset
+ @value = @original
+ @spinner.value = @original
+ end # }}}
+
+ ## callback {{{
+ # Add event callback
+ ##
+
+ def callback(&block)
+ @callback = block
+ end # }}}
+ end
+
+ class Style
+ attr_accessor :buttons
+
+ ## reset {{{
+ # Reset elements of style
+ ##
+
+ def reset
+ @buttons.each do |k, v|
+ if v.respond_to?(:reset)
+ v.reset
+ elsif(v.is_a?(Hash))
+ v.each do |side, spin|
+ spin.reset if(spin.respond_to?(:reset))
+ end
+ end
+ end
+ end # }}}
+
+ ## append {{{
+ # Append to notebook
+ # @param [Notebook] notebook A #Gtk::Notebook
+ ##
+
+ def append(notebook)
+ label = Gtk::Label.new(@name)
+ notebook.append_page(@table, label)
+ end # }}}
+
+ ## [] {{{
+ # Acces values
+ # @param [Symbol] name Value name
+ ##
+
+ def [](name)
+ case @buttons[name]
+ when ColorButton then @buttons[name].value
+ when Hash then @buttons[name]
+ end
+ end # }}}
+
+ ## attach_label {{{
+ # Attach a label to the table
+ # @param [Fixnum] x X slot
+ # @param [Fixnum] y Y slot
+ # @param [String] caption Label caption
+ ##
+
+ def attach_label(x, y, caption)
+ label = Gtk::Label.new(caption)
+ @table.attach(label, x, x + 1, y, y + 1)
+ end # }}}
+
+ ## sum {{{
+ # Get total width of given styles
+ # @param [Array] List of styles
+ # @return [Fixnum] Width in pixel
+ ##
+
+ def sum(list)
+ width = 0
+
+ [ :border, :padding, :margin ].each do |button|
+ list.each do |l|
+ if(@buttons[button][l].respond_to?(:value))
+ width += @buttons[button][l].value
+ end
+ end
+ end
+
+ width
+ end # }}}
+
+ private
+
+ def compact(name) # {{{
+ ret = []
+ val = @buttons[name]
+
+ # Compact padding/margin values
+ if(val[:top].value == val[:bottom].value and
+ val[:top].value == val[:right].value and
+ val[:top].value == val[:left].value)
+ ret << val[:top].value
+ elsif(val[:top].value == val[:bottom].value and
+ val[:left].value == val[:right].value)
+ ret << val[:top].value
+ ret << val[:left].value
+ elsif(val[:left].value == val[:right].value)
+ ret << val[:top].value
+ ret << val[:left].value
+ ret << val[:bottom].value
+ else
+ ret = val.values.map(&:value)
+ end
+
+ ret.join(', ')
+ end # }}}
+ end
+
+ class StyleNormal < Style
+
+ ## initialize {{{
+ # Create a new style element
+ # @param [String] name Element name
+ # @param [Array] colors Color array
+ ##
+
+ def initialize(name, colors)
+ @name = name
+ @buttons = {}
+
+ # Table
+ @table = Gtk::Table.new(5, 7)
+
+ # Labels: Vertical
+ attach_label(0, 1, 'Foreground')
+ attach_label(0, 2, 'Background')
+ attach_label(0, 3, 'Top')
+ attach_label(0, 4, 'Right')
+ attach_label(0, 5, 'Bottom')
+ attach_label(0, 6, 'Left')
+
+ # Labels: Horizontal
+ attach_label(1, 0, 'Color')
+ attach_label(2, 0, 'Border')
+ attach_label(3, 0, 'Padding')
+ attach_label(4, 0, 'Margin')
+
+ # Color buttons
+ y = 1
+
+ {
+ :fg => 'fg', :bg => 'bg', :top => 'bo_top',
+ :right => 'bo_right', :bottom => 'bo_bottom', :left => 'bo_left'
+ }.each do |name, suffix|
+ @buttons[name] = ColorButton.new(
+ colors[('%s_%s' % [ @name.downcase, suffix ]).to_sym] ||
+ ColorButton::DEFAULT_COLOR
+ )
+ @buttons[name].attach(@table, 1, y)
+
+ y += 1
+ end
+
+ # Spin buttons
+ x = 2
+
+ [ :border, :padding, :margin ].each do |name|
+ @buttons[name] = {}
+ y = 3
+
+ [ :top, :right, :bottom, :left ].each do |side|
+ @buttons[name][side] = SpinButton.new(0)
+ @buttons[name][side].attach(@table, x, y)
+
+ y += 1
+ end
+
+ x += 1
+ end
+ end # }}}
+
+ ## dump {{{
+ # Print style element
+ ##
+
+ def dump
+ puts "style :#{@name.downcase} do"
+ puts " foreground '#{@buttons[:fg].value}'"
+ puts " background '#{@buttons[:bg].value}'"
+
+ # Compact borders
+ if(@buttons[:top].value == @buttons[:right].value and
+ @buttons[:top].value == @buttons[:bottom].value and
+ @buttons[:top].value == @buttons[:left].value and
+ @buttons[:border][:top].value == @buttons[:border][:left].value and
+ @buttons[:border][:top].value == @buttons[:border][:bottom].value and
+ @buttons[:border][:top].value == @buttons[:border][:right].value)
+ puts " border '#{@buttons[:top].value}', #{@buttons[:border][:top].value}"
+ else
+ puts " border_top '#{@buttons[:top].value}', #{@buttons[:border][:top].value}"
+ puts " border_right '#{@buttons[:right].value}', #{@buttons[:border][:right].value}"
+ puts " border_bottom '#{@buttons[:bottom].value}', #{@buttons[:border][:bottom].value}"
+ puts " border_left '#{@buttons[:left].value}', #{@buttons[:border][:left].value}"
+ end
+
+ puts " padding #{compact(:padding)}"
+ puts " margin #{compact(:margin)}"
+ puts "end"
+ puts
+ end # }}}
+ end
+
+ class StyleClients < Style
+
+ ## initialize {{{
+ # Create a new other element
+ # @param [String] name Element name
+ # @param [Array] colors Color array
+ ##
+
+ def initialize(name, colors)
+ @name = name
+ @table = Gtk::Table.new(5, 7)
+ @buttons = {}
+
+ # Labels: Vertical
+ attach_label(0, 1, 'Client active')
+ attach_label(0, 2, 'Client inactive')
+ attach_label(0, 3, 'Top')
+ attach_label(0, 4, 'Right')
+ attach_label(0, 5, 'Bottom')
+ attach_label(0, 6, 'Left')
+
+ # Labels: Horizontal
+ attach_label(1, 0, 'Color')
+ attach_label(2, 0, 'Border')
+ attach_label(3, 0, 'Padding')
+ attach_label(4, 0, 'Margin')
+
+ # Buttons
+ y = 1
+
+ [ :active, :inactive ].each do |name|
+ # Color button
+ @buttons[name] = ColorButton.new(
+ colors[('client_%s' % name).to_sym]
+ )
+ @buttons[name].attach(@table, 1, y)
+
+ # Border spinner
+ sym = ('%s_border' % [ name ]).to_sym
+ @buttons[sym] = SpinButton.new(2)
+ @buttons[sym].attach(@table, 2, y)
+
+ y += 1
+ end
+
+ # Margin
+ @buttons[:margin] = {}
+
+ [ :top, :right, :bottom, :left ].each do |side|
+ @buttons[:margin][side] = SpinButton.new(0)
+ @buttons[:margin][side].attach(@table, 4, y)
+
+ y += 1
+ end
+
+ # Fill remaining fields
+ @buttons[:fg] = @buttons[:active]
+ @buttons[:bg] = @buttons[:inactive]
+ @buttons[:border ] = {
+ top: @buttons[:active_border],
+ right: @buttons[:active_border],
+ bottom: @buttons[:active_border],
+ left: @buttons[:active_border]
+ }
+
+ # Just for text placement
+ @buttons[:padding] = { top: 5, right: 0, bottom: 0, left: 5 }
+ end # }}}
+
+ ## dump {{{
+ # Print style element
+ ##
+
+ def dump
+ puts <<STYLE
+style :#{@name.downcase} do
+ active '#{@buttons[:active].value}'
+ inactive '#{@buttons[:inactive].value}'
+ margin #{compact(:margin)}
+end\n
+STYLE
+ end # }}}
+ end
+
+ class StyleSubtle < Style
+
+ ## initialize {{{
+ # Create a new other element
+ # @param [String] name Element name
+ # @param [Array] colors Color array
+ ##
+
+ def initialize(name, colors)
+ @name = name
+ @table = Gtk::Table.new(5, 7)
+ @buttons = {}
+
+ # Labels: Vertical
+ attach_label(0, 1, 'Panel top')
+ attach_label(0, 2, 'Panel bottom')
+ attach_label(0, 3, 'Background')
+ attach_label(0, 4, 'Stipple')
+ attach_label(0, 5, 'Top')
+ attach_label(0, 6, 'Right')
+ attach_label(0, 7, 'Bottom')
+ attach_label(0, 8, 'Left')
+
+ # Labels: Horizontal
+ attach_label(1, 0, 'Color')
+ attach_label(2, 0, 'Border')
+ attach_label(3, 0, 'Padding')
+ attach_label(4, 0, 'Margin')
+
+ # Buttons
+ y = 1
+
+ [ :panel_top, :panel_bottom, :background, :stipple ].each do |name|
+ # Color button
+ @buttons[name] = ColorButton.new(colors[name])
+ @buttons[name].attach(@table, 1, y)
+
+ y += 1
+ end
+
+ # Padding
+ @buttons[:padding] = {}
+
+ [ :top, :right, :bottom, :left ].each do |side|
+ @buttons[:padding][side] = SpinButton.new(0)
+ @buttons[:padding][side].attach(@table, 3, y)
+
+ y += 1
+ end
+ end # }}}
+
+ ## dump {{{
+ # Print style element
+ ##
+
+ def dump
+ puts "style :#{@name.downcase} do"
+
+ # Compact panel colors
+ if(@buttons[:panel_top].value == @buttons[:panel_bottom].value)
+ puts " panel '#{@buttons[:panel_top].value}'"
+ else
+ puts " panel_top '#{@buttons[:panel_top].value}'"
+ puts " panel_bottom '#{@buttons[:panel_bottom].value}'"
+ end
+
+ puts " background '#{@buttons[:background].value}'"
+ puts " stipple '#{@buttons[:stipple].value}'"
+ puts " padding #{compact(:padding)}"
+ puts "end"
+ puts
+ end # }}}
+ end
+
+ class Styler < Gtk::Window
+ include Singleton
+
+ BORDER_WIDTH = 2
+ WINDOW_WIDTH = 790
+ AREA_WIDTH = WINDOW_WIDTH - 16 #< Padding + spacing
+ CLIENT_WIDTH = (AREA_WIDTH - 2 * BORDER_WIDTH) / 2
+
+ WINDOW_HEIGHT = 540
+ AREA_HEIGHT = 150
+
+ ## initialize {{{
+ # Init window
+ ##
+
+ def initialize
+ super
+
+ # Options
+ set_title('Styler for subtle #{Subtlext::VERSION}')
+ set_wmclass('styler', 'subtle')
+ set_resizable(false)
+ set_keep_above(true)
+ set_size_request(WINDOW_WIDTH, WINDOW_HEIGHT)
+ set_window_position(Gtk::Window::POS_CENTER)
+ stick
+
+ # Signals {{{
+ signal_connect('delete_event') do
+ false
+ end
+
+ signal_connect('destroy') do
+ Gtk.main_quit
+ end # }}}
+
+ # Alignment
+ align = Gtk::Alignment.new(0.5, 0.5, 0.5, 0.5)
+ align.set_padding(7, 7, 7, 7)
+ add(align)
+
+ # Vbox
+ vbox = Gtk::VBox.new()
+ align.add(vbox)
+
+ # Frame {{{
+ frame = Gtk::Frame.new
+ frame.set_border_width(0)
+ frame.set_shadow_type(Gtk::SHADOW_NONE)
+ vbox.pack_start(frame) # }}}
+
+ # Area {{{
+ @area = Gtk::DrawingArea.new
+ @area.set_size_request(AREA_WIDTH, AREA_HEIGHT)
+ @area.signal_connect('expose_event') do
+ expose(@area.window.create_cairo_context)
+ end
+ frame.add(@area) # }}}
+
+ # Notebook {{{
+ notebook = Gtk::Notebook.new
+ notebook.set_tab_pos(Gtk::PositionType::LEFT)
+ vbox.pack_start(notebook, true, false, 5) # }}}
+
+ # Styles {{{
+ colors = {}
+ Subtlext::Subtle.colors.map { |k, v| colors[k] = v.to_hex }
+ @styles = {}
+
+ # Styles and pages
+ [
+ 'all', 'title', 'views', 'focus', 'urgent',
+ 'occupied', 'sublets', 'separator'
+ ].each do |caption|
+ sym = caption.to_sym
+ @styles[sym] = StyleNormal.new(caption.capitalize, colors)
+ @styles[sym].append(notebook)
+ end
+
+ # Clients
+ @styles[:clients] = StyleClients.new('Clients', colors)
+ @styles[:clients].append(notebook)
+
+ # Subtle
+ @styles[:subtle] = StyleSubtle.new('Subtle', colors)
+ @styles[:subtle].append(notebook)
+
+ # All: Update border, padding and margin
+ [ :border, :padding, :margin ].each do |name|
+ [ :top, :right, :bottom, :left ].each do |side|
+ @styles[:all].buttons[name][side].callback do |value|
+ [
+ :title, :views, :focus, :urgent,
+ :occupied, :sublets, :separator
+ ].each do |style|
+ @styles[style].buttons[name][side].value = value
+ end
+ end
+ end
+ end
+
+ # All: Update colors
+ [ :fg, :bg, :top, :right, :bottom, :left ].each do |name|
+ @styles[:all].buttons[name].callback do |value|
+ [
+ :title, :views, :focus, :urgent,
+ :occupied, :sublets, :separator
+ ].each do |style|
+ @styles[style].buttons[name].value = value
+ end
+ end
+ end # }}}
+
+ # Hbox
+ hbox = Gtk::HButtonBox.new
+ vbox.pack_start(hbox, false, false, 5)
+
+ # Print button {{{
+ button = Gtk::Button.new('Print')
+ hbox.pack_start(button, false, false, 2)
+ button.signal_connect('clicked') do
+ @styles.select { |k, v| :all != k }.each do |k, v|
+ v.dump
+ end
+ end # }}}
+
+ # Reset button {{{
+ button = Gtk::Button.new('Reset')
+ hbox.pack_start(button, false, false, 2)
+ button.signal_connect('clicked') do
+ @styles.each do |k, v|
+ if v.respond_to? :reset
+ v.reset
+ end
+ end
+
+ @area.signal_emit('expose-event', nil)
+ end # }}}
+
+ # Exit button {{{
+ button = Gtk::Button.new('Exit')
+ hbox.pack_start(button, false, false, 2)
+ button.signal_connect('clicked') do
+ Gtk.main_quit
+ end # }}}
+
+ show_all
+ end # }}}
+
+ ## render {{{
+ # Render preview
+ ##
+
+ def render
+ @area.signal_emit('expose-event', nil)
+ end # }}}
+
+ private
+
+ def expose(cr) # {{{
+ # Font face, size and height
+ cr.select_font_face('Arial', 'normal')
+ cr.set_font_size(12)
+
+ extents = cr.font_extents
+ @font_height = extents.ascent + extents.descent + 2;
+ @font_y = (extents.height - 2 + extents.ascent) / 2
+
+ # Calculate item heights
+ panel_height = @font_height
+
+ [
+ :title, :views, :focus, :urgent,
+ :occupied, :sublets, :separator
+ ].each do |panel|
+ value = @font_height + @styles[panel].sum([ :top, :bottom ])
+
+ panel_height = value if(value > panel_height)
+ end
+
+ client_height = AREA_HEIGHT - 2 * panel_height - 2 * BORDER_WIDTH
+
+ # Border
+ cr.set_source_rgb(1.0, 0.0, 0.0)
+ cr.rectangle(0, 0, AREA_WIDTH, AREA_HEIGHT)
+ cr.fill
+
+ # Background
+ draw_rect(cr, BORDER_WIDTH, BORDER_WIDTH,
+ AREA_WIDTH - 2 * BORDER_WIDTH, AREA_HEIGHT - 2 * BORDER_WIDTH,
+ @styles[:subtle][:background])
+
+ # Panels
+ draw_rect(cr, BORDER_WIDTH, BORDER_WIDTH,
+ AREA_WIDTH - 2 * BORDER_WIDTH, panel_height,
+ @styles[:subtle][:panel_top]
+ )
+ draw_rect(cr, BORDER_WIDTH, BORDER_WIDTH + panel_height + client_height,
+ AREA_WIDTH - 2 * BORDER_WIDTH, panel_height,
+ @styles[:subtle][:panel_bottom]
+ )
+
+ # Clients
+ draw_box(cr, BORDER_WIDTH, BORDER_WIDTH + panel_height, CLIENT_WIDTH,
+ client_height, 'active', @styles[:clients])
+
+ draw_box(cr, BORDER_WIDTH + CLIENT_WIDTH, BORDER_WIDTH + panel_height,
+ CLIENT_WIDTH, client_height, 'inactive', @styles[:clients])
+
+ # Panel items
+ x = BORDER_WIDTH
+
+ [
+ 'focus', 'views', 'urgent', 'occupied', 'title'
+ ].each do |name|
+ sym = name.to_sym
+ extents = cr.text_extents(name)
+ width = @styles[sym].sum([ :left, :right ]) + extents.x_advance
+
+ draw_box(cr, x, BORDER_WIDTH, width,
+ panel_height, name, @styles[sym])
+
+ x += width
+ end
+
+ # Sublets
+ x = BORDER_WIDTH
+ {
+ 'sublet1' => :sublets, '|' => :separator, 'sublet2' => :sublets
+ }.each do |name, style|
+ extents = cr.text_extents(name)
+ width = @styles[style].sum([ :left, :right ]) + extents.x_advance
+
+ draw_box(cr, x, BORDER_WIDTH + panel_height + client_height,
+ width, panel_height, name, @styles[style])
+
+ x += width
+ end
+ end # }}}
+
+ def draw_text(cr, x, y, text, color) # {{{
+ cr.set_source_color(Gdk::Color.parse(color))
+ cr.move_to(x, y + @font_y)
+ cr.show_text(text)
+ cr.stroke
+ end # }}}
+
+ def draw_rect(cr, x, y, width, height, color) # {{{
+ cr.set_source_color(Gdk::Color.parse(color))
+ cr.rectangle(x, y, width, height)
+ cr.fill
+ end # }}}
+
+ def draw_box(cr, x, y, width, height, text, style) # {{{
+ mw = style[:margin][:left].value + style[:margin][:right].value
+ mh = style[:margin][:top].value + style[:margin][:bottom].value
+
+ # Filling
+ draw_rect(cr, x + style[:margin][:left].value,
+ y + style[:margin][:top].value, width - mw, height - mh, style[:bg])
+
+ # Borders
+ draw_rect(cr, x + style[:margin][:left].value,
+ y + style[:margin][:top].value, width - mw,
+ style[:border][:top].value,
+ text.end_with?('active') ? style[text.to_sym] : style[:top])
+
+ draw_rect(cr, x + width - style[:border][:right].value -
+ style[:margin][:right].value, y + style[:margin][:top].value,
+ style[:border][:right].value, height - mh,
+ text.end_with?('active') ? style[text.to_sym] : style[:right])
+
+ draw_rect(cr, x + style[:margin][:left].value, y + height -
+ style[:border][:bottom].value - style[:margin][:bottom].value,
+ width - mw, style[:border][:bottom].value,
+ text.end_with?('active') ? style[text.to_sym] : style[:bottom])
+
+ draw_rect(cr, x + style[:margin][:left].value,
+ y + style[:margin][:top].value, style[:border][:left].value,
+ height - mh,
+ text.end_with?('active') ? style[text.to_sym] : style[:left])
+
+ # Text
+ draw_text(cr, x + style.sum([ :left ]),
+ y + style.sum([ :top ]), text, style[:fg]
+ )
+ end # }}}
+ end
+ end # }}}
+end # }}}
+
+# Implicitly run<
+if __FILE__ == $0
+ Gtk.init
+ Subtle::Contrib::Styler.instance
+ Gtk.main
+end
+
+# vim:ts=2:bs=2:sw=2:et:fdm=marker