diff options
author | hobbs <hobbs> | 2006-10-31 01:42:25 (GMT) |
---|---|---|
committer | hobbs <hobbs> | 2006-10-31 01:42:25 (GMT) |
commit | 397a2c9832bf618f26be267501cf49ab06a562ec (patch) | |
tree | 61d5e957eccfcba57b0dd27ebc73db085385834e /generic/ttk/ttkScrollbar.c | |
parent | 18d330543869e240c2bd12fc9fbb8d5027f5cad6 (diff) | |
download | tk-397a2c9832bf618f26be267501cf49ab06a562ec.zip tk-397a2c9832bf618f26be267501cf49ab06a562ec.tar.gz tk-397a2c9832bf618f26be267501cf49ab06a562ec.tar.bz2 |
* doc/ttk_Geometry.3, doc/ttk_Theme.3, doc/ttk_button.n:
* doc/ttk_checkbutton.n, doc/ttk_combobox.n, doc/ttk_dialog.n:
* doc/ttk_entry.n, doc/ttk_frame.n, doc/ttk_image.n:
* doc/ttk_intro.n, doc/ttk_label.n, doc/ttk_labelframe.n:
* doc/ttk_menubutton.n, doc/ttk_notebook.n, doc/ttk_panedwindow.n:
* doc/ttk_progressbar.n, doc/ttk_radiobutton.n, doc/ttk_scrollbar.n:
* doc/ttk_separator.n, doc/ttk_sizegrip.n, doc/ttk_style.n:
* doc/ttk_treeview.n, doc/ttk_widget.n,:
* generic/ttk/ttk.decls, generic/ttk/ttkBlink.c:
* generic/ttk/ttkButton.c, generic/ttk/ttkCache.c:
* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.c:
* generic/ttk/ttkManager.h, generic/ttk/ttkNotebook.c:
* generic/ttk/ttkPanedwindow.c, generic/ttk/ttkProgress.c:
* generic/ttk/ttkScale.c, generic/ttk/ttkScroll.c:
* generic/ttk/ttkScrollbar.c, generic/ttk/ttkSeparator.c:
* generic/ttk/ttkSquare.c, generic/ttk/ttkState.c:
* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
* generic/ttk/ttkTagSet.c, generic/ttk/ttkTheme.c:
* generic/ttk/ttkTheme.h, generic/ttk/ttkThemeInt.h:
* generic/ttk/ttkTrace.c, generic/ttk/ttkTrack.c:
* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
* generic/ttk/ttkWidget.h:
* library/demos/ttk_demo.tcl, library/demos/ttk_iconlib.tcl:
* library/demos/ttk_repeater.tcl:
* library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl:
* library/ttk/button.tcl, library/ttk/clamTheme.tcl:
* library/ttk/classicTheme.tcl, library/ttk/combobox.tcl:
* library/ttk/cursors.tcl, library/ttk/defaults.tcl:
* library/ttk/dialog.tcl, library/ttk/entry.tcl:
* library/ttk/fonts.tcl, library/ttk/icons.tcl:
* library/ttk/keynav.tcl, library/ttk/menubutton.tcl:
* library/ttk/notebook.tcl, library/ttk/panedwindow.tcl:
* library/ttk/progress.tcl, library/ttk/scale.tcl:
* library/ttk/scrollbar.tcl, library/ttk/sizegrip.tcl:
* library/ttk/treeview.tcl, library/ttk/ttk.tcl:
* library/ttk/utils.tcl, library/ttk/winTheme.tcl:
* library/ttk/xpTheme.tcl:
* macosx/ttkMacOSXTheme.c:
* tests/ttk/all.tcl, tests/ttk/bwidget.test, tests/ttk/combobox.test:
* tests/ttk/entry.test, tests/ttk/image.test:
* tests/ttk/labelframe.test, tests/ttk/layout.test:
* tests/ttk/misc.test, tests/ttk/notebook.test:
* tests/ttk/panedwindow.test, tests/ttk/progressbar.test:
* tests/ttk/scrollbar.test, tests/ttk/treetags.test:
* tests/ttk/treeview.test, tests/ttk/ttk.test, tests/ttk/validate.test:
* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c:
First import of Ttk themed Tk widgets as branched from tile 0.7.8
* generic/tkInt.h, generic/tkWindow.c: add Ttk_Init call, copy
tk classic widgets to ::tk namespace.
* library/tk.tcl: add source of ttk/ttk.tcl, define $::ttk::library.
* unix/Makefile.in, win/Makefile.in: add Ttk build bits
* win/configure, win/configure.in: check for uxtheme.h (XP theme).
Diffstat (limited to 'generic/ttk/ttkScrollbar.c')
-rw-r--r-- | generic/ttk/ttkScrollbar.c | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/generic/ttk/ttkScrollbar.c b/generic/ttk/ttkScrollbar.c new file mode 100644 index 0000000..1431c46 --- /dev/null +++ b/generic/ttk/ttkScrollbar.c @@ -0,0 +1,316 @@ +/* $Id: ttkScrollbar.c,v 1.1 2006/10/31 01:42:26 hobbs Exp $ + * Copyright (c) 2003, Joe English + * Ttk widget set: scrollbar widget implementation. + */ + +#include <string.h> +#include <tk.h> + +#include "ttkTheme.h" +#include "ttkWidget.h" + +/*------------------------------------------------------------------------ + * +++ Scrollbar widget record. + */ +typedef struct +{ + Tcl_Obj *commandObj; + + int orient; + Tcl_Obj *orientObj; + + double first; /* top fraction */ + double last; /* bottom fraction */ + + Ttk_Box troughBox; /* trough parcel */ + int minSize; /* minimum size of thumb */ +} ScrollbarPart; + +typedef struct +{ + WidgetCore core; + ScrollbarPart scrollbar; +} Scrollbar; + +static Tk_OptionSpec ScrollbarOptionSpecs[] = +{ + {TK_OPTION_STRING, "-command", "command", "Command", "", + Tk_Offset(Scrollbar,scrollbar.commandObj), -1, 0,0,0}, + + {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical", + Tk_Offset(Scrollbar,scrollbar.orientObj), + Tk_Offset(Scrollbar,scrollbar.orient), + 0,(ClientData)TTKOrientStrings,STYLE_CHANGED }, + + WIDGET_INHERIT_OPTIONS(CoreOptionSpecs) +}; + +/*------------------------------------------------------------------------ + * +++ Widget hooks. + */ + +static int +ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr) +{ + Scrollbar *sb = recordPtr; + sb->scrollbar.first = 0.0; + sb->scrollbar.last = 1.0; + + TrackElementState(&sb->core); + + return TCL_OK; +} + +static Ttk_Layout ScrollbarGetLayout( + Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr) +{ + Scrollbar *sb = recordPtr; + return WidgetGetOrientedLayout( + interp, theme, recordPtr, sb->scrollbar.orientObj); +} + +/* + * ScrollbarDoLayout -- + * Layout hook. Adjusts the position of the scrollbar thumb. + * + * Side effects: + * Sets sb->troughBox and sb->minSize. + */ +static void ScrollbarDoLayout(void *recordPtr) +{ + Scrollbar *sb = recordPtr; + WidgetCore *corePtr = &sb->core; + Ttk_LayoutNode *thumb; + Ttk_Box thumbBox; + int thumbWidth, thumbHeight; + double first, last, size; + int minSize; + + /* + * Use generic layout manager to compute initial layout: + */ + Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin)); + + /* + * Locate thumb element, extract parcel and requested minimum size: + */ + thumb = Ttk_LayoutFindNode(corePtr->layout, "thumb"); + if (!thumb) /* Something has gone wrong -- bail */ + return; + + sb->scrollbar.troughBox = thumbBox = Ttk_LayoutNodeParcel(thumb); + Ttk_LayoutNodeReqSize( + corePtr->layout, thumb, &thumbWidth,&thumbHeight); + + /* + * Adjust thumb element parcel: + */ + first = sb->scrollbar.first; + last = sb->scrollbar.last; + + if (sb->scrollbar.orient == TTK_ORIENT_VERTICAL) { + minSize = thumbHeight; + size = thumbBox.height - minSize; + thumbBox.y += (int)(size * first); + thumbBox.height = (int)(size * last) + minSize - (int)(size * first); + } else { + minSize = thumbWidth; + size = thumbBox.width - minSize; + thumbBox.x += (int)(size * first); + thumbBox.width = (int)(size * last) + minSize - (int)(size * first); + } + sb->scrollbar.minSize = minSize; + Ttk_PlaceLayoutNode(corePtr->layout, thumb, thumbBox); +} + +/*------------------------------------------------------------------------ + * +++ Widget commands. + */ + +/* $sb set $first $last -- + * Set the position of the scrollbar. + */ +static int +ScrollbarSetCommand( + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) +{ + Scrollbar *scrollbar = recordPtr; + Tcl_Obj *firstObj, *lastObj; + double first, last; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "first last"); + return TCL_ERROR; + } + + firstObj = objv[2]; + lastObj = objv[3]; + if (Tcl_GetDoubleFromObj(interp, firstObj, &first) != TCL_OK + || Tcl_GetDoubleFromObj(interp, lastObj, &last) != TCL_OK) + return TCL_ERROR; + + /* Range-checks: + */ + if (first < 0.0) { + first = 0.0; + } else if (first > 1.0) { + first = 1.0; + } + + if (last < first) { + last = first; + } else if (last > 1.0) { + last = 1.0; + } + + /* ASSERT: 0.0 <= first <= last <= 1.0 */ + + scrollbar->scrollbar.first = first; + scrollbar->scrollbar.last = last; + if (first <= 0.0 && last >= 1.0) { + scrollbar->core.state |= TTK_STATE_DISABLED; + } else { + scrollbar->core.state &= ~TTK_STATE_DISABLED; + } + + TtkRedisplayWidget(&scrollbar->core); + + return TCL_OK; +} + +/* $sb get -- + * Returns the last thing passed to 'set'. + */ +static int +ScrollbarGetCommand( + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) +{ + Scrollbar *scrollbar = recordPtr; + Tcl_Obj *result[2]; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, ""); + return TCL_ERROR; + } + + result[0] = Tcl_NewDoubleObj(scrollbar->scrollbar.first); + result[1] = Tcl_NewDoubleObj(scrollbar->scrollbar.last); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, result)); + + return TCL_OK; +} + +/* $sb delta $dx $dy -- + * Returns the percentage change corresponding to a mouse movement + * of $dx, $dy. + */ +static int +ScrollbarDeltaCommand( + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) +{ + Scrollbar *sb = recordPtr; + double dx, dy; + double delta = 0.0; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "dx dy"); + return TCL_ERROR; + } + + if (Tcl_GetDoubleFromObj(interp, objv[2], &dx) != TCL_OK + || Tcl_GetDoubleFromObj(interp, objv[3], &dy) != TCL_OK) + { + return TCL_ERROR; + } + + delta = 0.0; + if (sb->scrollbar.orient == TTK_ORIENT_VERTICAL) { + int size = sb->scrollbar.troughBox.height - sb->scrollbar.minSize; + if (size > 0) { + delta = (double)dy / (double)size; + } + } else { + int size = sb->scrollbar.troughBox.width - sb->scrollbar.minSize; + if (size > 0) { + delta = (double)dx / (double)size; + } + } + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(delta)); + return TCL_OK; +} + +/* $sb fraction $x $y -- + * Returns a real number between 0 and 1 indicating where the + * point given by x and y lies in the trough area of the scrollbar. + */ +static int +ScrollbarFractionCommand( + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) +{ + Scrollbar *sb = recordPtr; + Ttk_Box b = sb->scrollbar.troughBox; + int minSize = sb->scrollbar.minSize; + double x, y; + double fraction = 0.0; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "x y"); + return TCL_ERROR; + } + + if (Tcl_GetDoubleFromObj(interp, objv[2], &x) != TCL_OK + || Tcl_GetDoubleFromObj(interp, objv[3], &y) != TCL_OK) + { + return TCL_ERROR; + } + + fraction = 0.0; + if (sb->scrollbar.orient == TTK_ORIENT_VERTICAL) { + if (b.height > minSize) { + fraction = (double)(y - b.y) / (double)(b.height - minSize); + } + } else { + if (b.width > minSize) { + fraction = (double)(x - b.x) / (double)(b.width - minSize); + } + } + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction)); + return TCL_OK; +} + +static WidgetCommandSpec ScrollbarCommands[] = +{ + { "configure", WidgetConfigureCommand }, + { "cget", WidgetCgetCommand }, + { "delta", ScrollbarDeltaCommand }, + { "fraction", ScrollbarFractionCommand }, + { "get", ScrollbarGetCommand }, + { "identify", WidgetIdentifyCommand }, + { "instate", WidgetInstateCommand }, + { "set", ScrollbarSetCommand }, + { "state", WidgetStateCommand }, + { 0,0 } +}; + +/*------------------------------------------------------------------------ + * +++ Widget specification. + */ +WidgetSpec ScrollbarWidgetSpec = +{ + "TScrollbar", /* className */ + sizeof(Scrollbar), /* recordSize */ + ScrollbarOptionSpecs, /* optionSpecs */ + ScrollbarCommands, /* subcommands */ + ScrollbarInitialize, /* initializeProc */ + NullCleanup, /* cleanupProc */ + CoreConfigure, /* configureProc */ + NullPostConfigure, /* postConfigureProc */ + ScrollbarGetLayout, /* getLayoutProc */ + WidgetSize, /* sizeProc */ + ScrollbarDoLayout, /* layoutProc */ + WidgetDisplay /* displayProc */ +}; + +/*EOF*/ |