TK Windows pdf translation


(Dominic Sisneros) #1

I am looking for more information on Tk Ruby programming. There is some
stuff out on the internet but a lot of the main information is not in my
only language English. Can anyone translate this pdf about ruby tk to
English. It seems to have some information I have not seen, like how to
subclass Tk classes

Thanks


(Hidetoshi NAGAI) #2

Message-ID: <CABdJ6swLXSw0rfJmwYpTQHSZ_dpeYnz2rHPmDT9JMno2yc_3gQ@mail.gmail.com>

I am looking for more information on Tk Ruby programming. There is some
stuff out on the internet but a lot of the main information is not in my
only language English. Can anyone translate this pdf about ruby tk to
English. It seems to have some information I have not seen, like how to
subclass Tk classes
https://www.dumbo.ai.kyutech.ac.jp/~nagai/RubyKaigi2007-nagai.pdf

The following text is a broken English text. So, it may make you confused.

···

From: Dominic Sisneros <dsisnero@gmail.com>
Subject: TK Windows pdf translation
Date: Fri, 17 Aug 2018 14:30:11 -0600

Page 1 ~ 9 : omit (not important)

--- Page 10 ---------------------------------------------------------
[ Today's Theme ]

Explain functions to support creating a new widget class.
---------------------------------------------------------------------

--- Page 11 ~ 12 ----------------------------------------------------
[ Types based on Widget creation ]

Widget types based on the method to create widgets on Ruby/Tk

(1) Tcl/Tk's single widget class
(2) A widget (include a composite widget) created by Tcl/Tk's command
(3) Subclass of Ruby/Tk's widget class
(4) Ruby/Tk's composite widget
---------------------------------------------------------------------

--- Page 13 ---------------------------------------------------------
[ Creation Type 1 & 2 ]

* Those should be according to the general form of Tcl/Tk's
  widget creation command.
    <gen. command> <widget path> <option> <value> ...
    e.g. button .b -text Hello -command {puts "Hello !!"}

* By following the mechanism of Ruby/Tk's widget classes,
  you can easily define a new Ruby/Tk class.
---------------------------------------------------------------------

--- Page 14 ---------------------------------------------------------
[ Ruby/Tk's Widget Class ]

* Defined as a descendant of TkWindow class

* options at creation are given by a Hash
    <widget class>.new( <parent widget>, <option>=><value>, ... )

  e.g. TkButton.new(Tk.root,
                    :text=>'Hello',
                    :command=>proc{puts 'Hello !!'})
---------------------------------------------------------------------

--- Page 15 ---------------------------------------------------------
[ TkWindow#initialize ]

* Usually, no need to override on subclasses

* Operation
  1. process the options for widget path assignment,
     and decide the widget path
  2. extract options that require some special opetations
     (e.g. font option)
  3. call 'create_self' method
  4. (if need) exec font setting process
  5. (if need) process options that require some method calls
---------------------------------------------------------------------

--- Page 16 ---------------------------------------------------------
[ Options for Widget Path Assignment ]

* parent
  * Assign the parent widget
  * Usually, it is given by the 1st argument of 'new' method.
    It may be given on the Hash of option definition.

* widgetname
  * Use when need to give a specific name of widget,
    or when creating an object for a widget that already exists on Tk.

* without_creating
  * When the value is true, the process to creating a new widget
    is not called.
---------------------------------------------------------------------

--- Page 17 ---------------------------------------------------------
[ Options that Require Special Operations ]

* font options
  * to manage fonts by TkFont objects

* options which need to call some methods
  * mechanism treating features, which is not widget options,
    as if those are widget options.
  * to entry them, override "__methodcall_optkeys" method.

* options which need a special process for the value passed from Ruby to Tcl
  * to entry them, override "__ruby2val_optkeys" method.
---------------------------------------------------------------------

--- Page 18 ---------------------------------------------------------
[ TkWindow#create_self ]

* core method generatiing a widget by calling a Tcl/Tk command

* usually, no need to override

* use self.class::TkCommandNames[0] as the Tcl/Tk command to create
  a widget
---------------------------------------------------------------------

--- Page 19 ---------------------------------------------------------
[ Minimum Definition of a New Widget Class ]

For example ...

  Define Tk::Hoge class for widgets creating Tcl/Tk's "tk::hoge" command
  ===============================================================
    class Tk::Hoge < TkWindow
      TkCommandNames = ['tk::hoge'.freeze].freeze
    end
  ===============================================================

  call functions of a Tk::Hoge widget
  ===============================================================
    hoge1 = Tk::Hoge.new(parent, opt=>val, ... )
    hoge1.tk_send(<sub-command>, <option>, ... )
    Tk.tk_call(hoge1, <sub-command>, <option>, ... )
  ===============================================================
---------------------------------------------------------------------

--- Page 20 ---------------------------------------------------------
  However ...

    This minimum definition doesn't include cooperations with
    option database.
---------------------------------------------------------------------

--- Page 21 ---------------------------------------------------------
[ Option Database ]

* option (resouce) database
  * managing / setting default option values of each widget or
    widget class

  * same to the resource database of X Window System

  * a widget path == a widget name on the database

  * a widget class == a class name on the database

  * an option / option class == an option / option class on the database
---------------------------------------------------------------------

--- Page 22 ---------------------------------------------------------
[ Keep Class Name on Database ]

* TkOptionDB class can treat the option database

* When there is a database class name correspoiding to a widget class,
  the name should be defined as the value of the constant "WidgetClassName".

* When may need to auto-convert from a widget path to a widget object,
  the class name must be entried to TkComm::WidgetClassNames
   --> It is used to search a widget class from a database class name.
---------------------------------------------------------------------

--- Page 23 ---------------------------------------------------------
[ Convert to an Object from a Widget Path ]

* Tcl/Tk is distinguish widgetds by their widget path.

* need to manage mappings between a widget path and a widget object

* widgets cerated on Ruby/Tk
   --> manage mappings on a Hash table

* widgets cerated on Tcl/Tk
   --> ? ? ? ?

---------------------------------------------------------------------

--- Page 24 ---------------------------------------------------------
[ Auto-create an Object from a Widget Path having no Mapping Informaiton ]

1. check the widget class name on Tcl/Tk

2. search Ruby/Tk' widget class corresponding to the widget class name
    a) exist
        --> create an object without creating a new widget
    b) not exist
        --> create automatically a new widget class of Ruby/Tk based on
            the class name, and create an object of the widget class
  ===============================================================
   TkComm.window(<widget path>)
     --> create a widget object from a widget path by the described way
  ===============================================================
---------------------------------------------------------------------

--- Page 25 ---------------------------------------------------------
[ Minimum Definition of a New Widget Class (with database class definition) ]

For example ...

  On the previous example (Tk::Hoge class), when the database class name
  of the generaged widget is "HogeWidget",
  ===============================================================
    class Tk::Hoge < TkWindow
      TkCommandNames = ['tk::hoge'.freeze].freeze
      WidgetClassName = 'HogeWidget'.freeze
      WidgetClassNames[WidgetClassName] = self
    end
  ===============================================================
---------------------------------------------------------------------

--- Page 26 ---------------------------------------------------------
[ Minimum Definition of a New Widget Class (with database class definition) ]

By this definition, for example ...
  ===============================================================
    h = Tk::Hoge.new.pack

    h.opt = val
    h[:opt] = val

    h.font.size *= 2
    h.bind('Enter'){|ev| p ev; puts ev.window.path}
    h.bind_append('Enter', '%W'){|w| w.focus}
    h.bind(['Control-x', 'a'] '%x %y'){|x,y| p [x,y]}
    h.bind_remove('Enter')

    h.destroy
  ===============================================================
---------------------------------------------------------------------

--- Page 27 ---------------------------------------------------------
[ Convert from Ruby's objects ]

* a widget object --> a widget path string

* an array --> a list on Tcl/Tk

* a Hash ( {k1=>v1, k2=>v2, ...} )
    --> a sequece of options ( -k1 v1 -k2 v2 ... )

* a proc object --> a string of a callback command
   (the proc object is managed on Ruby/Tk )

* and others ... --> convet to a proper string
---------------------------------------------------------------------

--- Page 28 ---------------------------------------------------------
[ Convert to Ruby's objects ]

* Try to auto-convert from a Tcl/Tk's value (string) to a Ruby's object
    TkComm.tk_tcl2ruby(val_str)

* When fail to auto-convert but know the expected value type,
    TkComm.bool(val_str)
    TkComm.string(val_str)
    TkComm.number(val_str)
    TkComm.list(val_str) ... et al
---------------------------------------------------------------------

--- Page 29 ---------------------------------------------------------
(3) Subclass of Ruby/Tk's widget class
---------------------------------------------------------------------

--- Page 30 ---------------------------------------------------------
[ Creation Type 3 ]

* Ruby/Tk has some mechanisms to reduce the amount of description.
  However, omit them in this presentation.

* Except for some widget classes, new widget classes generated by
  inheritance can't have their own database class.
    --> If you want to make and give a new database class,
        you must use "creation type 4".
---------------------------------------------------------------------

--- Page 31 ---------------------------------------------------------
(4) Ruby/Tk's composite widget
---------------------------------------------------------------------

--- Page 32 ---------------------------------------------------------
[ Creation Type 4 ]

* treat a structure of multiple widgets as a single widget
  * build a construction of widgets on a single base (frame widget)
  * control the construction as one widget object

* to support definition
   --> TkComposite module
---------------------------------------------------------------------

--- Page 33 ---------------------------------------------------------
[ TkComposite module ]

* support to define a composite widget class

* override "initialize" method
  1. estimate or define its database class name
  2. create a frame widget as a base, and set it to @frame
  3. set the widget pash of @frame to @epath and @path
  4. call "initialize_composite" method
---------------------------------------------------------------------

--- Page 34 ---------------------------------------------------------
[ @epath and @path ]

* @epath
  * The widget path for management of geometry managers
  * The default value is the widget path of @frame.
    Usually, it is not necessary to change the value.

* @path
  * should keep the widget path of the core (most important) widget
    on the component
  * treat it as a primary (default) target of method calls
---------------------------------------------------------------------

--- Page 35 ---------------------------------------------------------
[ initialize_composite method ]

* called from "initialize" method to construct and setup the composite
  widget object

* componets must be descendants of the @frame widget

* don't forget setting @path
---------------------------------------------------------------------

--- Page 36 ---------------------------------------------------------
[ Support to control widget options ]

* On a composite widget, a target widget set to control a widget
  option depends on the option.

* sometimes want to treat multiple groups of widgets to control
  the same option

* sometimes want to make a control of widgets by method calls
  seamless with general manipuration of options

  --> TkComposite module has the methods to support such purpose.
---------------------------------------------------------------------

--- Page 37 ---------------------------------------------------------
[ Delegate of Widget Option Control ]

* "deletete" and "delegate_alias"
  * define target widget set to control the specified option
    ( "delegate_alias" can define the alias name of the option )
  ===============================================================
    delegate(<option>, <widget>, ... )
    delegate("DEFAULT", <widget>, ... )

    delegate_alias(<alias>, <option>, <widget>, ... )
  ===============================================================

* "option_methods"
  * can treat like as an option but defined with method calls
  ===============================================================
    option_methods([<set>, <get>, <info>], ... )
  ===============================================================
---------------------------------------------------------------------

--- Page 38 ---------------------------------------------------------
[ Setting of the database class name of the widget using TkComposite ]

* Use the database class name of the base (@frame) as the name of
  the composite widget

* If you need to define the database class name, use one of the followings
  i) "classname" option given at widget creation
  ii) the constant "WidgetClassName"
---------------------------------------------------------------------

--- Page 39 ---------------------------------------------------------
[ Examples of TkComposite ]

* See the sample scipts in the directory "ext/tk/samples" on Ruby's
  source tree.

* There are many kind of examples. Please check them.
---------------------------------------------------------------------

--- Page 40 ---------------------------------------------------------
[ Conclusion ]

* I introduced a part of Ruby/Tk's functions to support to define new
  widget classes

* Please see the content about Ruby/Tk in "Rubyist Magazine #003"
  (in Japanese). A part of other Ruby/Tk's functions are described in it.
---------------------------------------------------------------------

--- Page 41 ---------------------------------------------------------
[ Appendix (Q&A at RubyKaigi2007) ]

* Are there examples or tutorials?
  * Please see the examples included in Ruby/Tk's source tree
  * One of the example "WidgtDemo" can show the source code of the
    current running demo on the text widget. You can edit the source
    on the text widget, and re-run the modified source (the original
    source is not changed). Probably, it is useful to learn Ruby/Tk.

* What is merit/demerit including as one of the standard library?
   --- omit ---

* Does work on JRuby?
  * Probably, Java users will not want to use Tk.
---------------------------------------------------------------------

--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
Department of Artificial Intelligence, Kyushu Institute of Technology