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-2009 Daniel A. Steffen <das@users.sourceforge.net> 8 * Copyright 2008-2009, Apple Inc. 9 * 10 * See the file "license.terms" for information on usage and redistribution 11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 12 * 13 * RCS: @(#) $Id$ 14 */ 15 16#include "tkMacOSXPrivate.h" 17#include "tkEntry.h" 18 19static ThemeButtonKind ComputeIncDecParameters(int height, int *width); 20 21#define HIOrientation kHIThemeOrientationNormal 22 23/* 24 *-------------------------------------------------------------- 25 * 26 * ComputeIncDecParameters -- 27 * 28 * This procedure figures out which of the kThemeIncDec buttons to use. 29 * It also sets width to the width of the IncDec button. 30 * 31 * Results: 32 * The ThemeButtonKind of the button we should use. 33 * 34 * Side effects: 35 * May draw the entry border into pixmap. 36 * 37 *-------------------------------------------------------------- 38 */ 39 40static ThemeButtonKind 41ComputeIncDecParameters( 42 int height, 43 int *width) 44{ 45 ThemeButtonKind kind; 46 47 if (height < 11 || height > 28) { 48 *width = 0; 49 kind = (ThemeButtonKind) 0; 50 } else { 51 if (height >= 21) { 52 *width = 13; 53 kind = kThemeIncDecButton; 54 } else if (height >= 18) { 55 *width = 12; 56 kind = kThemeIncDecButtonSmall; 57 } else { 58 *width = 11; 59 kind = kThemeIncDecButtonMini; 60 } 61 } 62 63 return kind; 64} 65 66/* 67 *-------------------------------------------------------------- 68 * 69 * TkpDrawEntryBorderAndFocus -- 70 * 71 * This procedure redraws the border of an entry window. It overrides the 72 * generic border drawing code if the entry widget parameters are such 73 * that the native widget drawing is a good fit. This version just 74 * returns 1, so platforms that don't do special native drawing don't 75 * have to implement it. 76 * 77 * Results: 78 * 1 if it has drawn the border, 0 if not. 79 * 80 * Side effects: 81 * May draw the entry border into pixmap. 82 * 83 *-------------------------------------------------------------- 84 */ 85 86int 87TkpDrawEntryBorderAndFocus( 88 Entry *entryPtr, 89 Drawable d, 90 int isSpinbox) 91{ 92 CGRect bounds; 93 TkMacOSXDrawingContext dc; 94 GC bgGC; 95 Tk_Window tkwin = entryPtr->tkwin; 96 int oldWidth = 0; 97 MacDrawable *macDraw = (MacDrawable *) d; 98 const HIThemeFrameDrawInfo info = { 99 .version = 0, 100 .kind = kHIThemeFrameTextFieldSquare, 101 .state = (entryPtr->state == STATE_DISABLED ? kThemeStateInactive : 102 kThemeStateActive), 103 .isFocused = (entryPtr->flags & GOT_FOCUS ? 1 : 0), 104 }; 105 106 /* 107 * I use 6 as the borderwidth. 2 of the 5 go into the actual frame the 3 108 * are because the Mac OS Entry widgets leave more space around the Text 109 * than Tk does on X11. 110 */ 111 112 if (entryPtr->borderWidth != MAC_OSX_ENTRY_BORDER 113 || entryPtr->highlightWidth != MAC_OSX_FOCUS_WIDTH 114 || entryPtr->relief != MAC_OSX_ENTRY_RELIEF) { 115 return 0; 116 } 117 118 /* 119 * For the spinbox, we have to make the entry part smaller by the size of 120 * the buttons. We also leave 2 pixels to the left (as per the HIG) and 121 * space for one pixel to the right, 'cause it makes the buttons look 122 * nicer. 123 */ 124 125 if (isSpinbox) { 126 int incDecWidth; 127 128 oldWidth = Tk_Width(tkwin); 129 130 ComputeIncDecParameters(Tk_Height(tkwin) - 2 * MAC_OSX_FOCUS_WIDTH, 131 &incDecWidth); 132 Tk_Width(tkwin) -= incDecWidth + 1; 133 } 134 135 /* 136 * The focus ring is drawn with an Alpha at the outside part of the ring, 137 * so we have to draw over the edges of the ring before drawing the focus 138 * or the text will peep through. 139 */ 140 141 bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, d); 142 TkDrawInsetFocusHighlight(entryPtr->tkwin, bgGC, MAC_OSX_FOCUS_WIDTH, d, 0); 143 144 /* 145 * Inset the entry Frame by the maximum width of the focus rect, which is 146 * 3 according to the Carbon docs. 147 */ 148 149 bounds.origin.x = macDraw->xOff + MAC_OSX_FOCUS_WIDTH; 150 bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH; 151 bounds.size.width = Tk_Width(tkwin) - 2*MAC_OSX_FOCUS_WIDTH; 152 bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH; 153 if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) { 154 return 0; 155 } 156 ChkErr(HIThemeDrawFrame, &bounds, &info, dc.context, HIOrientation); 157 TkMacOSXRestoreDrawingContext(&dc); 158 if (isSpinbox) { 159 Tk_Width(tkwin) = oldWidth; 160 } 161 return 1; 162} 163 164/* 165 *-------------------------------------------------------------- 166 * 167 * TkpDrawSpinboxButtons -- 168 * 169 * This procedure redraws the buttons of an spinbox widget. It overrides 170 * the generic button drawing code if the spinbox widget parameters are 171 * such that the native widget drawing is a good fit. This version just 172 * returns 0, so platforms that don't do special native drawing don't 173 * have to implement it. 174 * 175 * Results: 176 * 1 if it has drawn the border, 0 if not. 177 * 178 * Side effects: 179 * May draw the entry border into pixmap. 180 * 181 *-------------------------------------------------------------- 182 */ 183 184int 185TkpDrawSpinboxButtons( 186 Spinbox *sbPtr, 187 Drawable d) 188{ 189 CGRect bounds; 190 Tk_Window tkwin = sbPtr->entry.tkwin; 191 int height = Tk_Height(tkwin); 192 int buttonHeight = height - 2 * MAC_OSX_FOCUS_WIDTH; 193 int incDecWidth; 194 TkMacOSXDrawingContext dc; 195 XRectangle rects[1]; 196 GC bgGC; 197 MacDrawable *macDraw = (MacDrawable *) d; 198 HIThemeButtonDrawInfo info = { 199 .version = 0, 200 .adornment = kThemeAdornmentNone, 201 }; 202 203 /* 204 * FIXME: RAISED really makes more sense 205 */ 206 207 if (sbPtr->buRelief != TK_RELIEF_FLAT) { 208 return 0; 209 } 210 211 /* 212 * The actual sizes of the IncDec button are 21 for the normal, 18 for the 213 * small and 15 for the mini. But the spinbox still looks okay if the 214 * entry is a little bigger than this, so we give it a little slop. 215 */ 216 217 info.kind = ComputeIncDecParameters(buttonHeight, &incDecWidth); 218 if (info.kind == (ThemeButtonKind) 0) { 219 return 0; 220 } 221 222 if (sbPtr->entry.state == STATE_DISABLED) { 223 info.state = kThemeStateInactive; 224 info.value = kThemeButtonOff; 225 } else if (sbPtr->selElement == SEL_BUTTONUP) { 226 info.state = kThemeStatePressedUp; 227 info.value = kThemeButtonOn; 228 } else if (sbPtr->selElement == SEL_BUTTONDOWN) { 229 info.state = kThemeStatePressedDown; 230 info.value = kThemeButtonOn; 231 } else { 232 info.state = kThemeStateActive; 233 info.value = kThemeButtonOff; 234 } 235 236 bounds.origin.x = macDraw->xOff + Tk_Width(tkwin) - incDecWidth - 1; 237 bounds.origin.y = macDraw->yOff + MAC_OSX_FOCUS_WIDTH; 238 bounds.size.width = incDecWidth; 239 bounds.size.height = Tk_Height(tkwin) - 2*MAC_OSX_FOCUS_WIDTH; 240 241 /* 242 * We had to make the entry part of the window smaller so that we wouldn't 243 * overdraw the spin buttons with the focus highlight. So now we have to 244 * draw the highlightbackground. 245 */ 246 247 bgGC = Tk_GCForColor(sbPtr->entry.highlightBgColorPtr, d); 248 rects[0].x = bounds.origin.x; 249 rects[0].y = 0; 250 rects[0].width = Tk_Width(tkwin); 251 rects[0].height = Tk_Height(tkwin); 252 XFillRectangles(Tk_Display(tkwin), d, bgGC, rects, 1); 253 254 if (!TkMacOSXSetupDrawingContext(d, NULL, 1, &dc)) { 255 return 0; 256 } 257 ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL); 258 TkMacOSXRestoreDrawingContext(&dc); 259 return 1; 260} 261 262/* 263 * Local Variables: 264 * mode: c 265 * c-basic-offset: 4 266 * fill-column: 79 267 * coding: utf-8 268 * End: 269 */ 270