font.tcl 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. # ------------------------------------------------------------------------------
  2. # font.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # ------------------------------------------------------------------------------
  5. # Index of commands:
  6. # - SelectFont::create
  7. # - SelectFont::configure
  8. # - SelectFont::cget
  9. # - SelectFont::_draw
  10. # - SelectFont::_destroy
  11. # - SelectFont::_modstyle
  12. # - SelectFont::_update
  13. # - SelectFont::_getfont
  14. # - SelectFont::_init
  15. # ------------------------------------------------------------------------------
  16. namespace eval SelectFont {
  17. Dialog::use
  18. LabelFrame::use
  19. ScrolledWindow::use
  20. Widget::declare SelectFont {
  21. {-title String "Font selection" 0}
  22. {-parent String "" 0}
  23. {-background TkResource "" 0 frame}
  24. {-type Enum dialog 0 {dialog toolbar}}
  25. {-font TkResource "" 0 label}
  26. {-command String "" 0}
  27. {-sampletext String "Sample Text" 0}
  28. {-bg Synonym -background}
  29. }
  30. proc ::SelectFont { path args } { return [eval SelectFont::create $path $args] }
  31. proc use {} {}
  32. variable _families
  33. variable _styles {bold italic underline overstrike}
  34. variable _sizes {4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24}
  35. variable _widget
  36. }
  37. # ------------------------------------------------------------------------------
  38. # Command SelectFont::create
  39. # ------------------------------------------------------------------------------
  40. proc SelectFont::create { path args } {
  41. variable _families
  42. variable _sizes
  43. variable _styles
  44. variable $path
  45. upvar 0 $path data
  46. if { ![info exists _families] } {
  47. loadfont
  48. }
  49. Widget::init SelectFont "$path#SelectFont" $args
  50. set bg [Widget::getoption "$path#SelectFont" -background]
  51. if { [Widget::getoption "$path#SelectFont" -type] == "dialog" } {
  52. Dialog::create $path -modal local -default 0 -cancel 1 -background $bg \
  53. -title [Widget::getoption "$path#SelectFont" -title] \
  54. -parent [Widget::getoption "$path#SelectFont" -parent]
  55. set frame [Dialog::getframe $path]
  56. set topf [frame $frame.topf -relief flat -borderwidth 0 -background $bg]
  57. set labf1 [LabelFrame::create $topf.labf1 -text "Font" -name font \
  58. -side top -anchor w -relief flat -background $bg]
  59. set sw [ScrolledWindow::create [LabelFrame::getframe $labf1].sw \
  60. -background $bg]
  61. set lbf [listbox $sw.lb \
  62. -height 5 -width 25 -exportselection false -selectmode browse]
  63. ScrolledWindow::setwidget $sw $lbf
  64. LabelFrame::configure $labf1 -focus $lbf
  65. eval $lbf insert end $_families
  66. set script "set SelectFont::$path\(family\) \[%W curselection\]; SelectFont::_update $path"
  67. bind $lbf <ButtonRelease-1> $script
  68. bind $lbf <space> $script
  69. pack $sw -fill both -expand yes
  70. set labf2 [LabelFrame::create $topf.labf2 -text "Size" -name size \
  71. -side top -anchor w -relief flat -background $bg]
  72. set sw [ScrolledWindow::create [LabelFrame::getframe $labf2].sw \
  73. -scrollbar vertical -background $bg]
  74. set lbs [listbox $sw.lb \
  75. -height 5 -width 6 -exportselection false -selectmode browse]
  76. ScrolledWindow::setwidget $sw $lbs
  77. LabelFrame::configure $labf2 -focus $lbs
  78. eval $lbs insert end $_sizes
  79. set script "set SelectFont::$path\(size\) \[%W curselection\]; SelectFont::_update $path"
  80. bind $lbs <ButtonRelease-1> $script
  81. bind $lbs <space> $script
  82. pack $sw -fill both -expand yes
  83. set labf3 [LabelFrame::create $topf.labf3 -text "Style" -name style \
  84. -side top -anchor w -relief sunken -bd 1 -background $bg]
  85. set subf [LabelFrame::getframe $labf3]
  86. foreach st $_styles {
  87. set name [lindex [BWidget::getname $st] 0]
  88. if { $name == "" } {
  89. set name "[string toupper [string index $name 0]][string range $name 1 end]"
  90. }
  91. checkbutton $subf.$st -text $name \
  92. -variable SelectFont::$path\($st\) \
  93. -background $bg \
  94. -command "SelectFont::_update $path"
  95. bind $subf.$st <Return> break
  96. pack $subf.$st -anchor w
  97. }
  98. LabelFrame::configure $labf3 -focus $subf.[lindex $_styles 0]
  99. pack $labf1 -side left -anchor n -fill both -expand yes
  100. pack $labf2 -side left -anchor n -fill both -expand yes -padx 8
  101. pack $labf3 -side left -anchor n -fill both -expand yes
  102. set botf [frame $frame.botf -width 100 -height 50 \
  103. -bg white -bd 0 -relief flat \
  104. -highlightthickness 1 -takefocus 0 \
  105. -highlightbackground black \
  106. -highlightcolor black]
  107. set lab [label $botf.label \
  108. -background white -foreground black \
  109. -borderwidth 0 -takefocus 0 -highlightthickness 0 \
  110. -text [Widget::getoption "$path#SelectFont" -sampletext]]
  111. place $lab -relx 0.5 -rely 0.5 -anchor c
  112. pack $topf -pady 4 -fill both -expand yes
  113. pack $botf -pady 4 -fill x
  114. Dialog::add $path -name ok
  115. Dialog::add $path -name cancel
  116. set data(label) $lab
  117. set data(lbf) $lbf
  118. set data(lbs) $lbs
  119. _getfont $path
  120. proc ::$path { cmd args } "return \[eval SelectFont::\$cmd $path \$args\]"
  121. return [_draw $path]
  122. } else {
  123. frame $path -relief flat -borderwidth 0 -background $bg
  124. bind $path <Destroy> "SelectFont::_destroy $path"
  125. set lbf [ComboBox::create $path.font \
  126. -highlightthickness 0 -takefocus 0 -background $bg \
  127. -values $_families \
  128. -textvariable SelectFont::$path\(family\) \
  129. -editable 0 \
  130. -modifycmd "SelectFont::_update $path"]
  131. set lbs [ComboBox::create $path.size \
  132. -highlightthickness 0 -takefocus 0 -background $bg \
  133. -width 4 \
  134. -values $_sizes \
  135. -textvariable SelectFont::$path\(size\) \
  136. -editable 0 \
  137. -modifycmd "SelectFont::_update $path"]
  138. pack $lbf -side left -anchor w
  139. pack $lbs -side left -anchor w -padx 4
  140. foreach st $_styles {
  141. button $path.$st \
  142. -highlightthickness 0 -takefocus 0 -padx 0 -pady 0 -bd 2 \
  143. -background $bg \
  144. -image [Bitmap::get $st] \
  145. -command "SelectFont::_modstyle $path $st"
  146. pack $path.$st -side left -anchor w
  147. }
  148. set data(label) ""
  149. set data(lbf) $lbf
  150. set data(lbs) $lbs
  151. _getfont $path
  152. rename $path ::$path:cmd
  153. proc ::$path { cmd args } "return \[eval SelectFont::\$cmd $path \$args\]"
  154. }
  155. return $path
  156. }
  157. # ------------------------------------------------------------------------------
  158. # Command SelectFont::configure
  159. # ------------------------------------------------------------------------------
  160. proc SelectFont::configure { path args } {
  161. variable _styles
  162. set res [Widget::configure "$path#SelectFont" $args]
  163. if { [Widget::hasChanged "$path#SelectFont" -font font] } {
  164. _getfont $path
  165. }
  166. if { [Widget::hasChanged "$path#SelectFont" -background bg] } {
  167. switch -- [Widget::getoption "$path#SelectFont" -type] {
  168. dialog {
  169. Dialog::configure $path -background $bg
  170. set topf [Dialog::getframe $path].topf
  171. $topf configure -background $bg
  172. foreach labf {labf1 labf2} {
  173. LabelFrame::configure $topf.$labf -background $bg
  174. set subf [LabelFrame::getframe $topf.$labf]
  175. ScrolledWindow::configure $subf.sw -background $bg
  176. $subf.sw.lb configure -background $bg
  177. }
  178. LabelFrame::configure $topf.labf3 -background $bg
  179. set subf [LabelFrame::getframe $topf.labf3]
  180. foreach w [winfo children $subf] {
  181. $w configure -background $bg
  182. }
  183. }
  184. toolbar {
  185. $path configure -background $bg
  186. ComboBox::configure $path.font -background $bg
  187. ComboBox::configure $path.size -background $bg
  188. foreach st $_styles {
  189. $path.$st configure -background $bg
  190. }
  191. }
  192. }
  193. }
  194. return $res
  195. }
  196. # ------------------------------------------------------------------------------
  197. # Command SelectFont::cget
  198. # ------------------------------------------------------------------------------
  199. proc SelectFont::cget { path option } {
  200. return [Widget::cget "$path#SelectFont" $option]
  201. }
  202. # ------------------------------------------------------------------------------
  203. # Command SelectFont::loadfont
  204. # ------------------------------------------------------------------------------
  205. proc SelectFont::loadfont { } {
  206. variable _families
  207. # initialize families
  208. set _families {}
  209. set lfont [font families]
  210. lappend lfont times courier helvetica
  211. foreach font $lfont {
  212. set family [font actual [list $font] -family]
  213. if { [lsearch -exact $_families $family] == -1 } {
  214. lappend _families $family
  215. }
  216. }
  217. set _families [lsort $_families]
  218. }
  219. # ------------------------------------------------------------------------------
  220. # Command SelectFont::_draw
  221. # ------------------------------------------------------------------------------
  222. proc SelectFont::_draw { path } {
  223. variable $path
  224. upvar 0 $path data
  225. $data(lbf) selection clear 0 end
  226. $data(lbf) selection set $data(family)
  227. $data(lbf) activate $data(family)
  228. $data(lbf) see $data(family)
  229. $data(lbs) selection clear 0 end
  230. $data(lbs) selection set $data(size)
  231. $data(lbs) activate $data(size)
  232. $data(lbs) see $data(size)
  233. _update $path
  234. if { [Dialog::draw $path] == 0 } {
  235. set result [Widget::getoption "$path#SelectFont" -font]
  236. } else {
  237. set result ""
  238. }
  239. unset data
  240. Widget::destroy "$path#SelectFont"
  241. destroy $path
  242. return $result
  243. }
  244. # ------------------------------------------------------------------------------
  245. # Command SelectFont::_destroy
  246. # ------------------------------------------------------------------------------
  247. proc SelectFont::_destroy { path } {
  248. variable $path
  249. upvar 0 $path data
  250. unset data
  251. Widget::destroy "$path#SelectFont"
  252. rename $path {}
  253. }
  254. # ------------------------------------------------------------------------------
  255. # Command SelectFont::_modstyle
  256. # ------------------------------------------------------------------------------
  257. proc SelectFont::_modstyle { path style } {
  258. variable $path
  259. upvar 0 $path data
  260. if { $data($style) == 1 } {
  261. $path.$style configure -relief raised
  262. set data($style) 0
  263. } else {
  264. $path.$style configure -relief sunken
  265. set data($style) 1
  266. }
  267. _update $path
  268. }
  269. # ------------------------------------------------------------------------------
  270. # Command SelectFont::_update
  271. # ------------------------------------------------------------------------------
  272. proc SelectFont::_update { path } {
  273. variable _families
  274. variable _sizes
  275. variable _styles
  276. variable $path
  277. upvar 0 $path data
  278. set type [Widget::getoption "$path#SelectFont" -type]
  279. if { $type == "dialog" } {
  280. set curs [$path:cmd cget -cursor]
  281. $path:cmd configure -cursor watch
  282. }
  283. if { [Widget::getoption "$path#SelectFont" -type] == "dialog" } {
  284. set font [list \
  285. [lindex $_families $data(family)] \
  286. [lindex $_sizes $data(size)]]
  287. } else {
  288. set font [list $data(family) $data(size)]
  289. }
  290. foreach st $_styles {
  291. if { $data($st) } {
  292. lappend font $st
  293. }
  294. }
  295. Widget::setoption "$path#SelectFont" -font $font
  296. if { $type == "dialog" } {
  297. $data(label) configure -font $font
  298. $path:cmd configure -cursor $curs
  299. } elseif { [set cmd [Widget::getoption "$path#SelectFont" -command]] != "" } {
  300. uplevel \#0 $cmd
  301. }
  302. }
  303. # ------------------------------------------------------------------------------
  304. # Command SelectFont::_getfont
  305. # ------------------------------------------------------------------------------
  306. proc SelectFont::_getfont { path } {
  307. variable _families
  308. variable _styles
  309. variable _sizes
  310. variable $path
  311. upvar 0 $path data
  312. array set font [font actual [Widget::getoption "$path#SelectFont" -font]]
  313. set data(bold) [expr {[string compare $font(-weight) "normal"] != 0}]
  314. set data(italic) [expr {[string compare $font(-slant) "roman"] != 0}]
  315. set data(underline) $font(-underline)
  316. set data(overstrike) $font(-overstrike)
  317. if { [Widget::getoption "$path#SelectFont" -type] == "dialog" } {
  318. set idxf [lsearch $_families $font(-family)]
  319. set idxs [lsearch $_sizes $font(-size)]
  320. set data(family) [expr {$idxf >= 0 ? $idxf : 0}]
  321. set data(size) [expr {$idxs >= 0 ? $idxs : 0}]
  322. } else {
  323. set data(family) $font(-family)
  324. set data(size) $font(-size)
  325. foreach st $_styles {
  326. $path.$st configure -relief [expr {$data($st) ? "sunken":"raised"}]
  327. }
  328. }
  329. }