Mercurial > projects > mde
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 * |