[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Window zooming weirdness

On Tue Nov  2 17:20, gray@ils.nwu.edu writes:
---> Start of edited message
I'm trying to implement this as a zoomed/normal state of the window where
the zoomed state is the whole picture and nothing but the picture, and the
normal state has the scaled picture and other stuff.
Initially the window is created/opened in normal mode, so the "zoomed-p"
slot has a value of "nil".

Here are the methods I've defined on my new window-based class:

(defmethod window-zoom-position ((window picture-window))
  (if (zoomed-p window)
    (zoom-position window)
    (normal-position window)))
(defmethod window-zoom-size ((window picture-window))
  (if (zoomed-p window)
    (zoom-size window)
    (normal-size window)))
(defmethod window-zoom-event-handler :before ((window picture-window)
  (let ((zoom-state (zoomed-p window))
        (new-zoom-state (eql message #$InZoomOut)))
    (when (and new-zoom-state (not zoom-state))
      (setf (normal-position window) (view-position window)))
    (setf (zoomed-p window) new-zoom-state)))
(defmethod window-size-parts ((window picture-window))
  (let ((picture (view-named 'picture window))
        (caption (view-named 'caption window)))
    (when (and picture caption)
      (let* ((caption-position (view-position caption))
             (caption-height (point-v (view-size caption)))
             (caption-h (point-h caption-position))
             (dimensions (view-size window)))
        (if (zoomed-p window)
          (let ((caption-v (+ 10 (point-v dimensions))))
            (set-view-position picture 0 0)
            (set-view-size picture dimensions)
            (set-view-position caption caption-h caption-v))
          (let ((caption-v (- (point-v dimensions) caption-height 10)))
            (set-view-position picture 10 10)
            (set-view-size picture 320 240)
            (set-view-position caption caption-h caption-v)))))))

The problem is this: the window will zoom to the correct size and position
on the very first click in the zoom box; however, any subsequent click
not change the size and/or position of the window, yet the two views
the window toggle as expected.

I've tried wrapping calls to "set-window-zoom-position" and "-size" around
the then and else forms in "window-zoom-position" and "window-zoom-size"
methods, but that doesn't seem to make a difference.
--> End of message text
I've been able to reproduce the effect in a window containing no
subviews. (* It would be helpful if you had included the class
definition of the window, the subviews and the initialize-instance.
Alternateively, it would have been ok to strip the example to
a simpler one *)

Here's code that will do what you want. I have not rewritten the
window-size-parts function. The window contains no views.
I've also changed the title of the window, toggling between Normal
and Zoom. The class of the window is a-pict-win, since you'll need
to remove methods for the existing pict-win.

The crucial step apppear to be ignoring the message passed to
window-zoom-event-handler and forcing the window to zoom-out everytime.
Everytime the zoom box is clicked, the window toggles between 
the normal and zoom settings for the window position and size.
The system also switches the window title between "Zoomed" and "Normal".

If you want to examine scrolling picture windows, see my contrib code
(from cambridge.apple.com) in pub/MCL2/contrib/pic-window.lisp.hqx
which allows you to scale a picture, preserving its proportions.



(defclass a-pict-win (window)
  ((zoom-position :initform nil :accessor zoom-position)
   (zoom-size :initform nil :accessor zoom-size)
   (normal-size :initform nil :accessor normal-size)
   (normal-position :initform nil :accessor normal-position)
   (zoomed-p :initform nil :accessor zoomed-p))
    :window-type :document-with-zoom
    :window-title "Display"))

(defmethod initialize-instance ((window a-pict-win) &rest initargs)
  (apply #'call-next-method window initargs)
  (setf (normal-size window) (view-size window)
        (normal-position window) (view-position window)
        (zoom-size window) #@(200 200)
        (zoom-position window) #@(50 50)))

(defmethod window-zoom-event-handler ((window a-pict-win)
  (declare (ignore message))
  (if (zoomed-p window)
    (save-zoom-settings window)
    (save-normal-settings window))
  ;; crucial code for switching between the normal and default settings
  (call-next-method window #$InZoomOut)
  ;; change from zoom -> normal or normal -> view and change window title
  (setf (zoomed-p window) (not (zoomed-p window)))
  (set-window-title window (if (zoomed-p window)
                             "Zoomed" "Normal")))

(defmethod window-zoom-position ((window a-pict-win))
 (if (zoomed-p window)
   (normal-position window)
   (zoom-position window)))
(defmethod window-zoom-size ((window a-pict-win))
  (if (zoomed-p window)
   (normal-size window)
   (zoom-size window)))

(defmethod save-normal-settings ((window a-pict-win))
  (setf (normal-position window) (view-position window))
  (setf (normal-size window) (view-size window)))

(defmethod save-zoom-settings ((window a-pict-win))
  (setf (zoom-position window) (view-position window))
  (setf (zoom-size window) (view-size window)))

(setq that (make-instance 'a-pict-win))