summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <dkf@noemail.net>2008-12-06 10:48:27 (GMT)
committerdkf <dkf@noemail.net>2008-12-06 10:48:27 (GMT)
commit4f0eac38b8a8dc3e5f08a29f06783c9386590f6d (patch)
tree7e161ef2a78eb2fc23ac4e1618b11c8ce8f7d26b /generic
parent821b68e9a8b9be6dd5bfdbe110c911c174d61b4f (diff)
downloadtk-4f0eac38b8a8dc3e5f08a29f06783c9386590f6d.zip
tk-4f0eac38b8a8dc3e5f08a29f06783c9386590f6d.tar.gz
tk-4f0eac38b8a8dc3e5f08a29f06783c9386590f6d.tar.bz2
Implementation of TIP #197.
FossilOrigin-Name: f5b1e7040ddddd4220f0b534e088e6fc876f3652
Diffstat (limited to 'generic')
-rw-r--r--generic/tkText.c30
-rw-r--r--generic/tkText.h18
-rw-r--r--generic/tkTextMark.c67
3 files changed, 89 insertions, 26 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index c2cc914..c04dae0 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.c,v 1.85 2008/11/27 23:47:09 ferrieux Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.86 2008/12/06 10:48:29 dkf Exp $
*/
#include "default.h"
@@ -75,6 +75,16 @@ static const char *const tabStyleStrings[] = {
};
/*
+ * The 'TkTextInsertUnfocussed' enum in tkText.h is used to define a type for
+ * the -insertunfocussed option of the Text widget. These values are used as
+ * indice into the string table below.
+ */
+
+static const char *const insertUnfocussedStrings[] = {
+ "hollow", "none", "solid", NULL
+};
+
+/*
* The following functions and custom option type are used to define the
* "line" option type, and thereby handle the text widget '-startline',
* '-endline' configuration options which are of that type.
@@ -177,6 +187,10 @@ static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(TkText, insertOnTime),
0, 0, 0},
+ {TK_OPTION_STRING_TABLE,
+ "-insertunfocussed", "insertUnfocussed", "InsertUnfocussed",
+ DEF_TEXT_INSERT_UNFOCUSSED, -1, Tk_Offset(TkText, insertUnfocussed),
+ 0, (ClientData) insertUnfocussedStrings, 0},
{TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth),
0, 0, 0},
@@ -2207,7 +2221,7 @@ ConfigureText(
if (textPtr->flags & GOT_FOCUS) {
Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
- textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
+ textPtr->insertBlinkHandler = NULL;
TextBlinkProc(textPtr);
}
@@ -2402,7 +2416,7 @@ TextEventProc(
}
} else {
textPtr->flags &= ~(GOT_FOCUS | INSERT_ON);
- textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
+ textPtr->insertBlinkHandler = NULL;
}
if (textPtr->inactiveSelBorder != textPtr->selBorder) {
TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr,
@@ -3427,6 +3441,16 @@ TextBlinkProc(
if ((textPtr->state == TK_TEXT_STATE_DISABLED) ||
!(textPtr->flags & GOT_FOCUS) || (textPtr->insertOffTime == 0)) {
+ if (!(textPtr->flags & GOT_FOCUS) &&
+ (textPtr->insertUnfocussed != TK_TEXT_INSERT_NOFOCUS_NONE)) {
+ /*
+ * The widget doesn't have the focus yet it is configured to
+ * display the cursor when it doesn't have the focus. Act now!
+ */
+
+ textPtr->flags |= INSERT_ON;
+ goto redrawInsert;
+ }
if ((textPtr->insertOffTime == 0) && !(textPtr->flags & INSERT_ON)) {
/*
* The widget was configured to have zero offtime while the
diff --git a/generic/tkText.h b/generic/tkText.h
index eb650ea..0a97630 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.h,v 1.35 2008/12/04 21:33:25 nijtmans Exp $
+ * RCS: @(#) $Id: tkText.h,v 1.36 2008/12/06 10:48:29 dkf Exp $
*/
#ifndef _TKTEXT
@@ -579,6 +579,17 @@ typedef struct TkSharedText {
} TkSharedText;
/*
+ * The following enum is used to define a type for the -insertunfocussed
+ * option of the Text widget.
+ */
+
+typedef enum {
+ TK_TEXT_INSERT_NOFOCUS_HOLLOW,
+ TK_TEXT_INSERT_NOFOCUS_NONE,
+ TK_TEXT_INSERT_NOFOCUS_SOLID
+} TkTextInsertUnfocussed;
+
+/*
* A data structure of the following type is kept for each text widget that
* currently exists for this process:
*/
@@ -710,7 +721,10 @@ typedef struct TkText {
Tk_3DBorder insertBorder; /* Used to draw vertical bar for insertion
* cursor. */
int insertWidth; /* Total width of insert cursor. */
- int insertBorderWidth; /* Width of 3-D border around insert cursor. */
+ int insertBorderWidth; /* Width of 3-D border around insert cursor */
+ TkTextInsertUnfocussed insertUnfocussed;
+ /* How to display the insert cursor when the
+ * text widget does not have the focus. */
int insertOnTime; /* Number of milliseconds cursor should spend
* in "on" state for each blink. */
int insertOffTime; /* Number of milliseconds cursor should spend
diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c
index d162c6f..4e483d8 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -10,11 +10,12 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextMark.c,v 1.22 2008/10/17 23:18:37 nijtmans Exp $
+ * RCS: @(#) $Id: tkTextMark.c,v 1.23 2008/12/06 10:48:29 dkf Exp $
*/
#include "tkInt.h"
#include "tkText.h"
+#include "tk3d.h"
/*
* Macro that determines the size of a mark segment:
@@ -145,7 +146,7 @@ TkTextMarkCmd(
Tcl_GetString(objv[3]), "\"", NULL);
return TCL_ERROR;
}
- markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ markPtr = Tcl_GetHashValue(hPtr);
}
if (objc == 4) {
if (markPtr->typePtr == &tkTextRightMarkType) {
@@ -157,10 +158,10 @@ TkTextMarkCmd(
}
str = Tcl_GetStringFromObj(objv[4],&length);
c = str[0];
- if ((c == 'l') && (strncmp(str, "left", (unsigned)length) == 0)) {
+ if ((c == 'l') && (strncmp(str, "left", (unsigned) length) == 0)) {
newTypePtr = &tkTextLeftMarkType;
} else if ((c == 'r') &&
- (strncmp(str, "right", (unsigned)length) == 0)) {
+ (strncmp(str, "right", (unsigned) length) == 0)) {
newTypePtr = &tkTextRightMarkType;
} else {
Tcl_AppendResult(interp, "bad mark gravity \"", str,
@@ -215,7 +216,7 @@ TkTextMarkCmd(
hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable,
Tcl_GetString(objv[i]));
if (hPtr != NULL) {
- markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ markPtr = Tcl_GetHashValue(hPtr);
/*
* Special case not needed with peer widgets.
@@ -276,7 +277,7 @@ TkTextSetMark(
widgetSpecific = 0;
hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->markTable, name,
&isNew);
- markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ markPtr = Tcl_GetHashValue(hPtr);
}
if (!isNew) {
/*
@@ -289,7 +290,7 @@ TkTextSetMark(
TkTextIndex index, index2;
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
- TkTextIndexForwChars(NULL,&index, 1, &index2, COUNT_INDICES);
+ TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
/*
* While we wish to redisplay, no heights have changed, so no need
@@ -298,8 +299,8 @@ TkTextSetMark(
TkTextChanged(NULL, textPtr, &index, &index2);
if (TkBTreeLinesTo(textPtr, indexPtr->linePtr) ==
- TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr)) {
- TkTextIndexBackChars(NULL,indexPtr, 1, &insertIndex,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr)) {
+ TkTextIndexBackChars(NULL, indexPtr, 1, &insertIndex,
COUNT_INDICES);
indexPtr = &insertIndex;
}
@@ -330,7 +331,7 @@ TkTextSetMark(
if (markPtr == textPtr->insertMarkPtr) {
TkTextIndex index2;
- TkTextIndexForwChars(NULL,indexPtr, 1, &index2, COUNT_INDICES);
+ TkTextIndexForwChars(NULL, indexPtr, 1, &index2, COUNT_INDICES);
/*
* While we wish to redisplay, no heights have changed, so no need to
@@ -414,12 +415,13 @@ TkTextMarkNameToIndex(
} else if (!strcmp(name, "current")) {
segPtr = textPtr->currentMarkPtr;
} else {
- Tcl_HashEntry *hPtr;
- hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);
+ Tcl_HashEntry *hPtr =
+ Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);
+
if (hPtr == NULL) {
return TCL_ERROR;
}
- segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ segPtr = Tcl_GetHashValue(hPtr);
}
TkTextMarkSegToIndex(textPtr, segPtr, indexPtr);
return TCL_OK;
@@ -586,7 +588,7 @@ TkTextInsertDisplayProc(
int rightSideWidth;
int ix = 0, iy = 0, iw = 0, ih = 0, charWidth = 0;
- if(textPtr->insertCursorType) {
+ if (textPtr->insertCursorType) {
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth);
rightSideWidth = charWidth + halfWidth;
@@ -614,14 +616,37 @@ TkTextInsertDisplayProc(
* the cursor.
*/
- if (textPtr->flags & INSERT_ON) {
+ if (textPtr->flags & GOT_FOCUS) {
+ if (textPtr->flags & INSERT_ON) {
+ Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
+ x - halfWidth, y, charWidth + textPtr->insertWidth,
+ height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
+ } else if (textPtr->selBorder == textPtr->insertBorder) {
+ Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border,
+ x - halfWidth, y, charWidth + textPtr->insertWidth,
+ height, 0, TK_RELIEF_FLAT);
+ }
+ } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_HOLLOW) {
+ if (textPtr->insertBorderWidth < 1) {
+ /*
+ * Hack to work around the fact that a "solid" border always
+ * paints in black.
+ */
+
+ TkBorder *borderPtr = (TkBorder *) textPtr->insertBorder;
+
+ XDrawRectangle(Tk_Display(textPtr->tkwin), dst, borderPtr->bgGC,
+ x - halfWidth, y, charWidth + textPtr->insertWidth - 1,
+ height - 1);
+ } else {
+ Tk_Draw3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
+ x - halfWidth, y, charWidth + textPtr->insertWidth,
+ height, textPtr->insertBorderWidth, TK_RELIEF_RAISED);
+ }
+ } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_SOLID) {
Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
x - halfWidth, y, charWidth + textPtr->insertWidth, height,
textPtr->insertBorderWidth, TK_RELIEF_RAISED);
- } else if (textPtr->selBorder == textPtr->insertBorder) {
- Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border,
- x - halfWidth, y, charWidth + textPtr->insertWidth, height,
- 0, TK_RELIEF_FLAT);
}
}
@@ -750,7 +775,7 @@ MarkFindNext(
* position.
*/
- segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ segPtr = Tcl_GetHashValue(hPtr);
TkTextMarkSegToIndex(textPtr, segPtr, &index);
segPtr = segPtr->nextPtr;
} else {
@@ -848,7 +873,7 @@ MarkFindPrev(
* position.
*/
- segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ segPtr = Tcl_GetHashValue(hPtr);
TkTextMarkSegToIndex(textPtr, segPtr, &index);
} else {
/*