small pane sizing improvement


to wilyfans@jli.com
From Bill Trost <trost@cloud.rain.com>
Date Thu, 31 Aug 1995 16:33:39 -0700
Sender owner-wilyfans@jli.portland.or.us



The following patch changes the pane sizing algorithm so that there
isn't any "wasted" space with a partial lines at the bottom of the
pane, by shortening the pane to be just large enough to include all
the lines it can show.

I noticed while debugging this that there's an ugly dependency on the
pane drawing order.  Create three panes in a column, and drag the
middle pane up so that the top pane is nothing but tag.  The bottom
pane will get its scrollbar clobbered.

This should be an easy fix, but I wanted to separate fixes from
feechurs.

I'll leave it up to Gary to integrate this into the next "release".


--- 1.1 1995/08/31 21:26:10
+++ pane.c      1995/08/31 23:26:47
@@ -75,17 +75,51 @@
        p->needsreshape = false;
 }
 
+/* Sets the rectangle size for the current, and maybe the
+    following rectangle.  Returns non-zero if pane->below
+    needs a resize.  r is modified to indicate the pane's new
+    size, (its x coordinates are unchanged, however).
+ */
+static int
+pane_set_reshape_rect(Pane *p, Rectangle *r) {
+       int             old;
+       ulong   height;
+
+       r->min.y = p->offset;
+       if (!p->below) {
+               r->max.y = screen.r.max.y;
+               return 0;
+       }
+
+       /* Cleverness -- don't use up screen space for partial lines.
+          Even cleverer would be to round instead of truncate, but
+          truncating isn't any worse than not addressing the issue.
+          16 is the cumulative sun of the magic border widths
+          implemented in libtext. */
+       height = p->below->offset - r->min.y - 16;
+       height = (height / font->height) * font->height + 16;
+       if (height <= TAGHEIGHT + 8)
+               height = TAGHEIGHT;
+       old = p->below->offset;
+       p->below->offset = r->max.y = r->min.y + height;
+       return old != p->below->offset;
+}
+
 /* Redraw pane, calculate our own rectangle.
  */
 static void
 pane_reshaped(Pane *p)
 {
        Rectangle       r;
+       int     change;
 
        r = column_rectangle(p->column);
-       r.min.y = p->offset;
-       r.max.y = p->below ? p->below->offset : screen.r.max.y;
+       change = pane_set_reshape_rect(p, &r);
        pane_reshapedr(p,r);
+       if (!change)
+               return;
+       assert(p->below);
+       pane_reshaped(p->below);
 }
 
 /* Redraw a list of panes inside box.  No squeezing.
@@ -95,8 +129,7 @@
 pane_list_reshaped(Pane *p, Rectangle r)
 {
        for (; p; p=p->below) {
-               r.min.y = p->offset;
-               r.max.y = (p->below) ? p->below->offset : screen.r.max.y;
+               (void) pane_set_reshape_rect(p, &r);
                pane_reshapedr(p, r);
        }
 }
 


Partial thread listing: