summaryrefslogtreecommitdiff
path: root/ext/tk/sample/ttk_wrapper.rb
blob: 1706c867d2f3c40a69a9d827b962bb9d3edf9f97 (plain)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env ruby
# frozen_string_literal: false
#
#  ttk_wrapper.rb  --  use Ttk widgets as default on old Ruby/Tk scripts
#
#                       by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
#
version = '0.1.3'
#
##########################################################################
#  parse commandline arguments
##########################################################################
require 'optparse'
opt = OptionParser.new("Usage: #{$0} [options] rubytk_script" << "\n    " <<
                         "Ruby/Tk script wrapper. Use Ttk widgets as default.")
opt.version = version

OPTS = {}
OPTS[:themedir] = []
OPTS[:rb_theme] = []
OPTS[:theme] = 'default'

opt.on('-l', '--list', 'list available theme names'){|v| OPTS[:list] = true}
opt.on('-t', '--theme theme', 'theme name'){|v| OPTS[:theme] = v}
opt.on('-d', '--themedir themes_dir', 'directory of theme definitions'){|v|
  OPTS[:themedir] << v
}
opt.on('-r', '--rubytheme rb_theme', 'theme definition file (ruby script)'){|v|
  OPTS[:rb_theme] << v
}
opt.on('-v', '--verbose', 'print verbose messages'){|v| OPTS[:verbose] = true}

opt.parse!(ARGV)


##########################################################################
#  load Ttk (Tile) extension
##########################################################################
require 'tk'

begin
  require 'tkextlib/tile'
  Tk.default_widget_set = :Ttk
rescue LoadError
  if OPTS[:verbose]
    print "warning: fail to load 'Ttk' extension. use standard widgets.\n"
  end
end

if OPTS[:verbose]
  print "current default widget set is '#{Tk.default_widget_set}'\n"
end


##########################################################################
# define Tcl/Tk procedures for compatibility.
# those are required when want to use themes included
# in "sample/tkextlib/tile/demo.rb".
##########################################################################
Tk::Tile.__define_LoadImages_proc_for_compatibility__!
Tk::Tile::Style.__define_wrapper_proc_for_compatibility__!


##########################################################################
#  use themes defined on the demo of Ttk (Tile) extension
##########################################################################
demodir = File.dirname(__FILE__)
demo_themesdir = File.expand_path(File.join(demodir, 'tkextlib', 'tile', 'themes'))

Tk::AUTO_PATH.lappend(*OPTS[:themedir]) unless OPTS[:themedir].empty?
Tk::AUTO_PATH.lappend('.', demodir, demo_themesdir)

OPTS[:themedir] << demo_themesdir
print "theme-dirs: #{OPTS[:themedir].inspect}\n" if OPTS[:verbose]

OPTS[:themedir].each{|themesdir|
  if File.directory?(themesdir)
    Dir.foreach(themesdir){|name|
      next if name == '.' || name == '..'
      path = File.join(themesdir, name)
      Tk::AUTO_PATH.lappend(path) if File.directory?(path)
    }
  end
}

# This forces an update of the available packages list. It's required
# for package names to find the themes in demos/themes/*.tcl
Tk.ip_eval("#{TkPackage.unknown_proc}  Tcl #{TkPackage.provide('Tcl')}")

# load themes written in Ruby.
themes_by_ruby = [File.join(demo_themesdir, 'kroc.rb')]
themes_by_ruby.concat OPTS[:rb_theme]
print "ruby-themes: #{themes_by_ruby.inspect}\n" if OPTS[:verbose]

themes_by_ruby.each{|f|
  begin
    load(f, true)
  rescue LoadError
    print "fail to load \"#{f}\"\n" if OPTS[:verbose]
  end
}


##########################################################################
# ignore unsupported options of Ttk widgets
##########################################################################
TkConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! true
TkItemConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! true


##########################################################################
#  set theme of widget style
##########################################################################
if OPTS[:list] || OPTS[:verbose]
  print "supported theme names: #{Tk::Tile.themes.inspect}\n"
  exit if OPTS[:list] && ARGV.empty?
end
print "use theme: \"#{OPTS[:theme]}\"\n" if OPTS[:theme] && OPTS[:verbose]
#setTheme(OPTS[:theme]) if OPTS[:theme]
Tk::Tile.set_theme(OPTS[:theme]) if OPTS[:theme]


##########################################################################
#  replace $0 and $PROGRAM_NAME
##########################################################################
#  When the expand_path of the target script is long, ruby sometimes
#  fails to set the path to $0 (the path string is trimmed).
#  The following replaces $0 and $PROGNAME to avoid such trouble.
progname_obj = $0.dup
$program_name = progname_obj

alias $REAL_PROGRAM_NAME $0
alias $PROGRAM_NAME $program_name
alias $0 $program_name

trace_var(:$program_name){|val|
  unless progname_obj.object_id == val.object_id
    progname_obj.replace(val.to_s)
    $program_name = progname_obj
  end
}


##########################################################################
#  load script
##########################################################################
if (path = ARGV.shift) && (script = File.expand_path(path))
  print "load script \"#{script}\"\n" if OPTS[:verbose]
  $0 = script
  load(script)
else
  print "Error: no script is given.\n"
  print opt.help
  exit(1)
end