Update of /project/cells-gtk/cvsroot/public_html In directory common-lisp.net:/tmp/cvs-serv17280/public_html
Modified Files: cgtk-primer.html Log Message: Messy, some errors, but I'm going to use it anyway. Date: Sat Oct 8 17:03:00 2005 Author: pdenno
Index: public_html/cgtk-primer.html diff -u public_html/cgtk-primer.html:1.4 public_html/cgtk-primer.html:1.5 --- public_html/cgtk-primer.html:1.4 Sat Oct 1 21:03:15 2005 +++ public_html/cgtk-primer.html Sat Oct 8 17:03:00 2005 @@ -25,18 +25,101 @@
<h1>Introduction</h1>
-Here we will discuss the most important parts of the cell-gtk GTK binding, and how -cells can be used in defining cells-gtk GUIs. As of this writing, we have begun -the discussion of cells. This minimal introduction might be sufficient to get you -started. We'll see. +<strong>[This is Work In Progress currently. My apologies.]</strong><p/>
-<h1>Cells slots</h1> +Here we will discuss the most important parts of the cells-gtk GTK binding, and how +cells can be used in defining cells-gtk GUIs. This minimal introduction might be +sufficient to get you started. We'll see. + +<h2>Cells, Cell slots, and all that...</h2> + +The example from <a href='http://bc.tech.coop/blog/030911.html'>Bill Clementson's Blog</a> +is a nice starting point. Read it and come back here.<p/> + +...Welcome back. Perhaps you came back with the impression that Cells is a way to manage +the relationship among the values in the slots of a CLOS object. That would be good. +You might also imagine that if the slots describe the state of some real world object like a motor, +you could use Cells to control the object -- to orchestrate how all its parts work together +toward some goal. That also would be good. Now, if that object were a GTK-based GUI... no +I'm getting ahead of myself. Let's look at the basic idea of Cells, it is similar to +<a href="http://en.wikipedia.org/wiki/Constraint_satisfaction">constraint satisfaction</a>. +That is, you have values, and rules that govern the relationships among the values, +and whenever the network is pushed out of a consistent state (i.e. whenever the rules +no longer hold), the objective is to get it back to a consistent one by updating some values. +In Bill's example, <em>status fuelpump</em> and <em>temp</em> are cells -- slots in +a motor CLOS object whose values are managed by the cells constraint network. +The constraint network itself might be depicted as this: +<p/> +[graph] +<p/> +In this graph the nodes are values and edges have rules attached. The collection of edges +into a node together with the rule are the cell. +<!-- (hmmm is this going to work?) --> The green nodes +are values controlled by cells and the empty nodes are regular 'unmanaged' values +(such as you get by reading the value from regular CLOS slot). +<p/> +Cells such as <em>temp</em>, which have no edges leading into them, are called 'c-input cells'. +A c-input cell gives you an opportunity to push the network out of a consistent state, +so that it must find another consistent state (raise the temperature, force the motor +and fuel pump to stop). They are one way the network interacts with its environment. +(Thinking about GUI: Part of the 'environment' of your Cells-GTK application are lisp objects, +the state of which you'd like to communicate to the user.) +<p/> +Another way that the cells network can interact with its environment is through +c-output (or c-echo) methods. These are 'observers' of a cell that are invoked when the +value of that cell is modified. They are sort of the converse of the c-input: modify +a c-input value and the network reacts; when the network reacts, it can modify +values outside the network with a c-output. +<p/> +So what about the values <em>inside</em> the network -- the nodes with edges pointing into them? +Observing those with c-output methods and using c-input and setf to modify them would be +bad form. If you program that way, you aren't doing anything that couldn't be done without Cells. +Drop Cells-GTK and go back to programming in C-based GTK or Java. The result will be that you +hand back to the programmer the burden of keeping track of every change to the GUI. +C-input cells are intended (small apps like Bill's aside) to be used to 'instrument' +(or "put sensors on") your code. If you have a legacy code that you are building a Cells-GTK GUI for, .... +<p/> + + +<!-- +[They are what allow the object represented by the network to interact with its environment.] +--> +<p/> + + +<p/> +Now reiterating the ideas above: + +<ul> + <li>A <strong>cell</strong> is a slot in a CLOS object whose value is managed by accessors that are + part of a cells constraint network. + <li>A <strong>cells constraint network</strong> is a collection of cells that are interrelated through + reference to each other or through reference to other lisp objects, through any level of indirection. + <li>A <strong>c-input cell</strong> is a cell whose value may be set through explicit procedural code, + using setf on the slot. Note: setf-ing the cell causes the values of other cells to be recomputed -- + provided the cell is referenced by other cells in a cells constraint network.</li> + <li>A <strong>c-formula cell</strong> is a cell whose value is obtained through evaluation of a formula. + Note: The usual semantics of :initform do not apply when :initform is given by c-formula. + Instead of just setting the value at initialization, a formula (derived from the supplied lisp form) + specifies the dynamic relationship between the slot's value and other aspects of the program state. + <li>A <strong>c-output method</strong> is a method on a cell that is evaluated when the value of the + cell changes. +</ul>
-The cells defmodel provides for the declaration of several kinds of "cell slots," +Cells provides for the declaration of several kinds of "cell slots," but for the purpose of talking about cells-gtk, we can limit the discussion to -just a few kinds. However, first we should point out that by specifying +just the c-input and c-formula cells. How do you recognize what kind of cell slot +is being used? Well, first we should point out that by specifying :cell nil in a defmodel slot definition, the slot defined is an ordinary CLOS -slot and none of the following pertains. +slot. The rest are specified using :initform on the slot. The following defmodel +defines a c-input cell, a c-formula cell and a regular CLOS slot. + +<pre> +(defmodel example () + ((control-me :initform (c-input (some-form-foo)) :accessor control-me) + (im-computed :initform (c-formula (some-form-bar)) :accessor im-computed) + (im-clos :cell nil :initform nil))) +</pre>
<tt> <pre> @@ -62,7 +145,6 @@ <li>A <strong>cell slot</strong> is specified by :cell t (advanced options aside) or by omitting the :cell option, since in defmodel, the default is t.</li>
- <li>An <strong>invariant cell slot</strong> is a cell slot that is initialized by an ordinary lisp form, either by an :initarg in make-instance, an :initform in the slot definition, or :default-initargs in the defmodel. The value of an @@ -87,6 +169,10 @@ are consistent at some point after the values of some of them are changed.</li> </ul>
+<h2>Cells and Cells-GTK</h2> + +<h2>Good Cells Technique</h2> + This all may seem abstract, but it has practical value in the design of your GUI. For example, I might set the :sensitivity of a button, the :text in a label or :fraction of a progress-bar based on @@ -150,8 +236,32 @@ <h1>Family: Referencing cells throughout the defmodel hierarchy.</h1>
The <strong>defmodel</strong> macro defines a part-subpart relationship -among components of the interface. The relationship is made by the -<strong>:kids</strong> :initarg or :default-initargs, of the parent model. +among components of the interface. The relationship is made by the <strong>:kids</strong> initarg. +<strong>:kids</strong> is given a list of children. In a cells-gtk defmodel some kids might be GTKContainer +(vbox, hbox, etc) -- things that in the GTK world, have kids of their own. It may be a natural coding practice +in that case for the defmodel to define a fairly deep ancestory hierarchy, laying out the arrangement of widgets. +(You're free to break things up wherever seem reasonable for your application). It might look like this: + +<pre> +(defmodel my-app (gtk-app) + () + (:default-initargs + :md-name :my-app + :kids + (list + (mk-vbox + :kids + (list + (mk-hbox + :kids + (list (mk-combo-box :md-name :my-combo) ...)) + (mk-hbox + :kids + (list (make-instance 'my-subpart)))))))) +</pre> +The point of the Family methods is to allow things a different places in this hierarchy (e.g. :my-combo +to reference :my-app). + <p/> <em>More will be written about this soon.</em>