summaryrefslogtreecommitdiffstats
path: root/generic/ttk/ttkScrollbar.c
diff options
context:
space:
mode:
authorhobbs <hobbs>2006-10-31 01:42:25 (GMT)
committerhobbs <hobbs>2006-10-31 01:42:25 (GMT)
commit397a2c9832bf618f26be267501cf49ab06a562ec (patch)
tree61d5e957eccfcba57b0dd27ebc73db085385834e /generic/ttk/ttkScrollbar.c
parent18d330543869e240c2bd12fc9fbb8d5027f5cad6 (diff)
downloadtk-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.c316
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*/