/[emacs]/emacs/src/window.c
ViewVC logotype

Diff of /emacs/src/window.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.449 by kfstorm, Wed Sep 24 23:52:45 2003 UTC revision 1.450 by jhd, Sat Oct 11 23:03:09 2003 UTC
# Line 2538  adjust_window_margins (w) Line 2538  adjust_window_margins (w)
2538    return 1;    return 1;
2539  }  }
2540    
2541    /* Calculate new sizes for windows in the list FORWARD when the window size
2542       goes from TOTAL to SIZE.  TOTAL must be greater than SIZE.
2543       The number of windows in FORWARD is NCHILDREN, and the number that
2544       can shrink is SHRINKABLE.
2545       The minimum size a window can have is MIN_SIZE.
2546       If we are shrinking fixed windows, RESIZE_FIXED_P is non-zero.
2547       If we are shrinking columns, WIDTH_P is non-zero, otherwise we are
2548       shrinking rows.
2549    
2550       This function returns an allocated array of new sizes that the caller
2551       must free.  The size -1 means the window is fixed and RESIZE_FIXED_P
2552       is zero.  Array index 0 refers to the first window in FORWARD, 1 to
2553       the second, and so on.
2554    
2555       This function tries to keep windows at least at the minimum size
2556       and resize other windows before it resizes any window to zero (i.e.
2557       delete that window).
2558    
2559       Windows are resized proportional to their size, so bigger windows
2560       shrink more than smaller windows.  */
2561    static int *
2562    shrink_windows (total, size, nchildren, shrinkable,
2563                    min_size, resize_fixed_p, forward, width_p)
2564         int total, size, nchildren, shrinkable, min_size;
2565         int resize_fixed_p, width_p;
2566         Lisp_Object forward;
2567    {
2568      int available_resize = 0;
2569      int *new_sizes;
2570      struct window *c;
2571      Lisp_Object child;
2572      int smallest = total;
2573      int total_removed = 0;
2574      int total_shrink = total - size;
2575      int i;
2576    
2577      new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
2578    
2579      for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
2580        {
2581          int child_size;
2582    
2583          c = XWINDOW (child);
2584          child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
2585    
2586          if (! resize_fixed_p && window_fixed_size_p (c, width_p, 0))
2587            new_sizes[i] = -1;
2588          else
2589            {
2590              new_sizes[i] = child_size;
2591              if (child_size > min_size)
2592                available_resize += child_size - min_size;
2593            }
2594        }
2595      /* We might need to shrink some windows to zero.  Find the smallest
2596         windows and set them to 0 until we can fulfil the new size.  */
2597    
2598      while (shrinkable > 1 && size + available_resize < total)
2599        {
2600          for (i = 0; i < nchildren; ++i)
2601            if (new_sizes[i] > 0 && smallest > new_sizes[i])
2602              smallest = new_sizes[i];
2603    
2604          for (i = 0; i < nchildren; ++i)
2605            if (new_sizes[i] == smallest)
2606              {
2607                /* Resize this window down to zero.  */
2608                new_sizes[i] = 0;
2609                if (smallest > min_size)
2610                  available_resize -= smallest - min_size;
2611                available_resize += smallest;
2612                --shrinkable;
2613                total_removed += smallest;
2614    
2615                /* Out of for, just remove one window at the time and
2616                   check again if we have enough space.  */
2617                break;
2618              }
2619        }
2620    
2621      /* Now, calculate the new sizes.  Try to shrink each window
2622         proportional to its size.  */
2623      for (i = 0; i < nchildren; ++i)
2624        {
2625          if (new_sizes[i] > min_size)
2626            {
2627              int to_shrink = total_shrink*new_sizes[i]/total;
2628              if (new_sizes[i] - to_shrink < min_size)
2629                to_shrink = new_sizes[i] - min_size;
2630              new_sizes[i] -= to_shrink;
2631              total_removed += to_shrink;
2632            }
2633        }
2634    
2635      /* Any reminder due to rounding, we just subtract from windows
2636         that are left and still can be shrunk.  */
2637      while (total_shrink > total_removed)
2638        {
2639          for (i = 0; i < nchildren; ++i)
2640            if (new_sizes[i] > min_size)
2641              {
2642                --new_sizes[i];
2643                ++total_removed;
2644    
2645                /* Out of for, just shrink one window at the time and
2646                   check again if we have enough space.  */
2647                break;
2648              }
2649        }
2650    
2651      return new_sizes;
2652    }
2653    
2654  /* Set WINDOW's height or width to SIZE.  WIDTH_P non-zero means set  /* Set WINDOW's height or width to SIZE.  WIDTH_P non-zero means set
2655     WINDOW's width.  Resize WINDOW's children, if any, so that they     WINDOW's width.  Resize WINDOW's children, if any, so that they
# Line 2641  size_window (window, size, width_p, node Line 2753  size_window (window, size, width_p, node
2753        int fixed_size, each, extra, n;        int fixed_size, each, extra, n;
2754        int resize_fixed_p, nfixed;        int resize_fixed_p, nfixed;
2755        int last_pos, first_pos, nchildren, total;        int last_pos, first_pos, nchildren, total;
2756          int *new_sizes = NULL;
2757    
2758        /* Determine the fixed-size portion of the this window, and the        /* Determine the fixed-size portion of the this window, and the
2759           number of child windows.  */           number of child windows.  */
# Line 2665  size_window (window, size, width_p, node Line 2778  size_window (window, size, width_p, node
2778           windows.  */           windows.  */
2779        resize_fixed_p = nfixed == nchildren || size < fixed_size;        resize_fixed_p = nfixed == nchildren || size < fixed_size;
2780    
2781        /* Compute how many lines/columns to add to each child.  The        /* Compute how many lines/columns to add/remove to each child.  The
2782           value of extra takes care of rounding errors.  */           value of extra takes care of rounding errors.  */
2783        n = resize_fixed_p ? nchildren : nchildren - nfixed;        n = resize_fixed_p ? nchildren : nchildren - nfixed;
2784        each = (size - total) / n;        if (size < total && n > 1)
2785        extra = (size - total) - n * each;          new_sizes = shrink_windows (total, size, nchildren, n, min_size,
2786                                        resize_fixed_p, *forward, width_p);
2787          else
2788            {
2789              each = (size - total) / n;
2790              extra = (size - total) - n * each;
2791            }
2792    
2793        /* Compute new children heights and edge positions.  */        /* Compute new children heights and edge positions.  */
2794        first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);        first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
2795        last_pos = first_pos;        last_pos = first_pos;
2796        for (child = *forward; !NILP (child); child = c->next)        for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
2797          {          {
2798            int new_size, old_size;            int new_size, old_size;
2799    
# Line 2692  size_window (window, size, width_p, node Line 2811  size_window (window, size, width_p, node
2811            /* If this child can be resized, do it.  */            /* If this child can be resized, do it.  */
2812            if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))            if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
2813              {              {
2814                new_size = old_size + each + extra;                new_size = new_sizes ? new_sizes[n] : old_size + each + extra;
2815                extra = 0;                extra = 0;
2816              }              }
2817    
# Line 2703  size_window (window, size, width_p, node Line 2822  size_window (window, size, width_p, node
2822    
2823            /* Remember the bottom/right edge position of this child; it            /* Remember the bottom/right edge position of this child; it
2824               will be used to set the top/left edge of the next child.  */               will be used to set the top/left edge of the next child.  */
2825            last_pos += new_size;            last_pos += new_size;
2826          }          }
2827    
2828          if (new_sizes) xfree (new_sizes);
2829    
2830        /* We should have covered the parent exactly with child windows.  */        /* We should have covered the parent exactly with child windows.  */
2831        xassert (size == last_pos - first_pos);        xassert (size == last_pos - first_pos);
2832    

Legend:
Removed from v.1.449  
changed lines
  Added in v.1.450

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26