summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatthoyts <patthoyts@users.sourceforge.net>2016-09-21 23:41:44 (GMT)
committerpatthoyts <patthoyts@users.sourceforge.net>2016-09-21 23:41:44 (GMT)
commita74f5d2c79ac224546adb83aea7b3ea2527b98ca (patch)
treea3025449e9f439f19f08e5cf7d37e80a3e60db0a
parentc6f38f9550c0b06da628964a298e5b290f8a1f8f (diff)
downloadtk-a74f5d2c79ac224546adb83aea7b3ea2527b98ca.zip
tk-a74f5d2c79ac224546adb83aea7b3ea2527b98ca.tar.gz
tk-a74f5d2c79ac224546adb83aea7b3ea2527b98ca.tar.bz2
[3126428] Repaint ttk labels and buttons when the image is changed.
In Tk the images associated with labels and buttons have their image changed callback set to cause the widget to be redrawn if the image is changed in any way. However, this has not been done for the ttk equivalent widgets.
-rw-r--r--generic/ttk/ttkButton.c13
-rw-r--r--generic/ttk/ttkImage.c36
-rw-r--r--generic/ttk/ttkTheme.h2
3 files changed, 46 insertions, 5 deletions
diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c
index bc44f25..c00754b 100644
--- a/generic/ttk/ttkButton.c
+++ b/generic/ttk/ttkButton.c
@@ -136,6 +136,15 @@ BaseCleanup(void *recordPtr)
TtkFreeImageSpec(basePtr->base.imageSpec);
}
+static void
+BaseImageChanged(
+ ClientData clientData, int x, int y, int width, int height,
+ int imageWidth, int imageHeight)
+{
+ Base *basePtr = (Base *)clientData;
+ TtkResizeWidget(&basePtr->core);
+}
+
static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
Base *basePtr = recordPtr;
@@ -149,8 +158,8 @@ static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
}
if (basePtr->base.imageObj) {
- imageSpec = TtkGetImageSpec(
- interp, basePtr->core.tkwin, basePtr->base.imageObj);
+ imageSpec = TtkGetImageSpecEx(
+ interp, basePtr->core.tkwin, basePtr->base.imageObj, BaseImageChanged, basePtr);
if (!imageSpec) {
goto error;
}
diff --git a/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c
index 2b12864..c435a50 100644
--- a/generic/ttk/ttkImage.c
+++ b/generic/ttk/ttkImage.c
@@ -25,6 +25,8 @@ struct TtkImageSpec {
int mapCount; /* #state-specific overrides */
Ttk_StateSpec *states; /* array[mapCount] of states ... */
Tk_Image *images; /* ... per-state images to use */
+ Tk_ImageChangedProc *imageChanged;
+ ClientData imageChangedClientData;
};
/* NullImageChanged --
@@ -34,15 +36,41 @@ static void NullImageChanged(ClientData clientData,
int x, int y, int width, int height, int imageWidth, int imageHeight)
{ /* No-op */ }
+/* ImageSpecImageChanged --
+ * Image changes should trigger a repaint.
+ */
+static void ImageSpecImageChanged(ClientData clientData,
+ int x, int y, int width, int height, int imageWidth, int imageHeight)
+{
+ Ttk_ImageSpec *imageSpec = (Ttk_ImageSpec *)clientData;
+ if (imageSpec->imageChanged != NULL) {
+ imageSpec->imageChanged(imageSpec->imageChangedClientData,
+ x, y, width, height,
+ imageWidth, imageHeight);
+ }
+}
+
/* TtkGetImageSpec --
* Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
- * Result must be released using TtkFreeImageSpec.
+ * Result must be released using TtkFreeImageSpec.
*
- * TODO: Need a variant of this that takes a user-specified ImageChanged proc
*/
Ttk_ImageSpec *
TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
{
+ return TtkGetImageSpecEx(interp, tkwin, objPtr, NULL, NULL);
+}
+
+/* TtkGetImageSpecEx --
+ * Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
+ * Result must be released using TtkFreeImageSpec.
+ * imageChangedProc will be called when not NULL when
+ * the image changes to allow widgets to repaint.
+ */
+Ttk_ImageSpec *
+TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr,
+ Tk_ImageChangedProc *imageChangedProc, ClientData imageChangedClientData)
+{
Ttk_ImageSpec *imageSpec = 0;
int i = 0, n = 0, objc;
Tcl_Obj **objv;
@@ -52,6 +80,8 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
imageSpec->mapCount = 0;
imageSpec->states = 0;
imageSpec->images = 0;
+ imageSpec->imageChanged = imageChangedProc;
+ imageSpec->imageChangedClientData = imageChangedClientData;
if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
goto error;
@@ -73,7 +103,7 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
/* Get base image:
*/
imageSpec->baseImage = Tk_GetImage(
- interp, tkwin, Tcl_GetString(objv[0]), NullImageChanged, NULL);
+ interp, tkwin, Tcl_GetString(objv[0]), ImageSpecImageChanged, imageSpec);
if (!imageSpec->baseImage) {
goto error;
}
diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h
index 7bf2a7f..9251dea 100644
--- a/generic/ttk/ttkTheme.h
+++ b/generic/ttk/ttkTheme.h
@@ -372,6 +372,8 @@ MODULE_SCOPE void Ttk_RegisterNamedColor(Ttk_ResourceCache, const char *, XColor
typedef struct TtkImageSpec Ttk_ImageSpec;
TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *);
+TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *,
+ Tk_ImageChangedProc *, ClientData);
TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *);
TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State);