1/* 2 * tkMacOSXEntry.c -- 3 * 4 * This file implements the native aqua entry widget. 5 * 6 * Copyright 2001, Apple Computer, Inc. 7 * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> 8 * 9 * See the file "license.terms" for information on usage and redistribution of 10 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 * 12 * The following terms apply to all files originating from Apple 13 * Computer, Inc. ("Apple") and associated with the software 14 * unless explicitly disclaimed in individual files. 15 * 16 * 17 * Apple hereby grants permission to use, copy, modify, 18 * distribute, and license this software and its documentation 19 * for any purpose, provided that existing copyright notices are 20 * retained in all copies and that this notice is included 21 * verbatim in any distributions. No written agreement, license, 22 * or royalty fee is required for any of the authorized 23 * uses. Modifications to this software may be copyrighted by 24 * their authors and need not follow the licensing terms 25 * described here, provided that the new terms are clearly 26 * indicated on the first page of each file where they apply. 27 * 28 * 29 * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE 30 * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 31 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF 32 * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, 33 * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND 35 * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, 36 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 37 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS 38 * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE 39 * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE 40 * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 41 * 42 * GOVERNMENT USE: If you are acquiring this software on behalf 43 * of the U.S. government, the Government shall have only 44 * "Restricted Rights" in the software and related documentation 45 * as defined in the Federal Acquisition Regulations (FARs) in 46 * Clause 52.227.19 (c) (2). If you are acquiring the software 47 * on behalf of the Department of Defense, the software shall be 48 * classified as "Commercial Computer Software" and the 49 * Government shall have only "Restricted Rights" as defined in 50 * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the 51 * foregoing, the authors grant the U.S. Government and others 52 * acting in its behalf permission to use and distribute the 53 * software in accordance with the terms specified in this 54 * license. 55 * 56 * RCS: @(#) $Id: tkMacOSXEntry.c,v 1.2.2.13 2007/11/09 06:26:55 das Exp $ 57 */ 58 59#include "tkMacOSXPrivate.h" 60#include "tkMacOSXDefault.h" 61#include "tkEntry.h" 62 63static ThemeButtonKind ComputeIncDecParameters (int height, int *width); 64 65/* 66 *-------------------------------------------------------------- 67 * 68 * ComputeIncDecParameters -- 69 * 70 * This procedure figures out which of the kThemeIncDec 71 * buttons to use. It also sets width to the width of the 72 * IncDec button. 73 * 74 * Results: 75 * The ThemeButtonKind of the button we should use. 76 * 77 * Side effects: 78 * May draw the entry border into pixmap. 79 * 80 *-------------------------------------------------------------- 81 */ 82static ThemeButtonKind 83ComputeIncDecParameters(int height, int *width) 84{ 85 ThemeButtonKind kind; 86 87 TK_IF_HI_TOOLBOX (3, 88 if (height < 11 || height > 28) { 89 *width = 0; 90 kind = (ThemeButtonKind) 0; 91 } else { 92 if (height >= 21) { 93 *width = 13; 94 kind = kThemeIncDecButton; 95 } else if (height >= 18) { 96 *width = 12; 97 kind = kThemeIncDecButtonSmall; 98 } else { 99 *width = 11; 100 kind = kThemeIncDecButtonMini; 101 } 102 } 103 ) TK_ELSE_HI_TOOLBOX (3, 104 if (height < 21 || height > 28) { 105 *width = 0; 106 kind = (ThemeButtonKind) 0; 107 } else { 108 *width = 13; 109 kind = kThemeIncDecButton; 110 } 111 ) TK_ENDIF 112 113 return kind; 114} 115 116/* 117 *-------------------------------------------------------------- 118 * 119 * TkpDrawEntryBorderAndFocus -- 120 * 121 * This procedure redraws the border of an entry window. 122 * It overrides the generic border drawing code if the 123 * entry widget parameters are such that the native widget 124 * drawing is a good fit. 125 * This version just returns 1, so platforms that don't 126 * do special native drawing don't have to implement it. 127 * 128 * Results: 129 * 1 if it has drawn the border, 0 if not. 130 * 131 * Side effects: 132 * May draw the entry border into pixmap. 133 * 134 *-------------------------------------------------------------- 135 */ 136int 137TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox) 138{ 139 Rect bounds; 140 TkMacOSXDrawingContext dc; 141 GC bgGC; 142 Tk_Window tkwin = entryPtr->tkwin; 143 ThemeDrawState drawState; 144 int oldWidth = 0; 145 MacDrawable *macDraw = (MacDrawable *) d; 146 147 /* 148 * I use 6 as the borderwidth. 2 of the 5 go into the actual frame the 149 * 3 are because the Mac OS Entry widgets leave more space around the 150 * Text than Tk does on X11. 151 */ 152 153 if (entryPtr->borderWidth != MAC_OSX_ENTRY_BORDER 154 || entryPtr->highlightWidth != MAC_OSX_FOCUS_WIDTH 155 || entryPtr->relief != MAC_OSX_ENTRY_RELIEF) { 156 return 0; 157 } 158 159 /* 160 * For the spinbox, we have to make the entry part smaller by the size 161 * of the buttons. We also leave 2 pixels to the left (as per the HIG) 162 * and space for one pixel to the right, 'cause it makes the buttons look 163 * nicer. 164 */ 165 166 if (isSpinbox) { 167 ThemeButtonKind buttonKind; 168 int incDecWidth; 169 170 oldWidth = Tk_Width(tkwin); 171 172 buttonKind = ComputeIncDecParameters(Tk_Height(tkwin) 173 - 2 * MAC_OSX_FOCUS_WIDTH, &incDecWidth); 174 Tk_Width(tkwin) -= incDecWidth + 1; 175 } 176 177 /* 178 * The focus ring is drawn with an Alpha at the outside 179 * part of the ring, so we have to draw over the edges of the 180 * ring before drawing the focus or the text will peep through. 181 */ 182 183 bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, d); 184 TkDrawInsetFocusHighlight(entryPtr->tkwin, bgGC, MAC_OSX_FOCUS_WIDTH, d, 0); 185 186 /* 187 * Inset the entry Frame by the maximum width of the focus rect, 188 * which is 3 according to the Carbon docs. 189 */ 190 191 bounds.left = macDraw->xOff + MAC_OSX_FOCUS_WIDTH; 192 bounds.top = macDraw->yOff + MAC_OSX_FOCUS_WIDTH; 193 bounds.right = macDraw->xOff + Tk_Width(tkwin) - MAC_OSX_FOCUS_WIDTH; 194 bounds.bottom = macDraw->yOff + Tk_Height(tkwin) - MAC_OSX_FOCUS_WIDTH; 195 if (entryPtr->state == STATE_DISABLED) { 196 drawState = kThemeStateInactive; 197 } else { 198 drawState = kThemeStateActive; 199 } 200 if (!TkMacOSXSetupDrawingContext(d, NULL, 0, &dc)) { 201 return 0; 202 } 203 DrawThemeEditTextFrame(&bounds, drawState); 204 if (entryPtr->flags & GOT_FOCUS) { 205 /* 206 * Don't call this if we don't have the focus, because then it 207 * erases the focus rect to white, but we've already drawn the 208 * highlightbackground above. 209 */ 210 211 DrawThemeFocusRect(&bounds, (entryPtr->flags & GOT_FOCUS) != 0); 212 } 213 if (isSpinbox) { 214 Tk_Width(tkwin) = oldWidth; 215 } 216 TkMacOSXRestoreDrawingContext(&dc); 217 return 1; 218} 219/* 220 *-------------------------------------------------------------- 221 * 222 * TkpDrawSpinboxButtons -- 223 * 224 * This procedure redraws the buttons of an spinbox widget. 225 * It overrides the generic button drawing code if the 226 * spinbox widget parameters are such that the native widget 227 * drawing is a good fit. 228 * This version just returns 0, so platforms that don't 229 * do special native drawing don't have to implement it. 230 * 231 * Results: 232 * 1 if it has drawn the border, 0 if not. 233 * 234 * Side effects: 235 * May draw the entry border into pixmap. 236 * 237 *-------------------------------------------------------------- 238 */ 239 240int 241TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d) 242{ 243 Rect inBounds; 244 ThemeButtonKind inKind; 245 ThemeButtonDrawInfo inNewInfo; 246 ThemeButtonDrawInfo * inPrevInfo = NULL; 247 ThemeEraseUPP inEraseProc = NULL; 248 ThemeButtonDrawUPP inLabelProc = NULL; 249 UInt32 inUserData = 0; 250 Tk_Window tkwin = sbPtr->entry.tkwin; 251 int height = Tk_Height(tkwin); 252 int buttonHeight = height - 2 * MAC_OSX_FOCUS_WIDTH; 253 int incDecWidth; 254 TkMacOSXDrawingContext dc; 255 XRectangle rects[1]; 256 GC bgGC; 257 MacDrawable *macDraw = (MacDrawable *) d; 258 259 /* 260 * FIXME: RAISED really makes more sense 261 */ 262 263 if (sbPtr->buRelief != TK_RELIEF_FLAT) { 264 return 0; 265 } 266 267 /* 268 * The actual sizes of the IncDec button are 21 for the normal, 269 * 18 for the small and 15 for the mini. But the spinbox still 270 * looks okay if the entry is a little bigger than this, so we 271 * give it a little slop. 272 */ 273 274 inKind = ComputeIncDecParameters(buttonHeight, &incDecWidth); 275 if (inKind == (ThemeButtonKind) 0) { 276 return 0; 277 } 278 279 if (sbPtr->entry.state == STATE_DISABLED) { 280 inNewInfo.state = kThemeStateInactive; 281 inNewInfo.value = kThemeButtonOff; 282 } else if (sbPtr->selElement == SEL_BUTTONUP) { 283 inNewInfo.state = kThemeStatePressedUp; 284 inNewInfo.value = kThemeButtonOn; 285 } else if (sbPtr->selElement == SEL_BUTTONDOWN) { 286 inNewInfo.state = kThemeStatePressedDown; 287 inNewInfo.value = kThemeButtonOn; 288 } else { 289 inNewInfo.state = kThemeStateActive; 290 inNewInfo.value = kThemeButtonOff; 291 } 292 293 inNewInfo.adornment = kThemeAdornmentNone; 294 295 inBounds.left = macDraw->xOff + Tk_Width(tkwin) - incDecWidth - 1; 296 inBounds.right = macDraw->xOff + Tk_Width(tkwin) - 1; 297 inBounds.top = macDraw->yOff + MAC_OSX_FOCUS_WIDTH; 298 inBounds.bottom = macDraw->yOff + Tk_Height(tkwin) - MAC_OSX_FOCUS_WIDTH; 299 300 /* We had to make the entry part of the window smaller so that we 301 * wouldn't overdraw the spin buttons with the focus highlight. So 302 * now we have to draw the highlightbackground. 303 */ 304 305 bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d); 306 rects[0].x = inBounds.left; 307 rects[0].y = 0; 308 rects[0].width = Tk_Width(tkwin); 309 rects[0].height = Tk_Height(tkwin); 310 XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1); 311 312 if (!TkMacOSXSetupDrawingContext(d, NULL, 0, &dc)) { 313 return 0; 314 } 315 ChkErr(DrawThemeButton, &inBounds, inKind, &inNewInfo, inPrevInfo, 316 inEraseProc, inLabelProc, inUserData); 317 TkMacOSXRestoreDrawingContext(&dc); 318 return 1; 319} 320 321