summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2017-04-11 14:47:18 (GMT)
committerdgp <dgp@users.sourceforge.net>2017-04-11 14:47:18 (GMT)
commit114422ec97ee32fa6c8690f42d065c3b3c0a86f0 (patch)
tree5fd8ace33fdad30a4968b161edabcce2b60c9ef0 /generic
parent0c9cc5316ee8883de4c5d4910cec9f7ad9d1f378 (diff)
parent5585b37bd8ba8f04fef131a80360d286bc00a5db (diff)
downloadtk-114422ec97ee32fa6c8690f42d065c3b3c0a86f0.zip
tk-114422ec97ee32fa6c8690f42d065c3b3c0a86f0.tar.gz
tk-114422ec97ee32fa6c8690f42d065c3b3c0a86f0.tar.bz2
merge 8.6
Diffstat (limited to 'generic')
-rw-r--r--generic/ttk/ttkNotebook.c81
1 files changed, 45 insertions, 36 deletions
diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c
index 81a8b64..06aa275 100644
--- a/generic/ttk/ttkNotebook.c
+++ b/generic/ttk/ttkNotebook.c
@@ -4,6 +4,7 @@
#include <string.h>
#include <ctype.h>
+#include <math.h>
#include <stdio.h>
#include <tk.h>
@@ -288,13 +289,14 @@ static void ActivateTab(Notebook *nb, int index)
* TabState --
* Return the state of the specified tab, based on
* notebook state, currentIndex, activeIndex, and user-specified tab state.
- * The USER1 bit is set for the leftmost tab, and USER2
- * is set for the rightmost tab.
+ * The USER1 bit is set for the leftmost visible tab, and USER2
+ * is set for the rightmost visible tab.
*/
static Ttk_State TabState(Notebook *nb, int index)
{
Ttk_State state = nb->core.state;
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
+ int i = 0;
if (index == nb->notebook.currentIndex) {
state |= TTK_STATE_SELECTED;
@@ -305,11 +307,25 @@ static Ttk_State TabState(Notebook *nb, int index)
if (index == nb->notebook.activeIndex) {
state |= TTK_STATE_ACTIVE;
}
- if (index == 0) {
- state |= TTK_STATE_USER1;
+ for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ if (tab->state == TAB_STATE_HIDDEN) {
+ continue;
+ }
+ if (index == i) {
+ state |= TTK_STATE_USER1;
+ }
+ break;
}
- if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) {
- state |= TTK_STATE_USER2;
+ for (i = Ttk_NumberSlaves(nb->notebook.mgr) - 1; i >= 0; --i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ if (tab->state == TAB_STATE_HIDDEN) {
+ continue;
+ }
+ if (index == i) {
+ state |= TTK_STATE_USER2;
+ }
+ break;
}
if (tab->state == TAB_STATE_DISABLED) {
state |= TTK_STATE_DISABLED;
@@ -325,6 +341,8 @@ static Ttk_State TabState(Notebook *nb, int index)
/* TabrowSize --
* Compute max height and total width of all tabs (horizontal layouts)
* or total height and max width (vertical layouts).
+ * The -mintabwidth style option is taken into account (for the width
+ * only).
*
* Side effects:
* Sets width and height fields for all tabs.
@@ -334,7 +352,7 @@ static Ttk_State TabState(Notebook *nb, int index)
* (max height/width) but not parallel (total width/height).
*/
static void TabrowSize(
- Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr)
+ Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr)
{
Ttk_Layout tabLayout = nb->notebook.tabLayout;
int tabrowWidth = 0, tabrowHeight = 0;
@@ -346,6 +364,7 @@ static void TabrowSize(
Ttk_RebindSublayout(tabLayout, tab);
Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
+ tab->width = MAX(tab->width, minTabWidth);
if (orient == TTK_ORIENT_HORIZONTAL) {
tabrowHeight = MAX(tabrowHeight, tab->height);
@@ -406,7 +425,7 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
/* Tab row:
*/
- TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight);
tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins);
tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins);
@@ -436,47 +455,32 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
/* SqueezeTabs --
* Squeeze or stretch tabs to fit within the tab area parcel.
+ * This happens independently of the -mintabwidth style option.
*
- * All tabs are adjusted by an equal amount, but will not be made
- * smaller than the minimum width. (If all the tabs still do
- * not fit in the available space, the rightmost ones will
- * be further squozen by PlaceTabs()).
- *
- * The algorithm does not always yield an optimal layout, but does
- * have the important property that decreasing the available width
- * by one pixel will cause at most one tab to shrink by one pixel;
- * this means that tabs resize "smoothly" when the window shrinks
- * and grows.
+ * All tabs are adjusted by an equal amount.
*
* @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations
* @@@ <<NOTE-SQUEEZE-HIDDEN>> does not account for hidden tabs.
*/
static void SqueezeTabs(
- Notebook *nb, int needed, int available, int minTabWidth)
+ Notebook *nb, int needed, int available)
{
int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
if (nTabs > 0) {
- int difference = available - needed,
- delta = difference / nTabs,
- remainder = difference % nTabs,
- slack = 0;
+ int difference = available - needed;
+ double fraction = (double)difference / needed;
+ double slack = 0;
+ double ad;
int i;
- if (remainder < 0) { remainder += nTabs; --delta; }
-
for (i = 0; i < nTabs; ++i) {
Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i);
- int adj = delta + (i < remainder) + slack;
-
- if (tab->width + adj >= minTabWidth) {
- tab->width += adj;
- slack = 0;
- } else {
- slack = adj - (minTabWidth - tab->width);
- tab->width = minTabWidth;
- }
+
+ ad = slack + tab->width * fraction;
+ tab->width += (int)ad;
+ slack = ad - floor(ad);
}
}
}
@@ -539,8 +543,13 @@ static void NotebookDoLayout(void *recordPtr)
Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin));
/* Place tabs:
+ * Note: TabrowSize() takes into account -mintabwidth, but the tabs will
+ * actually have this minimum size when displayed only if there is enough
+ * space to draw the tabs with this width. Otherwise some of the tabs can
+ * be squeezed to a size smaller than -mintabwidth because we prefer
+ * displaying all tabs than than honoring -mintabwidth for all of them.
*/
- TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight);
tabrowBox = Ttk_PadBox(
Ttk_PositionBox(&cavity,
tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins),
@@ -548,7 +557,7 @@ static void NotebookDoLayout(void *recordPtr)
nbstyle.tabPosition),
nbstyle.tabMargins);
- SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth);
+ SqueezeTabs(nb, tabrowWidth, tabrowBox.width);
PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement);
/* Layout for client area frame: