diff options
author | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-04-09 09:27:54 +0000 |
---|---|---|
committer | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-04-09 09:27:54 +0000 |
commit | 54f84a1246443ce50e30b5142339e33f3a95c640 (patch) | |
tree | fb9148aad230bba9dc69884b7d706f4ae58c0aae /ext/tk/sample/tkextlib/tile | |
parent | 232773bf1554e01b0681a86259770be56bc68536 (diff) | |
download | ruby-54f84a1246443ce50e30b5142339e33f3a95c640.tar.gz ruby-54f84a1246443ce50e30b5142339e33f3a95c640.tar.xz ruby-54f84a1246443ce50e30b5142339e33f3a95c640.zip |
* ext/tk/lib/tk.rb: update RELEASE_DATE
* ext/tk/lib/tk/image.rb: support to create TkImage object without
creating a new image object on Tk.
* ext/tk/lib/tk/menu.rb: use TkCommandNames on create_self()
* ext/tk/lib/tk/root.rb: TkRoot.to_eval() returns '.'.
* ext/tk/lib/tk/text.rb: add methods to create a TkText::IndexString
from (x, y) coords.
* ext/tk/lib/tkextlib/tile.rb: bug fix and update support status.
* ext/tk/lib/tkextlib/tile/*.rb: ditto.
* ext/tk/sample/tkextlib/tile: New demo.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8@8291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk/sample/tkextlib/tile')
19 files changed, 1337 insertions, 0 deletions
diff --git a/ext/tk/sample/tkextlib/tile/Orig_LICENSE.txt b/ext/tk/sample/tkextlib/tile/Orig_LICENSE.txt new file mode 100644 index 000000000..2326ef21f --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/Orig_LICENSE.txt @@ -0,0 +1,30 @@ + + ###################################################################### + ### The following text is the original 'license.terms' of tile ### + ### extension. ### + ###################################################################### + + +LICENSE ("MIT-style") + +This software is Copyright (C) 2003 Joe English and other parties. + +The following terms apply to all files associated with this software +unless explicitly disclaimed in individual files. + +The author(s) hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS for a PARTICULAR PURPOSE. IN NO EVENT +shall the AUTHORS of THIS SOFTWARE be LIABLE to ANY PARTY for +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, or CONSEQUENTIAL DAMAGES +arising out of the USE of THIS SOFTWARE and its DOCUMENTATION. diff --git a/ext/tk/sample/tkextlib/tile/demo.rb b/ext/tk/sample/tkextlib/tile/demo.rb new file mode 100644 index 000000000..7851e879c --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/demo.rb @@ -0,0 +1,742 @@ +#!/usr/bin/env ruby +# +# Demo for 'tile' package. +# +require 'tk' + +demodir = File.dirname($0) +Tk::AUTO_PATH.lappend('.', demodir, File.join(demodir, 'themes')) + +require 'tkextlib/tile' + +Tk.load_tclscript(File.join(demodir, 'toolbutton.tcl')) + +# This forces an update of the available packages list. It's required +# for package names to find the themes in demos/themes/*.tcl +Tk.tk_call(TkPackage.unknown_proc, 'Tcl', TkPackage.provide('Tcl')) + +TkRoot.new{ + title 'Tile demo' + iconname 'Tile demo' +} + +# The descriptive names of the builtin themes. +$THEMELIST = [ + ['default', 'Classic'], + ['alt', 'Revitalized'], + ['winnative', 'Windows native'], + ['xpnative', 'XP Native'], + ['aqua', 'Aqua'], +] + +$V = TkVariable.new_hash(:THEME => 'default', + :COMPOUND => 'top', + :CONSOLE => false, + :MENURADIO1 => 'One', + :MENUCHECK1 => true) + +# Add in any available loadable themes. +TkPackage.names.find_all{|n| n =~ /^tile::theme::/}.each{|pkg| + name = pkg.split('::')[-1] + unless $THEMELIST.assoc(name) + $THEMELIST << [name, Tk.tk_call('string', 'totitle', name)] + end +} + +# Add theme definition written by ruby +$RUBY_THEMELIST = [] +begin + load(File.join(demodir, 'themes', 'kroc.rb'), true) +rescue + $RUBY_THEMELIST << ['kroc-rb', 'Kroc (by Ruby)', false] +else + $RUBY_THEMELIST << ['kroc-rb', 'Kroc (by Ruby)', true] +end + +def makeThemeControl(parent) + c = Tk::Tile::TLabelframe.new(parent, :text=>'Theme') + $THEMELIST.each{|theme, name| + b = Tk::Tile::TRadiobutton.new(c, :text=>name, :value=>theme, + :variable=>$V.ref(:THEME), + :command=>proc{setTheme(theme)}) + b.grid(:sticky=>:ew) + unless (TkPackage.names.find{|n| n == "tile::theme::#{theme}"}) + b.state(:disabled) + end + } + $RUBY_THEMELIST.each{|theme, name, available| + b = Tk::Tile::TRadiobutton.new(c, :text=>name, :value=>theme, + :variable=>$V.ref(:THEME), + :command=>proc{setTheme(theme)}) + b.grid(:sticky=>:ew) + b.state(:disabled) unless available + } + c +end + +def makeThemeMenu(parent) + m = TkMenu.new(parent) + $THEMELIST.each{|theme, name| + m.add(:radiobutton, :label=>name, :variable=>$V.ref(:THEME), + :value=>theme, :command=>proc{setTheme(theme)}) + unless (TkPackage.names.find{|n| n == "tile::theme::#{theme}"}) + m.entryconfigure(:end, :state=>:disabled) + end + } + $RUBY_THEMELIST.each{|theme, name, available| + m.add(:radiobutton, :label=>name, :variable=>$V.ref(:THEME), + :value=>theme, :command=>proc{setTheme(theme)}) + m.entryconfigure(:end, :state=>:disabled) unless available + } + m +end + +def setTheme(theme) + if (TkPackage.names.find{|n| n == "tile::theme::#{theme}"}) + TkPackage.require("tile::theme::#{theme}") + end + Tk::Tile::Style.theme_use(theme) +end + +# +# Load icons... +# +$BUTTONS = ['open', 'new', 'save'] +$CHECKBOXES = ['bold', 'italic'] +$ICON = {} + +def loadIcons(file) + Tk.load_tclscript(file) + img_data = TkVarAccess.new('ImgData') + img_data.keys.each{|icon| + $ICON[icon] = TkPhotoImage.new(:data=>img_data[icon]) + } +end + +loadIcons(File.join(demodir, 'iconlib.tcl')) + +# +# Utilities: +# +def foreachWidget(wins, cmd) + wins.each{|w| + cmd.call(w) + foreachWidget(w.winfo_children, cmd) + } +end + +# sbstub +# Used as the :command option for a scrollbar, +# updates the scrollbar's position. +# +def sbstub(sb, cmd, num, units = 'units') + case cmd.to_s + when 'moveto' + sb.set(num, num+0.5) + + when 'scroll' + if units.to_s == 'pages' + delta = 0.2 + else + delta = 0.05 + end + current = sb.get + sb.set(current[0] + delta * num, current[1] + delta * num) + end +end + +# ... for debugging: +TkBindTag::ALL.bind('ButtonPress-3', proc{|w| $W = w}, '%W') +TkBindTag::ALL.bind('Control-ButtonPress-3', proc{|w| w.set_focus}, '%W') + +def showHelp() + Tk.messageBox(:message=>'No help yet...') +end + +# +# See toolbutton.tcl. +TkOption.add('*Toolbar.relief', :groove) +TkOption.add('*Toolbar.borderWidth', 2) + +TkOption.add('*Toolbar.Button.Pad', 2) + +$ROOT = Tk.root +$BASE = $ROOT +Tk.destroy(*($ROOT.winfo_children)) + +$TOOLBARS = [] + +# +# Toolbar button standard vs. tile comparison: +# +def makeToolbars + # + # Tile toolbar: + # + tb = Tk::Tile::TFrame.new($BASE, :class=>'Toolbar') + $TOOLBARS << tb + i = 0 + $BUTTONS.each{|icon| + i += 1 + Tk::Tile::TButton.new(tb, :text=>icon, :image=>$ICON[icon], + :compound=>$V[:COMPOUND], + :style=>:Toolbutton).grid(:row=>0, :column=>i, + :sticky=>:news) + } + $CHECKBOXES.each{|icon| + i += 1 + Tk::Tile::TCheckbutton.new(tb, :text=>icon, :image=>$ICON[icon], + :variable=>$V.ref(icon), + :compound=>$V[:COMPOUND], + :style=>:Toolbutton).grid(:row=>0, :column=>i, + :sticky=>:news) + } + + mb = Tk::Tile::TMenubutton.new(tb, :text=>'toolbar', :image=>$ICON['file'], + :compound=>$V[:COMPOUND]) + mb.configure(:menu=>makeCompoundMenu(mb)) + i += 1 + mb.grid(:row=>0, :column=>i, :sticky=>:news) + + i += 1 + tb.grid_columnconfigure(i, :weight=>1) + + # + # Standard toolbar: + # + tb = TkFrame.new($BASE, :class=>'Toolbar') + $TOOLBARS << tb + i = 0 + $BUTTONS.each{|icon| + i += 1 + TkButton.new(tb, :text=>icon, :image=>$ICON[icon], + :compound=>$V[:COMPOUND], :relief=>:flat, + :overrelief=>:raised).grid(:row=>0, :column=>i, + :sticky=>:news) + } + $CHECKBOXES.each{|icon| + i += 1 + TkCheckbutton.new(tb, :text=>icon, :image=>$ICON[icon], + :variable=>$V.ref(icon), :compound=>$V[:COMPOUND], + :indicatoron=>false, :selectcolor=>'', :relief=>:flat, + :overrelief=>:raised).grid(:row=>0, :column=>i, + :sticky=>:news) + } + + mb = TkMenubutton.new(tb, :text=>'toolbar', :image=>$ICON['file'], + :compound=>$V[:COMPOUND]) + mb.configure(:menu=>makeCompoundMenu(mb)) + i += 1 + mb.grid(:row=>0, :column=>i, :sticky=>:news) + + i += 1 + tb.grid_columnconfigure(i, :weight=>1) +end + +# +# Toolbar :compound control: +# +def makeCompoundMenu(mb) + menu = TkMenu.new(mb) + %w(text image none top bottom left right center).each{|str| + menu.add(:radiobutton, :label=>Tk.tk_call('string', 'totitle', str), + :variable=>$V.ref(:COMPOUND), :value=>str, + :command=>proc{ changeToolbars() }) + } + menu +end + +makeToolbars() + +## CONTROLS +control = Tk::Tile::TFrame.new($BASE) + +# +# Overall theme control: +# +makeThemeControl(control).grid(:sticky=>:news, :padx=>6, :ipadx=>6) +control.grid_rowconfigure(99, :weight=>1) + +def changeToolbars + foreachWidget($TOOLBARS, + proc{|w| + begin + w.compound($V[:COMPOUND]) + rescue + end + }) +end + +def scrolledWidget(parent, klass, themed, *args) + if themed + f = Tk::Tile::TFrame.new(parent) + t = klass.new(f, *args) + vs = Tk::Tile::TScrollbar.new(f) + hs = Tk::Tile::TScrollbar.new(f) + else + f = TkFrame.new(parent) + t = klass.new(f, *args) + vs = TkScrollbar.new(f) + hs = TkScrollbar.new(f) + end + t.yscrollbar(vs) + t.xscrollbar(hs) + + TkGrid.configure(t, vs, :sticky=>:news) + TkGrid.configure(hs, 'x', :sticky=>:news) + TkGrid.rowconfigure(f, 0, :weight=>1) + TkGrid.columnconfigure(f, 0, :weight=>1) + + [f, t] +end + +# +# Notebook demonstration: +# +def makeNotebook + nb = Tk::Tile::TNotebook.new($BASE, :padding=>6) + nb.enable_traversal + client = Tk::Tile::TFrame.new(nb) + nb.add(client, :text=>'Demo', :underline=>0) + nb.select(client) + + others = Tk::Tile::TFrame.new(nb) + nb.add(others, :text=>'Others', :underline=>4) + nb.add(Tk::Tile::TLabel.new(nb, :text=>'Nothing to see here...'), + :text=>'Stuff', :sticky=>:new) + nb.add(Tk::Tile::TLabel.new(nb, :text=>'Nothing to see here either.'), + :text=>'More Stuff', :sticky=>:se) + + [nb, client, others] +end + +nb, client, others = makeNotebook() + +# +# Side-by side check, radio, and menu button comparison: +# +def fillMenu(menu) + %w(above below left right flush).each{|dir| + menu.add(:command, :label=>Tk.tk_call('string', 'totitle', dir), + :command=>proc{ menu.winfo_parent.direction(dir) }) + } + menu.add(:cascade, :label=>'Submenu', :menu=>(submenu = TkMenu.new(menu))) + submenu.add(:command, :label=>'Subcommand 1') + submenu.add(:command, :label=>'Subcommand 2') + submenu.add(:command, :label=>'Subcommand 3') + + menu.add(:separator) + menu.add(:command, :label=>'Quit', :command=>proc{Tk.root.destroy}) +end + +l = Tk::Tile::TLabelframe.new(client, :text=>'Styled', :padding=>6) +r = TkLabelframe.new(client, :text=>'Standard', :padx=>6, :pady=>6) + +## Styled frame +cb = Tk::Tile::TCheckbutton.new(l, :text=>'Checkbutton', + :variable=>$V.ref(:SELECTED), :underline=>2) +rb1 = Tk::Tile::TRadiobutton.new(l, :text=>'One', :variable=>$V.ref(:CHOICE), + :value=>1, :underline=>0) +rb2 = Tk::Tile::TRadiobutton.new(l, :text=>'Two', :variable=>$V.ref(:CHOICE), + :value=>2) +rb3 = Tk::Tile::TRadiobutton.new(l, :text=>'Three', + :variable=>$V.ref(:CHOICE), + :value=>3, :underline=>0) +btn = Tk::Tile::TButton.new(l, :text=>'Button', :underline=>0) + +mb = Tk::Tile::TMenubutton.new(l, :text=>'Menubutton', :underline=>2) +#m = TkMenu.new(mb) +#mb.menu(m) +#fillMenu(m) + +$entryText = TkVariable.new('Entry widget') +e = Tk::Tile::TEntry.new(l, :textvariable=>$entryText) +e.selection_range(6, :end) + +ltext_f, ltext = scrolledWidget(l, TkText, true, + :width=>12, :height=>5, :wrap=>:none) + +scales = Tk::Tile::TFrame.new(l) +sc = Tk::Tile::TScale.new(scales, :orient=>:horizontal, :from=>0, :to=>100, + :variable=>$V.ref(:SCALE)) +vsc = Tk::Tile::TScale.new(scales, :orient=>:vertical, :from=>-25, :to=>25, + :variable=>$V.ref(:VSCALE)) + +prg = Tk::Tile::TProgress.new(scales, :orient=>:horizontal, + :from=>0, :to=>100) +vprg = Tk::Tile::TProgress.new(scales, :orient=>:vertical, + :from=>-25, :to=>25) + +sc.command{|*args| prg.set(*args)} +vsc.command{|*args| vprg.set(*args)} + +Tk.grid(sc, :columnspan=>2, :sticky=>:ew) +Tk.grid(prg, :columnspan=>2, :sticky=>:ew) +Tk.grid(vsc, vprg, :sticky=>:nws) +TkGrid.columnconfigure(scales, 0, :weight=>1) +TkGrid.columnconfigure(scales, 1, :weight=>1) + +# NOTE TO MAINTAINERS: +# The checkbuttons are -sticky ew / -expand x on purpose: +# it demonstrates one of the differences between TCheckbuttons +# and standard checkbuttons. +# +Tk.grid(cb, :sticky=>:ew) +Tk.grid(rb1, :sticky=>:ew) +Tk.grid(rb2, :sticky=>:ew) +Tk.grid(rb3, :sticky=>:ew) +Tk.grid(btn, :sticky=>:ew, :padx=>2, :pady=>2) +Tk.grid(mb, :sticky=>:ew, :padx=>2, :pady=>2) +Tk.grid(e, :sticky=>:ew, :padx=>2, :pady=>2) +Tk.grid(ltext_f, :sticky=>:news) +Tk.grid(scales, :sticky=>:news, :pady=>2) + +TkGrid.columnconfigure(l, 0, :weight=>1) +TkGrid.rowconfigure(l, 7, :weight=>1) # text widget (grid is a PITA) + +## Orig frame +cb = TkCheckbutton.new(r, :text=>'Checkbutton', :variable=>$V.ref(:SELECTED)) +rb1 = TkRadiobutton.new(r, :text=>'One', + :variable=>$V.ref(:CHOICE), :value=>1) +rb2 = TkRadiobutton.new(r, :text=>'Two', :variable=>$V.ref(:CHOICE), + :value=>2, :underline=>1) +rb3 = TkRadiobutton.new(r, :text=>'Three', + :variable=>$V.ref(:CHOICE), :value=>3) +btn = TkButton.new(r, :text=>'Button') + +mb = TkMenubutton.new(r, :text=>'Menubutton', :underline=>3, :takefocus=>true) +m = TkMenu.new(mb) +mb.menu(m) +$V[:rmbIndicatoron] = mb.indicatoron +m.add(:checkbutton, :label=>'Indicator?', #' + :variable=>$V.ref(:rmbIndicatoron), + :command=>proc{mb.indicatoron($V[:rmbIndicatoron].value)}) +m.add(:separator) +fillMenu(m) + +e = TkEntry.new(r, :textvariable=>$entryText) + +rtext_f, rtext = scrolledWidget(r, TkText, false, + :width=>12, :height=>5, :wrap=>:none) + +sc = TkScale.new(r, :orient=>:horizontal, :from=>0, :to=>100, + :variable=>$V.ref(:SCALE)) +vsc = TkScale.new(r, :orient=>:vertical, :from=>-25, :to=>25, + :variable=>$V.ref(:VSCALE)) + +Tk.grid(cb, :sticky=>:ew) +Tk.grid(rb1, :sticky=>:ew) +Tk.grid(rb2, :sticky=>:ew) +Tk.grid(rb3, :sticky=>:ew) +Tk.grid(btn, :sticky=>:ew, :padx=>2, :pady=>2) +Tk.grid(mb, :sticky=>:ew, :padx=>2, :pady=>2) +Tk.grid(e, :sticky=>:ew, :padx=>2, :pady=>2) +Tk.grid(rtext_f, :sticky=>:news) +Tk.grid(sc, :sticky=>:news) +Tk.grid(vsc, :sticky=>:nws) + +TkGrid.columnconfigure(l, 0, :weight=>1) +TkGrid.rowconfigure(l, 7, :weight=>1) # text widget (grid is a PITA) + +Tk.grid(l, r, :sticky=>:news, :padx=>6, :pady=>6) +TkGrid.rowconfigure(client, 0, :weight=>1) +TkGrid.columnconfigure(client, [0, 1], :weight=>1) + +# +# Add some text to the text boxes: +# +msgs = [ +"The cat crept into the crypt, crapped and crept out again", +"Peter Piper picked a peck of pickled peppers", +"How much wood would a woodchuck chuck if a woodchuck could chuck wood", +"He thrusts his fists against the posts and still insists he sees the ghosts", +"Who put the bomb in the bom-b-bom-b-bom,", +"Is this your sister's sixth zither, sir?", +"Who put the ram in the ramalamadingdong?", +"I am not the pheasant plucker, I'm the pheasant plucker's mate." +] + +nmsgs = msgs.size +(0...50).each{|n| + msg = msgs[n % nmsgs] + ltext.insert(:end, "#{n}: #{msg}\n") + rtext.insert(:end, "#{n}: #{msg}\n") +} + +# +# Command box: +# +cmd = Tk::Tile::TFrame.new($BASE) +b_close = Tk::Tile::TButton.new(cmd, :text=>'Close', + :underline=>0, :default=>:normal, + :command=>proc{Tk.root.destroy}) +b_help = Tk::Tile::TButton.new(cmd, :text=>'Help', :underline=>0, + :default=>:normal, :command=>proc{showHelp()}) +Tk.grid('x', b_close, b_help, :pady=>[6, 4], :padx=>4) +TkGrid.columnconfigure(cmd, 0, :weight=>1) + +# +# Set up accelerators: +# +$ROOT.bind('KeyPress-Escape', proc{Tk.event_generate(b_close, '<Invoke>')}) +$ROOT.bind('<Help>', proc{Tk.event_generate(b_help, '<Invoke>')}) +Tk::Tile::KeyNav.enableMnemonics($ROOT) +Tk::Tile::KeyNav.defaultButton(b_help) + +Tk.grid($TOOLBARS[0], '-', :sticky=>:ew) +Tk.grid($TOOLBARS[1], '-', :sticky=>:ew) +Tk.grid(control, nb, :sticky=>:news) +Tk.grid(cmd, '-', :sticky=>:ew) +TkGrid.columnconfigure($ROOT, 1, :weight=>1) +TkGrid.rowconfigure($ROOT, 2, :weight=>1) + +# +# Add a menu +# +menu = TkMenu.new($BASE) +$ROOT.menu(menu) +m_file = TkMenu.new(menu, :tearoff=>0) +menu.add(:cascade, :label=>'File', :underline=>0, :menu=>m_file) +m_file.add(:command, :label=>'Open', :underline=>0, + :compound=>:left, :image=>$ICON['open']) +m_file.add(:command, :label=>'Save', :underline=>0, + :compound=>:left, :image=>$ICON['save']) +m_file.add(:separator) +m_f_test = TkMenu.new(menu, :tearoff=>0) +m_file.add(:cascade, :label=>'Test submenu', :underline=>0, :menu=>m_f_test) +m_file.add(:checkbutton, :label=>'Text check', :underline=>5, + :variable=>$V.ref(:MENUCHECK1)) +m_file.insert(:end, :separator) + +if Tk.windowingsystem != 'x11' + m_file.insert(:end, :checkbutton, :label=>'Console', :underline=>5, + :variable=>$V.ref(:CONSOLE), :command=>proc{toggle_console()}) + def toggle_console + if TkComm.bool($V[:CONSOLE]) + TkConsole.show + else + TkConsole.hide + end + end +end + +m_file.add(:command, :label=>'Exit', :underline=>1, + :command=>proc{Tk.event_generate(b_close, '<Invoke>')}) + +%w(One Two Three Four).each{|lbl| + m_f_test.add(:radiobutton, :label=>lbl, :variable=>$V.ref(:MENURADIO1)) +} + +# Add Theme menu. +# +menu.add(:cascade, :label=>'Theme', :underline=>3, + :menu=>makeThemeMenu(menu)) + +setTheme($V[:THEME]) + +# +# Other demos: +# +$Timers = {:StateMonitor=>nil, :FocusMonitor=>nil} + +msg = TkMessage.new(others, :aspect=>200) + +$Desc = {} + +showDescription = TkBindTag.new +showDescription.bind('Enter', proc{|w| msg.text($Desc[w.path])}, '%W') +showDescription.bind('Leave', proc{|w| msg.text('')}, '%W') + +[ + [ :trackStates, "Widget states...", + "Display/modify widget state bits" ], + + [ :scrollbarResizeDemo, "Scrollbar resize behavior...", + "Shows how Tile and standard scrollbars differ when they're sized too large" ], + + [ :trackFocus, "Track keyboard focus..." , + "Display the name of the widget that currently has focus" ] +].each{|demo_cmd, label, description| + b = Tk::Tile::TButton.new(others, :text=>label, + :command=>proc{ self.__send__(demo_cmd) }) + $Desc[b.path] = description + b.bindtags <<= showDescription + + b.pack(:side=>:top, :expand=>false, :fill=>:x, :padx=>6, :pady=>6) +} + +msg.pack(:side=>:bottom, :expand=>true, :fill=>:both) + + +# +# Scrollbar resize demo: +# +$scrollbars = nil + +def scrollbarResizeDemo + if $scrollbars + begin + $scrollbars.destroy + rescue + end + end + $scrollbars = TkToplevel.new(:title=>'Scrollbars', :geometry=>'200x200') + f = TkFrame.new($scrollbars, :height=>200) + tsb = Tk::Tile::TScrollbar.new(f, :command=>proc{|*args| sbstub(tsb, *args)}) + sb = TkScrollbar.new(f, :command=>proc{|*args| sbstub(sb, *args)}) + Tk.grid(tsb, sb, :sticky=>:news) + + sb.set(0, 0.5) # prevent backwards-compatibility mode for old SB + + f.grid_columnconfigure(0, :weight=>1) + f.grid_columnconfigure(1, :weight=>1) + f.grid_rowconfigure(0, :weight=>1) + + f.pack(:expand=>true, :fill=>:both) +end + +# +# Track focus demo: +# +$FocusInf = TkVariable.new_hash +$focus = nil + +def trackFocus + if $focus + begin + $focus.destroy + rescue + end + end + $focus = TkToplevel.new(:title=>'Keyboard focus') + i = 0 + [ + ["Focus widget:", :Widget], + ["Class:", :WidgetClass], + ["Next:", :WidgetNext], + ["Grab:", :Grab], + ["Status:", :GrabStatus] + ].each{|label, var_index| + Tk.grid(Tk::Tile::TLabel.new($focus, :text=>label, :anchor=>:e), + Tk::Tile::TLabel.new($focus, + :textvariable=>$FocusInf.ref(var_index), + :width=>40, :anchor=>:w, :relief=>:groove), + :sticky=>:ew) + i += 1 + } + $focus.grid_columnconfigure(1, :weight=>1) + $focus.grid_rowconfigure(i, :weight=>1) + + $focus.bind('Destroy', proc{Tk.after_cancel($Timers[:FocusMonitor])}) + focusMonitor +end + +def focusMonitor + $FocusInf[:Widget] = focus_win = Tk.focus + if focus_win + $FocusInf[:WidgetClass] = focus_win.winfo_classname + $FocusInf[:WidgetNext] = Tk.focus_next(focus_win) + else + $FocusInf[:WidgetClass] = $FocusInf[:WidgetNext] = '' + end + + $FocusInf[:Grab] = grab_wins = Tk.current_grabs + unless grab_wins.empty? + $FocusInf[:GrabStatus] = grab_wins[0].grab_status + else + $FocusInf[:GrabStatus] = '' + end + + $Timers[:FocusMonitor] = Tk.after(200, proc{ focusMonitor() }) +end + +# +# Widget state demo: +# + +$Widget = TkVariable.new + +TkBindTag::ALL.bind('Control-Shift-ButtonPress-1', + proc{|w| + $Widget.value = w + updateStates() + Tk.callback_break + }, '%W') +$states_list = %w(active disabled focus pressed selected + background indeterminate invalid default) +$states_btns = {} +$states = nil + +$State = TkVariable.new_hash + +def trackStates + if $states + begin + $state.destroy + rescue + end + end + $states = TkToplevel.new(:title=>'Widget states') + + l_inf = Tk::Tile::TLabel.new($states, :text=>"Press Control-Shift-Button-1 on any widget") + + l_lw = Tk::Tile::TLabel.new($states, :text=>'Widget:', + :anchor=>:e, :relief=>:groove) + l_w = Tk::Tile::TLabel.new($states, :textvariable=>$Widget, + :anchor=>:w, :relief=>:groove) + + Tk.grid(l_inf, '-', :sticky=>:ew, :padx=>6, :pady=>6) + Tk.grid(l_lw, l_w, :sticky=>:ew) + + $states_list.each{|st| + cb = Tk::Tile::TCheckbutton.new($states, :text=>st, + :variable=>$State.ref(st), + :command=>proc{ changeState(st) }) + $states_btns[st] = cb + Tk.grid('x', cb, :sticky=>:nsew) + } + + $states.grid_columnconfigure(1, :weight=>1) + + f_cmd = Tk::Tile::TFrame.new($states) + Tk.grid('x', f_cmd, :sticky=>:nse) + + b_close = Tk::Tile::TButton.new(f_cmd, :text=>'Close', + :command=>proc{ $states.destroy }) + Tk.grid('x', b_close, :padx=>4, :pady=>[6,4]) + f_cmd.grid_columnconfigure(0, :weight=>1) + + $states.bind('KeyPress-Escape', proc{Tk.event_generate(b_close, '<Invoke>')}) + + $states.bind('Destroy', proc{Tk.after_cancel($Timers[:StateMonitor])}) + stateMonitor() +end + +def stateMonitor + updateStates() if $Widget.value != '' + $Timers[:StateMonitor] = Tk.after(200, proc{ stateMonitor() }) +end + +def updateStates + $states_list.each{|st| + begin + $State[st] = $Widget.window.instate(st) + rescue + $states_btns[st].state('disabled') + else + $states_btns[st].state('!disabled') + end + } +end + +def changeState(st) + if $Widget.value != '' + if $State.bool_element(st) + $Widget.window.state(st) + else + $Widget.window.state("!#{st}") + end + end +end + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/tile/iconlib.tcl b/ext/tk/sample/tkextlib/tile/iconlib.tcl new file mode 100644 index 000000000..9a93ece50 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/iconlib.tcl @@ -0,0 +1,110 @@ +array set ImgData { +bold {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAI6hI+py60U3wj+ +RYQFJYRvEWFBCeFbRFhQQvhG8YPgX0RYUEL4FhEWlBC+RYQFJYQPFN8IPqYut/8hBQA7} +copy {R0lGODlhEAAQAJEAANnZ2QAAAP///wAAhCH5BAEAAAAALAAAAAAQABAAAAJUhI8JFJ/gY4iI +UEL4FyIiFIXgW0iEUDgfACBI9pzMAAGRiIghWSMDECR7JEKGtkFIRFBG+TIQKDQxtgzcDcmX +IfgwQrFlCD4MyZch+EDzj+Bj6mYBADs=} +cut {R0lGODlhEAAQAJEAANnZ2QAAAAAAhP///yH5BAEAAAAALAAAAAAQABAAAAJFhI+pcUHwEeIi +E0gACIKPEAFBIXy0gMg8EhM+YmQiKSL4eAIiJMI/EQEhQGYGYiQIQAg+iAkIATIzECMBIgT/ +RBARERlSADs=} +dragfile {R0lGODlhGAAYAKIAANnZ2TMzM////wAAAJmZmf///////////yH5BAEAAAAALAAAAAAYABgA +AAPACBi63IqgC4GiyxwogaAbKLrMgSKBoBoousyBogEACIGiyxwoKgGAECI4uiyCExMTOACB +osuNpDoAGCI4uiyCIkREOACBosutSDoAgSI4usyCIjQAGCi63Iw0ACEoOLrMgiI0ABgoutyM +NAAhKDi6zIIiNAAYKLrcjDQAISg4usyCIjQAGCi63Iw0AIGiiqPLIyhCA4CBosvNSAMQKKo4 +ujyCIjQAGCi63Iw0AIGiy81IAxCBpMu9GAMAgKPL3QgJADs=} +dragicon {R0lGODlhGAAYALMAANnZ2TMzM/////8zM8zMzGYAAAAAAJmZmQCZMwAzZgCZzGZmZv////// +/////////yH5BAEAAAAALAAAAAAYABgAAAT/EMAgJ60SAjlBgEJOSoMIEMgZoJCT0iADBFIG +KOSkNMwAAABhwiHnIEKIIIQQAQIZhBBwyDmKEMIEE0yABoAghIBDzlGEENDIaQAIQgg45BwF +CinPOccAECYcUiKEEBFCiHPgMQAEIcQYYyABBUGIQCHlMQCEScZAAhKEEApCECGOARAEIQQp +BRGIpAyCJCGOASBAISdEcqJAVBLiGABggELOAJGUKyiVhDgGABigkJMEhNAKSqkEhTgGgCCl +FCQEGIJSSiUhjgEgQCEnJVBJmYQ4BoAAhZyTQCVnEuIYAAIUckoCk5xSiGMACFDISSs9BoBg +rRXQMQAEKOSklR4DEUAI8MhJ6wwGAACgkZNWCkAEADs=} +error {R0lGODlhIAAgAKIAANnZ2YQAAP8AAISEhP///////////////yH5BAEAAAAALAAAAAAgACAA +AAP/CLoMGLqKoMvtGIqiqxEYCLrcioGiyxwIusyBgaLLLRiBoMsQKLrcjYGgu4Giy+2CAkFX +A0WX2wXFIOgGii7trkCEohsDCACBoktEKLpKhISiGwAIECiqSKooukiqKKoxgACBooukKiIo +SKooujGDECi6iqQqsopEV2MQAkV3kXQZRXdjEAJFl5F0FUWXY3ACRZcFSRdFlyVwJlB0WZB0 +UXRZAmcCRZeRdBVFl2NwAkV3kXQZRXdjcAJFV5FURVaR6GoMDgSKLpKqiKAgqaLoxgwOBIoq +kiqKLpIqimrM4ECg6BIRiq4SIaHoxgyCBoou7a5AhKIbMzgAAIGiy+2CTWJmBhAAAkWX2wXF +zCDoBooud2PMDIKuRqDocgtGzMwg6O4Eii5z4Kgi6DIMhqLoagQGjiqCLvPgYOgqji6CLrfi +6DIj6HI7jq4i6DIkADs=} +file {R0lGODlhCwANAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAALAA0AAAIyhI9G8Q0AguSH +AMQdxQgxEyEFQfItICQokYgEBMm3gBCKLRIQJN8CQii2SECQfAug+FgAOw==} +folder {R0lGODlhEAANAKIAANnZ2YSEhMbGxv//AP///wAAAP///////yH5BAEAAAAALAAAAAAQAA0A +AANjCIqhiqDLITgyEgi6GoIjIyMYugCBpMsaWBA0giMjIzgyUYBBMjIoIyODEgVBODIygiMj +E1gQJIMyMjIoI1GAQSMjODIyghMFQSgjI4MyMhJYEDSCIyMjODJRgKHLXAiApcucADs=} +hourglass {R0lGODlhIAAgAKIAANnZ2YAAAAAAAP8AAP///8DAwICAgP///yH5BAEAAAAALAAAAAAgACAA +AAPZCLrc/jDKSau9OGcUuqyCoMvNGENVhaMrCLrcjaLLgqDL7WhFVIVVZoKgy+1oRUSFVWaC +oMvtaEVEhVVmgqDL7WhFRIVVZoKgy+1oVVaCJWaCoMvtgKxISrBMEHS5fZEVSRkKgi63NzIq +EwRdbndkVCYIutzeyIqqDAVBl9sXWRFJYZkg6HI7ICsiKqwyEwRdbkcrIhKsMhMEXW5HKyIp +lDITBF1uRysyEiwxEwRdbkcrIyuUEhMEXW5H0WVB0OVujKGqwtEVBF1uRtHlRdDl9odRTlrt +xRmjBAA7} +info {R0lGODlhIAAgAKIAANnZ2YSEhMbGxv///wAA/wAAAP///////yH5BAEAAAAALAAAAAAgACAA +AAP/CLoMGLqKoMvtGCo4uhKBgaDLDRghOLqsghEIuryBgqPLPSiBoMsQOLojhEQkOLpTCLob +OLqKpIujq4WgC4Gju0i6OLpbCKohOLorhEQkOLorhaAQOLrc3qgCIARHl9sbSQUEji4j6RKO +Lk9hQODosiKp4ujyFIbi6LIiqeLo8hSG4uiyIqni6PIUhuLosiKp4ujyFIYKji4PkiqOLkth +BASOLg+SKo4uV2AEhODoMpIqju5KYShA4Ogqku7i6E4FRgAAYOHocvugiohAUC0cXe7GiohA +0IUSHF3uQamICATdrULB0WUVrIqIQNBlCCwVHF2pwsJQRdDlDYyoKsHRPMLQDQRdbsDQqBmc +wlBF0OV2jJqZwggEXW5vVDMVgaDL7Y5qKgJBl9sfVUUg6HL7AxSKoMvtr1AEgi5DAgA7} +italic {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAIrhI+py+1A4hN8 +hIjINBITPlpEZBqJCR8tIjKNxISPFhGZQOITfExdbv9FCgA7} +new {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAJFhI95FN8IvgXJ +jyD4ECQ/JAh+kPyICIIdJP+CYAfJvyDYQfIvCHaQ/AuCHST/gmAHyb8g2EHyLwh2kPwLgk3x +MQg+pu4WADs=} +open {R0lGODlhEAAQAKIAANnZ2QAAAP//AP///4SEAP///////////yH5BAEAAAAALAAAAAAQABAA +AANZCLrczigUQZc1EDQgEHSZAwMgIhB0NQIDQkYwdANBNUZwZGQEJxBUQwZlZGRQAkE1RnAE +Q5dVcCSQdDcAYySQdDcAISSQdDcAASKQdDcAAQBDlwNBl9sfApQAOw==} +openfold {R0lGODlhEAANAKIAANnZ2YSEhP///8bGxv//AAAAAP///////yH5BAEAAAAALAAAAAAQAA0A +AANgCIqhiqDLgaIaCLoagkNDIxi6AIFCQ0M4KKpRgCFDQzg0NIQThaHLSxgVKLochRMVMkhD +Q4M0VBFYEDKEQ0NDOFFRgCE0NEhDQ4MVBRAoNDSEQ0NRWAAYuqyFBQBYurwJADs=} +overstrike {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAI3hI+py80Uh+Aj +RFhQCP8iMILgWwRGEHyLwAiCbxEYQfCB4iPBhwiMIPgXYREEHyEiguBj6nI7FQA7} +palette {R0lGODlhEAAQAKIAANnZ2QAAAP//AP////8A/4QAhP8AAAD//yH5BAEAAAAALAAAAAAQABAA +AANtCLrcjqGBoMsRKCMTgaALMSgDAYMSCKoxgAFBITgSAIAQEhUIARCAEgAQOBAwghMQEwga +MoIjIxAIEgCAEBEyKBAgg4GgGxAIYTGCgaALcRgQIIGgCwEYICODgaALITgyEoGguxiqCLrc +/lChBAA7} +passwd {R0lGODlhIAAgAMQAANnZ2QAAAICAgICAAP///7CwsMDAwMjIAPjIAOjo6Pj4AODg4HBwcMj4 +ANjY2JiYANDQ0MjIyPj4yKCgoMiYAMjImDAwAMjIMJiYmJCQkP////////////////////// +/yH5BAEAAAAALAAAAAAgACAAAAX/ICCOIhiIIgiII1maZSCMQnCeJyAIQiAIAiAMwxCcJwkk +EAQRCIUwGMSBDEEAAuJIlgKRJEEgGAMRBIGiDENQlqNAJAsYCEwgEEEgBAHSIEMAAuJIAgKR +LEsgGEMgCEJgBMqhHENQlgJILMsSCMRABEFgGAESHMcRgIA4kgKxOIsTBAOhKAITKEGDHMhD +kqIAEqAjisJAgIooBkpwNMcTgIA4jgLhOBAkEAOhKIoSKEGDIMcTkKQICgQEQQIxEIqiBEpw +IMdxPAEIiCMJCEQUMUQ0EIqiHIfSIM3xBGUpCiABCUQyEMqhHMiBHMjxBCAgjuQoEAKxRANB +HMqhHM1x/zxDUJajQIACsUTDQBAEIR3IcQRDAALiSIoCYQiEE03gII7HQR3BEICAOJICYRSC +QDjRNE1CAAzVQR3WE5AkAAqEUQiFQEARBAUAAAzHQR3BEICAOI4CUQhFIBAREwXjUFUHdQRD +QJJAABbCFAhEJBgBAADAMAwXdQRDAALiCAhEIRQCYRiCEZDjUFFHMAQkIBAFOAmTQBiFUAQg +II7AUFXUEQwBCQjEJExBkBRCEZCjMIBD9RxDAALiGEzCFBBYIRTBOI7AQB1DMIoCMQkYGAjL +JEwBCIgjOVDDEJCAQGACJiTTJEwBSY5BEJAiSCCwTAiCZBKmAATEkSzNQBCCYCDBJgELTNMk +g0AMEgwTAhAQR7I0zYARgvM8TyAIznMMAQA7} +paste {R0lGODlhEAAQAKIAANnZ2QAAAP//AISEAISEhP///wAAhP///yH5BAEAAAAALAAAAAAQABAA +AANwCLrcjqGBoKsYqiKrCDSGBkMiJJCGAgCDKBB0gwYDIKYwdJUIAyBokIaGBmloAhBiaAgH +TdcCEIKGBsmwVM0AIYaGcAxL1coQgoYGySoisMzMAoeGxrB01QJpaMiwMHTLAEPVsHTVEHTR +dBlBlxswAQA7} +print {R0lGODlhEAAQAKIAANnZ2QAAAP///4SEhP//AP///////////yH5BAEAAAAALAAAAAAQABAA +AANZCLrcjqG7CLqBoquBoBuCoSqBoBsouhoIuiEYqrKBoIGiqwEYEIChyxAIEYGgywEYgKHL +DAgRCLozgwABARgIukSEABEBGLq8gAEQCLobgAEAgKHLgaDLzZgAOw==} +question {R0lGODlhIAAgAKIAANnZ2YSEhMbGxv///wAAAAAA/////////yH5BAEAAAAALAAAAAAgACAA +AAP/CLoMGLqKoMvtGCo4uhKBgaDLDRghOLqsghEIuryBgqPLPSiBoMsQOLrcjYSgu4GjO4Kl +Kzi6Qwi6EDi6I4UyU1VYgqM7hKAagqM7VTg6VYWFoztCCAqBo6tVWDVThVU4ukqBACE4ulqF +VSNVWIWjq0IYEDi6K4UlU1VYOLpMgRA4uryCpTi6PIShOLq8hVU4uqyEoTi6vIUlOLqshKE4 +uryFhaPLSxgqOLrc3kgoAgJHl0ewSnB0eQhDIQRHl6uwCkeXhTAUIHB0uQqrcHSZAiMAAJBw +dFcKS3B0lwIjAkGVcHS5GykiAkEXSHB0uQeFIiIQdJcIBUeXVZAoIgJBT5chkFRwdIUICUMV +QZc3MIKIBEcJQzcQdLkBQ4NmcAhDFUGX2zFoZggjEHS5vRHNUASCLrc7oqEIBF1uf0QUgaDL +7Q9QKIIut79CEQi6DAkAOw==} +redo {R0lGODlhEAAQAJEAANnZ2QAAhP///////yH5BAEAAAAALAAAAAAQABAAAAIvhI+py+1vSByC +jxAYQXDMwsyAggQAQBB8iwgMgg8REQgUwqbYBDsIPqYutz+MgBQAOw==} +save {R0lGODlhEAAQAJEAANnZ2QAAAISEAP///yH5BAEAAAAALAAAAAAQABAAAAJWhI9pFB8RIIRC ++BYQFqQQvkWEBSmEbyFhQQrhW0hYkEL4FhIWpBC+hYQFSYxvIgFAoXy0AAiSGP8kAIIkxgcI +CSBEQvEBQgIIkVB8gJAAAhgfj+BjWgEAOw==} +underline {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAI3hI+py60UBy4I +vkVcBMG/iIsg+BdxEQT/Ii6C4F/ERRD8i7gIgn8RF0HwkWITfExFin8EH1OXCwA7} +undo {R0lGODlhEAAQAJEAANnZ2QAAhP///////yH5BAEAAAAALAAAAAAQABAAAAIuhI+py+2vSByC +HxdxQCHsCIg7oAAAEUHwLTAiKIQPgRSbYMfd3VEIH1OX2x8mUgA7} +warning {R0lGODlhIAAgAKIAANnZ2YSEAP//AMbGxgAAAISEhP///////yH5BAEAAAAALAAAAAAgACAA +AAP/CLq8gREIutz+KESGEHS5vVGIiAxSIehy+6JAUaUqBF1uBxQoukOFhaDL7RgoukKFhaDL +3RgoujqEVQi63IyBortUWAi63IuBostDWIWgy60YIjKERCMiSFUIutyAISKCpCoiOFSFoMsd +KCpIqiKCQlUIusyBooqkKiIoQ1UIuryBooqkiqJKVQi6rIGii6SKojpUWAi6DIGiG0RIgaJL +VQi6HCi6MoREg6I7VFgIuhsoukqEhKKrVFgIuhoouhuEgaKrQ1iFoAuBortDOCi6S4WFoBso +uiyEostDWIWgGii63K6IqgAAIVB0WQaJBkV3h7AKAAJFl4WQiFB0mQoLRyBQdFkJiQhFl4ew +CgJFl3WQaFB0WQirIFB0ud0RVVWg6HJ7o6GqAgwUXW5fNFRVhQCBpMvti0oVABCwdLndEehi +6XI7I4AEADs=} +} diff --git a/ext/tk/sample/tkextlib/tile/readme.txt b/ext/tk/sample/tkextlib/tile/readme.txt new file mode 100644 index 000000000..f5d613a7b --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/readme.txt @@ -0,0 +1,3 @@ +All of *.tcl, themes/kroc.tcl and images (themes/kroc/*) are +quoted from Tcl/Tk's Tile extension. +Please read Orig_LICENSE.txt. diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc.rb b/ext/tk/sample/tkextlib/tile/themes/kroc.rb new file mode 100644 index 000000000..a4b227947 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc.rb @@ -0,0 +1,159 @@ +# +# kroc.rb +# +# based on: +# >> kroc.tcl - Copyright (C) 2004 David Zolli <kroc@kroc.tk> +# + +imgdir = File.join(File.dirname(__FILE__), 'kroc') +$images = Tk::Tile.load_images(imgdir, '*.gif') + +def kroc_rb_settings + # Tk::Tile::Style.default(TkRoot, :background=>'#FCB64F', + # :troughcolor=>'#F8C278', :borderwidth=>1) + # or + # Tk::Tile::Style.default(Tk.root, :background=>'#FCB64F', + # :troughcolor=>'#F8C278', :borderwidth=>1) + # or + # Tk::Tile::Style.default('.', :background=>'#FCB64F', + # :troughcolor=>'#F8C278', :borderwidth=>1) + # or + # Tk::Tile::Style.default(nil, :background=>'#FCB64F', + # :troughcolor=>'#F8C278', :borderwidth=>1) + # or + Tk::Tile::Style.default(:background=>'#FCB64F', :troughcolor=>'#F8C278', + :borderwidth=>1) + # Tk::Tile::Style.default(TkRoot, :font=>Tk::Tile::Font::Default, + # :borderwidth=>1) + # or + # Tk::Tile::Style.default(Tk.root, :font=>Tk::Tile::Font::Default, + # :borderwidth=>1) + # or + # Tk::Tile::Style.default('.', :font=>Tk::Tile::Font::Default, + # :borderwidth=>1) + # or + # Tk::Tile::Style.default(nil, :font=>Tk::Tile::Font::Default, + # :borderwidth=>1) + # or + Tk::Tile::Style.default(:font=>Tk::Tile::Font::Default, :borderwidth=>1) + + # Tk::Tile::Style.map(TkRoot, :background=>[:active, '#694418']) + # or + # Tk::Tile::Style.map(Tk.root, :background=>[:active, '#694418']) + # or + # Tk::Tile::Style.map('.', :background=>[:active, '#694418']) + # or + # Tk::Tile::Style.map(nil, :background=>[:active, '#694418']) + # or + Tk::Tile::Style.map(:background=>[:active, '#694418']) + Tk::Tile::Style.map(:foreground=>[:disabled, 'B2B2B2', :active, '#FFE7CB']) + + # Tk::Tile::Style.default('TButton', :padding=>[10,4]) + Tk::Tile::Style.default(Tk::Tile::TButton, :padding=>[10,4]) + + # Tk::Tile::Style.default('TNotebook.Tab', + Tk::Tile::Style.default(Tk::Tile::TNotebook.style('Tab'), + :padding=>[10, 3], :font=>Tk::Tile::Font::Default) + # Tk::Tile::Style.map('TNotebook.Tab', + Tk::Tile::Style.map(Tk::Tile::TNotebook.style('Tab'), + :background=>[:selected, '#FCB64F', '', '#FFE6BA'], + :foreground=>['', 'black'], + :padding=>[:selected, [10, 6, 10, 3]]) + + # Tk::Tile::Style.map('TScrollbar', + Tk::Tile::Style.map(Tk::Tile::TScrollbar, + :background=>[:pressed, '#694418'], + :arrowcolor=>[:pressed, '#FEF7CB'], + :relief=>[:pressed, :sunken]) + + # Tk::Tile::Style.layout('Vertical.TScrollbar', + Tk::Tile::Style.layout(Tk::Tile.style('Vertical', Tk::Tile::TScrollbar), + ['Scrollbar.trough', {:children=>[ + 'Scrollbar.uparrow', {:side=>:top}, + 'Scrollbar.downarrow', {:side=>:bottom}, + 'Scrollbar.uparrow', {:side=>:bottom}, + 'Scrollbar.thumb', {:side=>:top, :expand=>true} + ]} + ]) + + # Tk::Tile::Style.layout('Horizontal.TScrollbar', + Tk::Tile::Style.layout(Tk::Tile.style('Horizontal', Tk::Tile::TScrollbar), + ['Scrollbar.trough', {:children=>[ + 'Scrollbar.leftarrow', {:side=>:left}, + 'Scrollbar.rightarrow', {:side=>:right}, + 'Scrollbar.leftarrow', {:side=>:right}, + 'Scrollbar.thumb', {:side=>:left, :expand=>true} + ]} + ]) + + # + # Elements: + # + Tk::Tile::Style.element_create('Button.button', :pixmap, + :images=>[ + :pressed, $images['button-p'], + :active, $images['button-h'], + '', $images['button-n'] + ], :border=>3, :tiling=>:tile) + + Tk::Tile::Style.element_create('Checkbutton.indicator', :pixmap, + :images=>[ + [:pressed, :selected], $images['check-nc'], + :pressed, $images['check-nu'], + [:active, :selected], $images['check-hc'], + :active, $images['check-hu'], + :selected, $images['check-nc'], + '', $images['check-nu'], + ], :tiling=>:fixed) + + Tk::Tile::Style.element_create('Radiobutton.indicator', :pixmap, + :images=>[ + [:pressed, :selected], $images['radio-nc'], + :pressed, $images['radio-nu'], + [:active, :selected], $images['radio-hc'], + :active, $images['radio-hu'], + :selected, $images['radio-nc'], + '', $images['radio-nu'], + ], :tiling=>:fixed) + + # + # Settings: + # + # Tk::Tile::Style.layout(Tk::Tile::TButton, + Tk::Tile::Style.layout('TButton', [ + 'Button.button', {:children=>[ + 'Button.focus', {:children=>[ + 'Button.padding', {:children=>[ + 'Button.label', {:expand=>true, :sticky=>''} + ]} + ]} + ]} + ]) + + # Tk::Tile::Style.layout(Tk::Tile::TCheckbutton, + Tk::Tile::Style.layout('TCheckbutton', [ + 'Checkbutton.border', {:children=>[ + 'Checkbutton.padding', {:children=>[ + 'Checkbutton.indicator', {:side=>:left}, + 'Checkbutton.focus', {:side=>:left, :children=>[ + 'Checkbutton.label' + ]} + ]} + ]} + ]) + + # Tk::Tile::Style.layout(Tk::Tile::TRadiobutton, + Tk::Tile::Style.layout('TRadiobutton', [ + 'Radiobutton.border', {:children=>[ + 'Radiobutton.padding', {:children=>[ + 'Radiobutton.indicator', {:side=>:left}, + 'Radiobutton.focus', {:expand=>true, :sticky=>:w, :children=>[ + 'Radiobutton.label', {:side=>:right, :expand=>true} + ]} + ]} + ]} + ]) +end + +Tk::Tile::Style.theme_create('kroc-rb', :parent=>'alt', + :settings=>proc{ kroc_rb_settings() }) diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc.tcl b/ext/tk/sample/tkextlib/tile/themes/kroc.tcl new file mode 100644 index 000000000..0f92674a2 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc.tcl @@ -0,0 +1,126 @@ +# kroc.tcl - Copyright (C) 2004 David Zolli <kroc@kroc.tk> +# +# A sample pixmap theme for the tile package. + +#package require tile::pixmap + +namespace eval tile { + namespace eval kroc { + variable version 0.0.1 + } +} + +namespace eval tile::kroc { + + set imgdir [file join [file dirname [info script]] kroc] + array set Images [tile::LoadImages $imgdir *.gif] + + style theme create kroc -parent alt -settings { + + style default . -background #FCB64F -troughcolor #F8C278 -borderwidth 1 + style default . -font TkDefaultFont -borderwidth 1 + style map . -background [list active #694418] + style map . -foreground [list disabled #B2B2B2 active #FFE7CB] + + style default TButton -padding "10 4" + + style default TNotebook.Tab -padding {10 3} -font TkDefaultFont + style map TNotebook.Tab \ + -background [list selected #FCB64F {} #FFE6BA] \ + -foreground [list {} black] \ + -padding [list selected {10 6 10 3}] + + style map TScrollbar \ + -background { pressed #694418} \ + -arrowcolor { pressed #FFE7CB } \ + -relief { pressed sunken } \ + ; + + style layout Vertical.TScrollbar { + Scrollbar.trough -children { + Scrollbar.uparrow -side top + Scrollbar.downarrow -side bottom + Scrollbar.uparrow -side bottom + Scrollbar.thumb -side top -expand true + } + } + + style layout Horizontal.TScrollbar { + Scrollbar.trough -children { + Scrollbar.leftarrow -side left + Scrollbar.rightarrow -side right + Scrollbar.leftarrow -side right + Scrollbar.thumb -side left -expand true + } + } + + # + # Elements: + # + style element create Button.button pixmap -images [list \ + pressed $Images(button-p) \ + active $Images(button-h) \ + {} $Images(button-n) \ + ] -border 3 -tiling tile + + style element create Checkbutton.indicator pixmap -images [list \ + {pressed selected} $Images(check-nc) \ + pressed $Images(check-nu) \ + {active selected} $Images(check-hc) \ + active $Images(check-hu) \ + selected $Images(check-nc) \ + {} $Images(check-nu) \ + ] -tiling fixed + + style element create Radiobutton.indicator pixmap -images [list \ + {pressed selected} $Images(radio-nc) \ + pressed $Images(radio-nu) \ + {active selected} $Images(radio-hc) \ + active $Images(radio-hu) \ + selected $Images(radio-nc) \ + {} $Images(radio-nu) \ + ] -tiling fixed + + + # + # Settings: + # + style layout TButton { + Button.button -children { + Button.focus -children { + Button.padding -children { + Button.label -expand true -sticky {} + } + } + } + } + + style layout TCheckbutton { + Checkbutton.border -children { + Checkbutton.padding -children { + Checkbutton.indicator -side left + Checkbutton.focus -side left -children { + Checkbutton.label + } + } + } + } + + style layout TRadiobutton { + Radiobutton.border -children { + Radiobutton.padding -children { + Radiobutton.indicator -side left + Radiobutton.focus -expand true -sticky w -children { + Radiobutton.label -side right -expand true + } + } + } + } + + } } + +# ------------------------------------------------------------------------- + +package provide tile::theme::kroc $::tile::kroc::version + +# ------------------------------------------------------------------------- diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/button-h.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/button-h.gif Binary files differnew file mode 100644 index 000000000..e7a140ded --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/button-h.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/button-n.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/button-n.gif Binary files differnew file mode 100644 index 000000000..78b506dde --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/button-n.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/button-p.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/button-p.gif Binary files differnew file mode 100644 index 000000000..a5a4e90be --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/button-p.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/check-hc.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/check-hc.gif Binary files differnew file mode 100644 index 000000000..41503c5eb --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/check-hc.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/check-hu.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/check-hu.gif Binary files differnew file mode 100644 index 000000000..b3e512ca6 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/check-hu.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/check-nc.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/check-nc.gif Binary files differnew file mode 100644 index 000000000..a28c288fc --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/check-nc.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/check-nu.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/check-nu.gif Binary files differnew file mode 100644 index 000000000..5c23931bb --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/check-nu.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/radio-hc.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-hc.gif Binary files differnew file mode 100644 index 000000000..359fe1cc8 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-hc.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/radio-hu.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-hu.gif Binary files differnew file mode 100644 index 000000000..9f46b3792 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-hu.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/radio-nc.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-nc.gif Binary files differnew file mode 100644 index 000000000..6437f33a7 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-nc.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/kroc/radio-nu.gif b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-nu.gif Binary files differnew file mode 100644 index 000000000..2d2aac859 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/kroc/radio-nu.gif diff --git a/ext/tk/sample/tkextlib/tile/themes/pkgIndex.tcl b/ext/tk/sample/tkextlib/tile/themes/pkgIndex.tcl new file mode 100644 index 000000000..179077917 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/themes/pkgIndex.tcl @@ -0,0 +1,15 @@ +# pkgIndex.tcl for additional tile pixmap themes. +# +# We don't provide the package is the image subdirectory isn't present, +# or we don't have the right version of Tcl/Tk +# +# To use this automatically within tile, the tile-using application should +# use tile::availableThemes and tile::setTheme +# +# $Id$ + +if {![file isdirectory [file join $dir kroc]]} { return } +if {![package vsatisfies [package provide Tcl] 8.4]} { return } + +package ifneeded tile::theme::kroc 0.0.1 \ + [list source [file join $dir kroc.tcl]] diff --git a/ext/tk/sample/tkextlib/tile/toolbutton.tcl b/ext/tk/sample/tkextlib/tile/toolbutton.tcl new file mode 100644 index 000000000..4e08034e3 --- /dev/null +++ b/ext/tk/sample/tkextlib/tile/toolbutton.tcl @@ -0,0 +1,152 @@ +# +# $Id$ +# +# Demonstration of custom widget styles. +# + +# +# ~ BACKGROUND +# +# Checkbuttons in toolbars have a very different appearance +# than regular checkbuttons: there's no indicator, they +# "pop up" when the mouse is over them, and they appear sunken +# when selected. +# +# Tk added partial support for toolbar-style buttons in 8.4 +# with the "-overrelief" option, and TIP #82 added further +# support with the "-offrelief" option. So to get a toolbar-style +# checkbutton, you can configure it with: +# +# checkbutton .cb \ +# -indicatoron false -selectcolor {} -relief flat -overrelief raised +# +# Behind the scenes, Tk has a lot of rather complicated logic +# to implement this checkbutton style; see library/button.tcl, +# generic/tkButton.c, and the platform-specific files unix/tkUnixButton.c +# et al. for the full details. +# +# The tile widget set has a better way: custom styles. +# Since the appearance is completely controlled by the theme engine, +# we can define a new "Toolbutton" style and just use: +# +# checkbutton .cb -style Toolbutton +# +# +# ~ DEMONSTRATION +# +# The tile built-in themes (default, "alt", windows, and XP) +# already include Toolbutton styles. This script will add +# them to the "step" and "blue" themes as a demonstration. +# +# (Note: Pushbuttons and radiobuttons can also use the "Toolbutton" +# style; see demo.tcl.) +# + +style theme settings "step" { + +# +# First, we use [style layout] to define what elements to +# use and how they're arranged. Toolbuttons are pretty +# simple, consisting of a border, some internal padding, +# and a label. (See also the TScrollbar layout definition +# in demos/blue.tcl for a more complicated layout spec.) +# + style layout Toolbutton { + Toolbutton.background + Toolbutton.border -children { + Toolbutton.padding -children { + Toolbutton.label + } + } + } + +# (Actually the above isn't strictly necessary, since the same layout +# is defined in the default theme; we could have inherited it +# instead.) +# +# Next, specify default values for element options. +# For many options (like -background), the defaults +# inherited from the parent style are sufficient. +# + style default Toolbutton -width 0 -padding 1 -relief flat -borderwidth 2 + +# +# Finally, use [style map] to specify state-specific +# resource values. We want a flat relief if the widget is +# disabled, sunken if it's selected (on) or pressed, +# and raised when it's active (the mouse pointer is +# over the widget). Each state-value pair is checked +# in order, and the first matching state takes precedence. +# + style map Toolbutton -relief { + disabled flat + selected sunken + pressed sunken + active raised + } +} + +# +# Now for the "blue" theme. (Since the purpose of this +# theme is to show what *can* be done, not necessarily what +# *should* be done, the following makes some questionable +# design decisions from an aesthetic standpoint.) +# +if {![catch {package require tile::theme::blue}]} { +style theme settings "blue" { + + # + # Default values: + # + style default Toolbutton \ + -width 0 -relief flat -borderwidth 2 \ + -background #6699CC -foreground #000000 ; + + # + # Configure state-specific values for -relief, as before: + # + style map Toolbutton -relief { + disabled flat + selected sunken + pressed sunken + active raised + } + + # + # Adjust the -padding at the same time, to enhance + # the raised/sunken illusion: + # + style default Toolbutton -padding 4 + style map Toolbutton -padding { + disabled {4} + selected {6 6 2 2} + pressed {6 6 2 2} + active {2 2 6 6} + } + + # + # ... and change the foreground and background colors + # when the mouse cursor is over the widget: + # + style map Toolbutton -background { + active #008800 + } -foreground { + active #FFFFFF + } +} + +} + +# +# ~ A final note: +# +# TIP #82 also says: "When -indicatoron is off and the button itself +# is on, the relief continues to be hard-coded to sunken. For symmetry, +# we might consider adding another -onrelief option to cover this +# case. But it is difficult to imagine ever wanting to change the +# value of -onrelief so it has been omitted from this TIP. +# If there as strong desire to have -onrelief, it can be added later." +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# The Tile project aims to make sure that this never needs to happen. +# |