Exemplo n.º 1
0
/* ConfigurePane --
 * 	Set pane options.
 */
static int ConfigurePane(
    Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window slaveWindow,
    int objc, Tcl_Obj *const objv[])
{
    Ttk_Manager *mgr = pw->paned.mgr;
    Tk_SavedOptions savedOptions;
    int mask = 0;

    if (Tk_SetOptions(interp, (void*)pane, pw->paned.paneOptionTable,
                      objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
    {
        return TCL_ERROR;
    }

    /* Sanity-check:
     */
    if (pane->weight < 0) {
        Tcl_AppendResult(interp, "-weight must be nonnegative", NULL);
        goto error;
    }

    /* Done.
     */
    Tk_FreeSavedOptions(&savedOptions);
    Ttk_ManagerSizeChanged(mgr);
    return TCL_OK;

error:
    Tk_RestoreSavedOptions(&savedOptions);
    return TCL_ERROR;
}
Exemplo n.º 2
0
static int
ConfigureSlave(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Window tkwin,		/* Token for the window to manipulate. */
    Tk_OptionTable table,	/* Token for option table. */
    int objc,			/* Number of config arguments. */
    Tcl_Obj *const objv[])	/* Object values for arguments. */
{
    register Master *masterPtr;
    Tk_SavedOptions savedOptions;
    int mask;
    Slave *slavePtr;
    Tk_Window masterWin = (Tk_Window) NULL;

    if (Tk_TopWinHierarchy(tkwin)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't use placer on top-level window \"%s\"; use "
		"wm command instead", Tk_PathName(tkwin)));
	Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	return TCL_ERROR;
    }

    slavePtr = CreateSlave(tkwin, table);

    if (Tk_SetOptions(interp, (char *) slavePtr, table, objc, objv,
	    slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }

    /*
     * Set slave flags. First clear the field, then add bits as needed.
     */

    slavePtr->flags = 0;
    if (slavePtr->heightPtr) {
	slavePtr->flags |= CHILD_HEIGHT;
    }

    if (slavePtr->relHeightPtr) {
	slavePtr->flags |= CHILD_REL_HEIGHT;
    }

    if (slavePtr->relWidthPtr) {
	slavePtr->flags |= CHILD_REL_WIDTH;
    }

    if (slavePtr->widthPtr) {
	slavePtr->flags |= CHILD_WIDTH;
    }

    if (!(mask & IN_MASK) && (slavePtr->masterPtr != NULL)) {
	/*
	 * If no -in option was passed and the slave is already placed then
	 * just recompute the placement.
	 */

	masterPtr = slavePtr->masterPtr;
	goto scheduleLayout;
    } else if (mask & IN_MASK) {
	/* -in changed */
	Tk_Window tkwin;
	Tk_Window ancestor;

	tkwin = slavePtr->inTkwin;

	/*
	 * Make sure that the new master is either the logical parent of the
	 * slave or a descendant of that window, and that the master and slave
	 * aren't the same.
	 */

	for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(slavePtr->tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't place %s relative to %s",
			Tk_PathName(slavePtr->tkwin), Tk_PathName(tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		goto error;
	    }
	}
	if (slavePtr->tkwin == tkwin) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't place %s relative to itself",
		    Tk_PathName(slavePtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
	    goto error;
	}
	if ((slavePtr->masterPtr != NULL)
		&& (slavePtr->masterPtr->tkwin == tkwin)) {
	    /*
	     * Re-using same old master. Nothing to do.
	     */

	    masterPtr = slavePtr->masterPtr;
	    goto scheduleLayout;
	}
	if ((slavePtr->masterPtr != NULL) &&
		(slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
	    Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
	}
	UnlinkSlave(slavePtr);
	masterWin = tkwin;
    }

    /*
     * If there's no master specified for this slave, use its Tk_Parent.
     */

    if (masterWin == NULL) {
	masterWin = Tk_Parent(slavePtr->tkwin);
	slavePtr->inTkwin = masterWin;
    }

    /*
     * Manage the slave window in this master.
     */

    masterPtr = CreateMaster(masterWin);
    slavePtr->masterPtr = masterPtr;
    slavePtr->nextPtr = masterPtr->slavePtr;
    masterPtr->slavePtr = slavePtr;
    Tk_ManageGeometry(slavePtr->tkwin, &placerType, slavePtr);

    /*
     * Arrange for the master to be re-arranged at the first idle moment.
     */

  scheduleLayout:
    Tk_FreeSavedOptions(&savedOptions);

    if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
	masterPtr->flags |= PARENT_RECONFIG_PENDING;
	Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
    }
    return TCL_OK;

    /*
     * Error while processing some option, cleanup and return.
     */

  error:
    Tk_RestoreSavedOptions(&savedOptions);
    return TCL_ERROR;
}
Exemplo n.º 3
0
static int
ConfigureScale(
    Tcl_Interp *interp,		/* Used for error reporting. */
    register TkScale *scalePtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *errorResult = NULL;
    int error;
    double varValue;

    /*
     * Eliminate any existing trace on a variable monitored by the scale.
     */

    if (scalePtr->varNamePtr != NULL) {
        Tcl_UntraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
                       TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                       ScaleVarProc, scalePtr);
    }

    for (error = 0; error <= 1; error++) {
        if (!error) {
            /*
             * First pass: set options to new values.
             */

            if (Tk_SetOptions(interp, (char *) scalePtr,
                              scalePtr->optionTable, objc, objv, scalePtr->tkwin,
                              &savedOptions, NULL) != TCL_OK) {
                continue;
            }
        } else {
            /*
             * Second pass: restore options to old values.
             */

            errorResult = Tcl_GetObjResult(interp);
            Tcl_IncrRefCount(errorResult);
            Tk_RestoreSavedOptions(&savedOptions);
        }

        /*
         * If the scale is tied to the value of a variable, then set the
         * scale's value from the value of the variable, if it exists and it
         * holds a valid double value.
         */

        if (scalePtr->varNamePtr != NULL) {
            double value;
            Tcl_Obj *valuePtr;

            valuePtr = Tcl_ObjGetVar2(interp, scalePtr->varNamePtr, NULL,
                                      TCL_GLOBAL_ONLY);
            if ((valuePtr != NULL) &&
                    (Tcl_GetDoubleFromObj(NULL, valuePtr, &value) == TCL_OK)) {
                scalePtr->value = TkRoundToResolution(scalePtr, value);
            }
        }

        /*
         * Several options need special processing, such as parsing the
         * orientation and creating GCs.
         */

        scalePtr->fromValue = TkRoundToResolution(scalePtr,
                              scalePtr->fromValue);
        scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue);
        scalePtr->tickInterval = TkRoundToResolution(scalePtr,
                                 scalePtr->tickInterval);

        /*
         * Make sure that the tick interval has the right sign so that
         * addition moves from fromValue to toValue.
         */

        if ((scalePtr->tickInterval < 0)
                ^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) {
            scalePtr->tickInterval = -scalePtr->tickInterval;
        }

        ComputeFormat(scalePtr);

        scalePtr->labelLength = scalePtr->label ? (int)strlen(scalePtr->label) : 0;

        Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder);

        if (scalePtr->highlightWidth < 0) {
            scalePtr->highlightWidth = 0;
        }
        scalePtr->inset = scalePtr->highlightWidth + scalePtr->borderWidth;
        break;
    }
    if (!error) {
        Tk_FreeSavedOptions(&savedOptions);
    }

    /*
     * Set the scale value to itself; all this does is to make sure that the
     * scale's value is within the new acceptable range for the scale. We
     * don't set the var here because we need to make special checks for
     * possibly changed varNamePtr.
     */

    TkScaleSetValue(scalePtr, scalePtr->value, 0, 1);

    /*
     * Reestablish the variable trace, if it is needed.
     */

    if (scalePtr->varNamePtr != NULL) {
        Tcl_Obj *valuePtr;

        /*
         * Set the associated variable only when the new value differs from
         * the current value, or the variable doesn't yet exist.
         */

        valuePtr = Tcl_ObjGetVar2(interp, scalePtr->varNamePtr, NULL,
                                  TCL_GLOBAL_ONLY);
        if ((valuePtr == NULL) || (Tcl_GetDoubleFromObj(NULL,
                                   valuePtr, &varValue) != TCL_OK)) {
            ScaleSetVariable(scalePtr);
        } else {
            char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE];

            sprintf(varString, scalePtr->format, varValue);
            sprintf(scaleString, scalePtr->format, scalePtr->value);
            if (strcmp(varString, scaleString)) {
                ScaleSetVariable(scalePtr);
            }
        }
        Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
                     TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                     ScaleVarProc, scalePtr);
    }

    ScaleWorldChanged(scalePtr);
    if (error) {
        Tcl_SetObjResult(interp, errorResult);
        Tcl_DecrRefCount(errorResult);
        return TCL_ERROR;
    }
    return TCL_OK;
}
Exemplo n.º 4
0
static int
ConfigureMenuButton(
    Tcl_Interp *interp,		/* Used for error reporting. */
    register TkMenuButton *mbPtr,
    /* Information about widget; may or may not
     * already have values for some fields. */
    int objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    Tk_SavedOptions savedOptions;
    Tcl_Obj *errorResult = NULL;
    int error;
    Tk_Image image;

    /*
     * Eliminate any existing trace on variables monitored by the menubutton.
     */

    if (mbPtr->textVarName != NULL) {
        Tcl_UntraceVar(interp, mbPtr->textVarName,
                       TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                       MenuButtonTextVarProc, mbPtr);
    }

    /*
     * The following loop is potentially executed twice. During the first pass
     * configuration options get set to their new values. If there is an error
     * in this pass, we execute a second pass to restore all the options to
     * their previous values.
     */

    for (error = 0; error <= 1; error++) {
        if (!error) {
            /*
             * First pass: set options to new values.
             */

            if (Tk_SetOptions(interp, (char *) mbPtr,
                              mbPtr->optionTable, objc, objv,
                              mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
                continue;
            }
        } else {
            /*
             * Second pass: restore options to old values.
             */

            errorResult = Tcl_GetObjResult(interp);
            Tcl_IncrRefCount(errorResult);
            Tk_RestoreSavedOptions(&savedOptions);
        }

        /*
         * A few options need special processing, such as setting the
         * background from a 3-D border, or filling in complicated defaults
         * that couldn't be specified to Tk_SetOptions.
         */

        if ((mbPtr->state == STATE_ACTIVE)
                && !Tk_StrictMotif(mbPtr->tkwin)) {
            Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->activeBorder);
        } else {
            Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->normalBorder);
        }

        if (mbPtr->highlightWidth < 0) {
            mbPtr->highlightWidth = 0;
        }

        if (mbPtr->padX < 0) {
            mbPtr->padX = 0;
        }
        if (mbPtr->padY < 0) {
            mbPtr->padY = 0;
        }

        /*
         * Get the image for the widget, if there is one. Allocate the new
         * image before freeing the old one, so that the reference count
         * doesn't go to zero and cause image data to be discarded.
         */

        if (mbPtr->imageString != NULL) {
            image = Tk_GetImage(mbPtr->interp, mbPtr->tkwin,
                                mbPtr->imageString, MenuButtonImageProc, mbPtr);
            if (image == NULL) {
                return TCL_ERROR;
            }
        } else {
            image = NULL;
        }
        if (mbPtr->image != NULL) {
            Tk_FreeImage(mbPtr->image);
        }
        mbPtr->image = image;

        /*
         * Recompute the geometry for the button.
         */

        if ((mbPtr->bitmap != None) || (mbPtr->image != NULL)) {
            if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->widthString,
                             &mbPtr->width) != TCL_OK) {
widthError:
                Tcl_AddErrorInfo(interp, "\n    (processing -width option)");
                continue;
            }
            if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->heightString,
                             &mbPtr->height) != TCL_OK) {
heightError:
                Tcl_AddErrorInfo(interp, "\n    (processing -height option)");
                continue;
            }
        } else {
            if (Tcl_GetInt(interp, mbPtr->widthString, &mbPtr->width)
                    != TCL_OK) {
                goto widthError;
            }
            if (Tcl_GetInt(interp, mbPtr->heightString, &mbPtr->height)
                    != TCL_OK) {
                goto heightError;
            }
        }
        break;
    }

    if (!error) {
        Tk_FreeSavedOptions(&savedOptions);
    }

    if (mbPtr->textVarName != NULL) {
        /*
         * If no image or -compound is used, display the value of a variable.
         * Set up a trace to watch for any changes in it, create the variable
         * if it doesn't exist, and fetch its current value.
         */
        const char *value;

        value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY);
        if (value == NULL) {
            Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text,
                       TCL_GLOBAL_ONLY);
        } else {
            if (mbPtr->text != NULL) {
                ckfree(mbPtr->text);
            }
            mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1));
            strcpy(mbPtr->text, value);
        }
        Tcl_TraceVar(interp, mbPtr->textVarName,
                     TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                     MenuButtonTextVarProc, mbPtr);
    }

    TkMenuButtonWorldChanged(mbPtr);
    if (error) {
        Tcl_SetObjResult(interp, errorResult);
        Tcl_DecrRefCount(errorResult);
        return TCL_ERROR;
    }
    return TCL_OK;
}