OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / tk8.6.12 / generic / ttk / ttkScrollbar.c
diff --git a/util/src/TclTk/tk8.6.12/generic/ttk/ttkScrollbar.c b/util/src/TclTk/tk8.6.12/generic/ttk/ttkScrollbar.c
new file mode 100644 (file)
index 0000000..5ffd671
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2003, Joe English
+ *
+ * ttk::scrollbar widget.
+ */
+
+#include "tkInt.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, (void *)ttkOrientStrings, STYLE_CHANGED },
+
+    WIDGET_TAKEFOCUS_FALSE,
+    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget hooks.
+ */
+
+static void
+ScrollbarInitialize(Tcl_Interp *dummy, void *recordPtr)
+{
+    Scrollbar *sb = (Scrollbar *)recordPtr;
+    (void)dummy;
+
+    sb->scrollbar.first = 0.0;
+    sb->scrollbar.last = 1.0;
+
+    TtkTrackElementState(&sb->core);
+}
+
+static Ttk_Layout ScrollbarGetLayout(
+    Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
+{
+    Scrollbar *sb = (Scrollbar *)recordPtr;
+    return TtkWidgetGetOrientedLayout(
+       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 = (Scrollbar *)recordPtr;
+    WidgetCore *corePtr = &sb->core;
+    Ttk_Element 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_FindElement(corePtr->layout, "thumb");
+    if (!thumb)        /* Something has gone wrong -- bail */
+       return;
+
+    sb->scrollbar.troughBox = thumbBox = Ttk_ElementParcel(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_PlaceElement(corePtr->layout, thumb, thumbBox);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands.
+ */
+
+/* $sb set $first $last --
+ *     Set the position of the scrollbar.
+ */
+static int
+ScrollbarSetCommand(
+    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+    Scrollbar *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(
+    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+    Scrollbar *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(
+    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+    Scrollbar *sb = (Scrollbar *)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(
+    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+    Scrollbar *sb = (Scrollbar *)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 const Ttk_Ensemble ScrollbarCommands[] = {
+    { "configure",     TtkWidgetConfigureCommand,0 },
+    { "cget",          TtkWidgetCgetCommand,0 },
+    { "delta",         ScrollbarDeltaCommand,0 },
+    { "fraction",      ScrollbarFractionCommand,0 },
+    { "get",           ScrollbarGetCommand,0 },
+    { "identify",      TtkWidgetIdentifyCommand,0 },
+    { "instate",       TtkWidgetInstateCommand,0 },
+    { "set",           ScrollbarSetCommand,0 },
+    { "state",         TtkWidgetStateCommand,0 },
+    { 0,0,0 }
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget specification.
+ */
+static WidgetSpec ScrollbarWidgetSpec =
+{
+    "TScrollbar",              /* className */
+    sizeof(Scrollbar),         /* recordSize */
+    ScrollbarOptionSpecs,      /* optionSpecs */
+    ScrollbarCommands,         /* subcommands */
+    ScrollbarInitialize,       /* initializeProc */
+    TtkNullCleanup,            /* cleanupProc */
+    TtkCoreConfigure,          /* configureProc */
+    TtkNullPostConfigure,      /* postConfigureProc */
+    ScrollbarGetLayout,                /* getLayoutProc */
+    TtkWidgetSize,             /* sizeProc */
+    ScrollbarDoLayout,         /* layoutProc */
+    TtkWidgetDisplay           /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(VerticalScrollbarLayout)
+    TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y,
+       TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_TOP)
+       TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM)
+       TTK_NODE("Vertical.Scrollbar.thumb", TTK_FILL_BOTH))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(HorizontalScrollbarLayout)
+    TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X,
+       TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_LEFT)
+       TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT)
+       TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Initialization.
+ */
+
+MODULE_SCOPE
+void TtkScrollbar_Init(Tcl_Interp *interp)
+{
+    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+    Ttk_RegisterLayout(theme,"Vertical.TScrollbar",VerticalScrollbarLayout);
+    Ttk_RegisterLayout(theme,"Horizontal.TScrollbar",HorizontalScrollbarLayout);
+
+    RegisterWidget(interp, "ttk::scrollbar", &ScrollbarWidgetSpec);
+}
+
+/*EOF*/