CLIM mail archive


More on highlighting

First of all, thanks to all who replied to my message.  I've made a little bit
of progress.  Second, here's the obligatory: CLIM 1.1, Allegro 4.1, Sun Sparc

I was mistaken with the example that had some text hanging out the end of a
highlighting box.  That only happens when the end of the longer line isn't
part of the presentation that ends the first line.  I managed to fix part
of my problem by specifying :single-box :highlighting.  It doesn't change
the look of the highlight, but it does stop other presentations from being

I tried adapting Chee's solution.  Basically, I converted the
highlight-text function into a highlight-presentation presentation method.
It sort of worked.  The problem is that I didn't give enough detail about
what I was doing, so that solution was not quite general enough.  So,
here's the detail:

I am currently trying to build a simple example of something I need for the
system I'm building.  This simple example involves parsing a paragraph of
text, but not in the natural language sense.  I accept a string from the
user and break it into sentences, then clauses, then words.  I end up with
a 4-deep tree representing the paragraph - the root is the paragraph, with
each child being a sentence, each grandchild a clause and each
great-grandchild a word.  Each node in the tree is called a context, and
the tree itself a context-tree.  Each context contains a "data-item"
object, and the start and end position of the data in the original string.
I have defined presentation methods for both contexts and data-items.  A
leaf context is presented by presenting it's data-item with :sensitive nil.
The presentation method for data-item simply uses format to output the
string.  There is a reason for this level of indirection, but it's not
really important here.  A non-leaf context is presented by presenting child
contexts separated by any filler that was in the original string (which
includes spaces, punctutation and newlines.

Next, I want the user to be able to select any context (whose corresponding
string is then bolded and some information about the context is displayed).

Using my adapted version of Chee, leaf contexts highlight properly.  But,
if I move the mouse cursor over a "filler" character, only the filler
characters of the corresponding non-leaf context are highlighted. 

Does anyone have any more ideas?  Here's the applicable code, if that
helps.  I store the selected context (the one that needs to be bolded) in a
slot in the application frame.  The highlighted-p presentation option is
set when the output needs to be bolded.  The filler characters are not yet
bolded when they should be, but only because I haven't fixed that part yet,
which should be easy.  Here's the code:
(clim:define-presentation-type context ()
  :options ((highlighted-p nil))

(clim:define-presentation-method clim:present
    (ctxt (type context) stream view &key)
  (declare (ignore view))
  (let* ((frame clim:*application-frame*)
         (sel (ke:selected-context frame))
         (data-string (data (data-item ctxt)) )
         (start (context-start ctxt))
         (pos start))
    (when (eq ctxt sel)
      (setq highlighted-p t))
    (cond ((null (context-children ctxt))
           (clim:present (data-item ctxt) `((context-data-item)
                                            :highlighted-p ,highlighted-p)
                         :stream stream
                         :single-box :highlighting
                         :sensitive nil))
          (t (loop 
                 for child in (context-children ctxt)
                 for ch-st = (context-start child)
                 for ch-end = (context-end child)
                 do (when (< pos ch-st)
                      (format stream "~A" (subseq data-string 
                                                  (- pos start)
                                                  (- ch-st start) ))
                      (setq pos ch-st))
                    (clim:present child `((context)
                                          :highlighted-p ,highlighted-p)
                                  :stream stream
                                  :single-box :highlighting)
                    (setq pos ch-end)
                 finally (format stream "~A" (subseq data-string 
                                                     (- pos start) )) ))

;;; Only sort of working.  Will figure out later.  When selecting a context
;;; that has nested presentations, only the top level "filler" is
;;; highlighted.  See comment below.
(clim:define-presentation-method clim:highlight-presentation
    ((type context) record stream state)
  (declare (ignore state))
  (multiple-value-bind (xoff yoff)
       stream record)
    (clim:with-translation (stream xoff yoff)
       #'(lambda (rec)
           ;; *** I think the problem is here: the typep test is likely too
           ;; restrictive, since the nested presentations don't appear as
           ;; text-output-record-elements.
           (when (typep rec 'clim::text-output-record-element)
                 (tp lf bm rt) 
               (clim:draw-rectangle* stream (1- tp) (1- lf) (1+ bm) (1+ rt)
                                     :filled nil :ink clim:+flipping-ink+)) ))

(clim:define-presentation-method clim:present
    (cdi (type context-data-item) stream view &key)
  (declare (ignore view))
  (clim:with-text-face ((if highlighted-p
    (display-data-item cdi stream))

Thanks for any help you can give me.


Randy A. Coulman                |       ARIES Laboratory
                                |       Department of Computational Science             |       University of Saskatchewan
                                |       Saskatoon, SK   S7N 0W0             


Main Index | Thread Index