comparison mde/gui/widget/layout.d @ 179:1f9d00f392bd default tip

Fixed a bug where (non-resizible) widgets wouldn't get shrunk when minimal size decreases, meaning optional context menus are hiden properly now. Optimised when ServiceContentList.opCall is called, I think without breaking anything.
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 15 Sep 2009 20:09:59 +0200
parents af40e9679436
children
comparison
equal deleted inserted replaced
178:62aa8845edd2 179:1f9d00f392bd
636 } 636 }
637 637
638 /** Get the row/column of relative position l. 638 /** Get the row/column of relative position l.
639 * 639 *
640 * returns: 640 * returns:
641 * -i if in space to left of col i, or i if on col i. */ 641 * -i if in space to left of col i, or i if on col i.
642 *
643 * Handles l right-of-last-column fine, asserts if l < pos[0]. */
642 ptrdiff_t getCell (wdim l) { 644 ptrdiff_t getCell (wdim l) {
643 debug assert (width, "AlignColumns not initialized when getCell called (code error)"); 645 debug assert (width, "AlignColumns not initialized when getCell called (code error)");
644 ptrdiff_t i = cols - 1; // starting from right... 646 ptrdiff_t i = cols - 1; // starting from right...
645 while (l < pos[i]) { // decrement while left of this column 647 while (l < pos[i]) { // decrement while left of this column
646 debug assert (i > 0, "getCell: l < pos[0] (code error)"); 648 debug assert (i > 0, "getCell: l < pos[0] (code error)");
665 return w; 667 return w;
666 } 668 }
667 if (nw == w) return w; 669 if (nw == w) return w;
668 670
669 wdim diff = nw - w; 671 wdim diff = nw - w;
670 if (firstSizable == -1) 672 if (diff > 0) {
671 diff = adjustCellSizes (diff, cols-1, -1); 673 if (firstSizable == -1)
672 else 674 diff = adjustCellSizes (diff, cols-1, -1);
673 diff = adjustCellSizes (diff, (dir == -1 ? lastSizable : firstSizable), dir); 675 else
676 diff = adjustCellSizes (diff, (dir == -1 ? lastSizable : firstSizable), dir);
677 debug assert (diff == 0);
678 } else {
679 // For decreasing, visit all cols; it's possible some have size above minimal
680 diff = adjustCellSizes (diff, (dir == -1 ? cols-1 : 0), dir);
681 debug if (diff != 0)
682 logger.warn ("Unable to meet target width ({}); outstanding diff: {}", nw, diff);
683 }
674 genPositions; 684 genPositions;
675 685
676 debug if (nw != w) { 686 debug if (nw != w) {
677 logger.trace ("resizeWidth on {} to {} failed, new width: {}, diff {}, firstSizable {}, columns {}",cast(void*)this, nw,w, diff, firstSizable, cols); 687 logger.error ("resizeWidth on {} to {} failed, new width: {}, diff {}, firstSizable {}, columns {}",cast(void*)this, nw,w, diff, firstSizable, cols);
678 /+ Also print column widths & positions: 688 /+ Also print column widths & positions:
679 logger.trace ("resizeWidth to {} failed! Column dimensions and positions:",nw); 689 logger.error ("resizeWidth to {} failed! Column dimensions and positions:",nw);
680 foreach (i,w; width) 690 foreach (i,w; width)
681 logger.trace ("\t{}\t{}", w,pos[i]);+/ 691 logger.error ("\t{}\t{}", w,pos[i]);+/
682 } 692 }
683 return w; 693 return w;
684 } 694 }
685 695
686 /** Calculate resizeU/resizeD, and return true if unable to resize. 696 /** Calculate resizeU/resizeD, and return true if unable to resize.
687 * 697 *
688 * This and resizeCols are for moving dividers between cells. */ 698 * This and resizeCols are for moving dividers between cells. */
689 bool findResizeCols (wdim l) { 699 bool findResizeCols (wdim l) {
690 resizeU = -getCell (l); // potential start for upward-resizes 700 resizeU = -getCell (l); // potential start for upward-resizes
691 if (resizeU <= 0) 701 if (resizeU <= 0)
692 return true; // not on a space between cells 702 return true; // not on a space between cells
703 if (resizeU >= cols) { // right of last column; cannot resize
704 resizeU = -1;
705 return true;
706 }
693 resizeD = resizeU - 1; // potential start for downward-resizes 707 resizeD = resizeU - 1; // potential start for downward-resizes
694 708
695 while (!sizable[resizeU]) { // find first actually resizable column (upwards) 709 while (!sizable[resizeU]) { // find first actually resizable column (upwards)
696 ++resizeU; 710 ++resizeU;
697 if (resizeU >= cols) { // cannot resize 711 if (resizeU >= cols) { // cannot resize
715 { 729 {
716 if (resizeU <= 0) return; 730 if (resizeU <= 0) return;
717 731
718 // do shrinking first (in case we hit the minimum) 732 // do shrinking first (in case we hit the minimum)
719 if (diff >= 0) { 733 if (diff >= 0) {
720 diff = -adjustCellSizes (-diff, resizeU, 1); 734 diff = adjustCellSizes (-diff, resizeU, 1) - diff;
721 adjustCellSizes (diff, resizeD, -1); 735 diff = adjustCellSizes (diff, resizeD, -1);
722 } else { 736 } else {
723 diff = -adjustCellSizes (diff, resizeD, -1); 737 diff = adjustCellSizes (diff, resizeD, -1) - diff;
724 adjustCellSizes (diff, resizeU, 1); 738 diff = adjustCellSizes (diff, resizeU, 1);
725 } 739 }
740 debug assert (diff == 0);
726 genPositions; 741 genPositions;
727 } 742 }
728 743
729 /** Called when one of the cells in column col now has minimal width nmw. 744 /** Called when one of the cells in column col now has minimal width nmw.
730 * 745 *
749 nmw = mcw; 764 nmw = mcw;
750 } 765 }
751 if (minWidth[col] == nmw) // no change 766 if (minWidth[col] == nmw) // no change
752 return false; 767 return false;
753 minWidth[col] = nmw; 768 minWidth[col] = nmw;
754 if (!sizable[col] && lastSizable >= 0) 769 if (!sizable[col])
755 nd = width[col] - nmw; // Not resizable but another column is 770 nd = width[col] - nmw; // Not resizable, so shrink
756 // Else leave larger; mustn't shrink ourself 771 // Else resizable so leave
757 } else 772 }
758 return false;
759
760 mw = spacing * cast(wdim)(cols - 1); 773 mw = spacing * cast(wdim)(cols - 1);
761 foreach (imw; minWidth) 774 foreach (imw; minWidth)
762 mw += imw; 775 mw += imw;
763 776
764 if (nd != 0) { // needs enlarging or shrinking 777 if (nd == 0)
778 return false;
779
780 if (nd < 0) { // needs enlarging; we should do so here
781 // set new width:
765 width[col] = nmw; 782 width[col] = nmw;
766 foreach (cb; cbs) 783 foreach (cb; cbs)
767 cb.setWidth (col, nmw, -1); 784 cb.setWidth (col, nmw, -1);
768 if (lastSizable >= 0) 785 // Try to compensate (keep overall size the same by shrinking larger
769 adjustCellSizes (nd, lastSizable, -1); 786 // than necessary columns); may not be possible:
770 } 787 adjustCellSizes (nd, 0, 1);
771 788 } else if (lastSizable >= 0) {
789 // If another column can be increased, do that (otherwise the call
790 // to parent.minXChange should decrease, if possible):
791 // Although it _may_ not, if e.g. alignment forces larger-than-minimal size.
792 width[col] = nmw;
793 foreach (cb; cbs)
794 cb.setWidth (col, nmw, -1);
795 nd = adjustCellSizes (nd, lastSizable, -1);
796 debug assert (nd == 0);
797 }
798 //else debug logger.trace ("expecting parent.minXChange to shrink");
799
772 debug wdim ow = w; 800 debug wdim ow = w;
773 genPositions; 801 genPositions;
774 debug if (w < ow) 802 debug if (w < ow)
775 logger.error ("newMinWidth: shrunk (code error); w={}, ow={}, nd={}", w,ow,nd); 803 logger.error ("newMinWidth: shrunk (code error); w={}, ow={}, nd={}", w,ow,nd);
776 804
798 * diff = amount to increase/decrease the total size 826 * diff = amount to increase/decrease the total size
799 * start= index for col/row to start resizing on; assumed to be sizable 827 * start= index for col/row to start resizing on; assumed to be sizable
800 * incr = direction to resize in (added to index each step). Must be either -1 or +1. 828 * incr = direction to resize in (added to index each step). Must be either -1 or +1.
801 * 829 *
802 * Returns: 830 * Returns:
803 * The amount adjusted. This may be larger than diff, since cellD is clamped by cellDMin. 831 * (diff - "the actual amount adjusted") - 0 if met exactly, <0 if unable
832 * to shrink as much as requested.
804 * 833 *
805 * Will shrink non-sizable columns if they're over minimal size. 834 * Will shrink non-sizable columns if they're over minimal size.
806 * Will increase column start, since it's assumed sizable. 835 * Will increase column start, since it's assumed sizable.
807 * 836 *
808 * Note: Check variable used for start is valid before calling! If a non- 837 * Note: Check variable used for start is valid before calling! If a non-
819 ptrdiff_t i = start; 848 ptrdiff_t i = start;
820 if (diff > 0) { // increase size of first resizable cell 849 if (diff > 0) { // increase size of first resizable cell
821 width[i] += diff; 850 width[i] += diff;
822 foreach (cb; cbs) 851 foreach (cb; cbs)
823 cb.setWidth (i, width[i], incr); 852 cb.setWidth (i, width[i], incr);
853 return 0;
824 } 854 }
825 else if (diff < 0) { // decrease 855 else if (diff < 0) { // decrease
826 wdim rd = diff; // running diff 856 wdim rd = diff; // running diff
827 while (i >= 0 && i < cols) { 857 while (i >= 0 && i < cols) {
828 if (width[i] > minWidth[i]) { 858 if (width[i] > minWidth[i]) {
841 // rd is remainder to decrease by 871 // rd is remainder to decrease by
842 } 872 }
843 873
844 i += incr; 874 i += incr;
845 } 875 }
846 diff -= rd; // still had rd left to decrease (may be 0) 876 return rd; // still had rd left to decrease (may be 0)
847 } 877 }
848 // else no adjustment needed (diff == 0) 878 // else no adjustment needed (diff == 0)
849 879 return 0;
850 return diff;
851 } 880 }
852 881
853 882
854 /** Minimal widths per cell. 883 /** Minimal widths per cell.
855 * 884 *