1 174 yongsun /* 2 174 yongsun * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 174 yongsun * 4 177 yongsun * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. 5 174 yongsun * 6 174 yongsun * The contents of this file are subject to the terms of either the GNU Lesser 7 174 yongsun * General Public License Version 2.1 only ("LGPL") or the Common Development and 8 174 yongsun * Distribution License ("CDDL")(collectively, the "License"). You may not use this 9 174 yongsun * file except in compliance with the License. You can obtain a copy of the CDDL at 10 174 yongsun * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at 11 174 yongsun * http://www.opensource.org/licenses/lgpl-license.php. See the License for the 12 174 yongsun * specific language governing permissions and limitations under the License. When 13 174 yongsun * distributing the software, include this License Header Notice in each file and 14 174 yongsun * include the full text of the License in the License file as well as the 15 174 yongsun * following notice: 16 174 yongsun * 17 174 yongsun * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE 18 174 yongsun * (CDDL) 19 174 yongsun * For Covered Software in this distribution, this License shall be governed by the 20 174 yongsun * laws of the State of California (excluding conflict-of-law provisions). 21 174 yongsun * Any litigation relating to this License shall be subject to the jurisdiction of 22 174 yongsun * the Federal Courts of the Northern District of California and the state courts 23 174 yongsun * of the State of California, with venue lying in Santa Clara County, California. 24 174 yongsun * 25 174 yongsun * Contributor(s): 26 174 yongsun * 27 174 yongsun * If you wish your version of this file to be governed by only the CDDL or only 28 174 yongsun * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to 29 174 yongsun * include this software in this distribution under the [CDDL or LGPL Version 2.1] 30 174 yongsun * license." If you don't indicate a single choice of license, a recipient has the 31 174 yongsun * option to distribute your version of this file under either the CDDL or the LGPL 32 174 yongsun * Version 2.1, or to extend the choice of license to its licensees as provided 33 174 yongsun * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL 34 174 yongsun * Version 2 license, then the option applies only if the new code is made subject 35 174 yongsun * to such option by the copyright holder. 36 174 yongsun */ 37 174 yongsun 38 273 yongsun #import "Carbon/Carbon.h" 39 174 yongsun #import "CandidateWindow.h" 40 174 yongsun 41 174 yongsun static void tuningFrameForScreen (NSRect *, NSSize, NSRect); 42 174 yongsun 43 174 yongsun @interface CandidateView : NSView { 44 174 yongsun NSAttributedString *_string; 45 174 yongsun } 46 174 yongsun 47 177 yongsun -(void) setAttributedString:(NSAttributedString *)str; 48 174 yongsun 49 174 yongsun @end 50 174 yongsun 51 174 yongsun @implementation CandidateView 52 174 yongsun 53 177 yongsun -(void) setAttributedString:(NSAttributedString *)str 54 174 yongsun { 55 174 yongsun [str retain]; 56 174 yongsun [_string release]; 57 174 yongsun _string = str; 58 174 yongsun [self setNeedsDisplay:YES]; 59 174 yongsun } 60 174 yongsun 61 174 yongsun - (void)drawRect:(NSRect)rect 62 174 yongsun { 63 174 yongsun if (!_string) 64 174 yongsun return; 65 174 yongsun 66 174 yongsun NSPoint stringOrigin; 67 174 yongsun NSSize stringSize = [_string size]; 68 174 yongsun stringOrigin.x = rect.origin.x + ( rect.size.width - stringSize.width)/2; 69 174 yongsun stringOrigin.y = rect.origin.y + ( rect.size.height - stringSize.height)/2; 70 174 yongsun [_string drawAtPoint:stringOrigin]; 71 174 yongsun } 72 174 yongsun 73 174 yongsun - (void) dealloc 74 174 yongsun { 75 174 yongsun [_string release]; 76 174 yongsun [super dealloc]; 77 174 yongsun } 78 174 yongsun 79 174 yongsun @end 80 174 yongsun 81 174 yongsun @implementation CandidateWindow 82 174 yongsun 83 174 yongsun -(id)init 84 174 yongsun { 85 183 yongsun _font = [[NSFont fontWithName:@"Hei" size:16] retain]; 86 183 yongsun _bgColor = [[NSColor colorWithDeviceRed:1.0 green:0.5 blue:0.0 alpha:0.8] retain]; 87 183 yongsun _fgColor = [[NSColor whiteColor] retain]; 88 183 yongsun _hlColor = [[NSColor blueColor] retain]; 89 183 yongsun 90 183 yongsun _attr = [[NSMutableDictionary alloc] init]; 91 183 yongsun [_attr setObject:_fgColor forKey:NSForegroundColorAttributeName]; 92 183 yongsun [_attr setObject:_font forKey:NSFontAttributeName]; 93 183 yongsun 94 174 yongsun _window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,0,0) 95 174 yongsun styleMask:NSBorderlessWindowMask 96 174 yongsun backing:NSBackingStoreBuffered 97 174 yongsun defer:NO]; 98 174 yongsun 99 174 yongsun [_window setLevel:NSScreenSaverWindowLevel]; 100 174 yongsun [_window setHasShadow: YES]; 101 174 yongsun [_window setOpaque:NO]; 102 183 yongsun 103 176 yongsun [_window setBackgroundColor:_bgColor]; 104 174 yongsun 105 174 yongsun _view = [[CandidateView alloc] initWithFrame:[[_window contentView] frame]]; 106 174 yongsun [_window setContentView:_view]; 107 174 yongsun 108 174 yongsun return self; 109 176 yongsun } 110 176 yongsun 111 266 yongsun -(NSFont *)font 112 266 yongsun { 113 266 yongsun return _font; 114 266 yongsun } 115 266 yongsun 116 176 yongsun -(void)setFont:(NSFont*)font 117 176 yongsun { 118 176 yongsun [font retain]; 119 176 yongsun [_font release]; 120 176 yongsun _font = font; 121 176 yongsun [_attr setObject:_font forKey:NSFontAttributeName]; 122 176 yongsun } 123 176 yongsun 124 266 yongsun -(NSColor *)bgColor 125 176 yongsun { 126 266 yongsun return _bgColor; 127 176 yongsun } 128 176 yongsun 129 176 yongsun -(void)setBgColor:(NSColor*)color 130 176 yongsun { 131 176 yongsun [color retain]; 132 176 yongsun [_bgColor release]; 133 176 yongsun _bgColor = color; 134 176 yongsun [_window setBackgroundColor:color]; 135 174 yongsun } 136 174 yongsun 137 266 yongsun -(NSColor *)fgColor 138 266 yongsun { 139 266 yongsun return _fgColor; 140 266 yongsun } 141 266 yongsun 142 266 yongsun -(void)setFgColor:(NSColor*)color 143 266 yongsun { 144 266 yongsun [color retain]; 145 266 yongsun [_fgColor release]; 146 266 yongsun _fgColor = color; 147 266 yongsun } 148 266 yongsun 149 266 yongsun -(NSColor *)hlColor 150 266 yongsun { 151 266 yongsun return _hlColor; 152 266 yongsun } 153 266 yongsun 154 266 yongsun -(void)setHlColor:(NSColor*)color 155 266 yongsun { 156 266 yongsun [color retain]; 157 266 yongsun [_hlColor release]; 158 266 yongsun _hlColor = color; 159 266 yongsun } 160 266 yongsun 161 174 yongsun -(void)showCandidates:(NSArray *)candiArray around:(NSRect)cursorRect 162 174 yongsun { 163 174 yongsun if ([candiArray count] == 0) { 164 174 yongsun [self hideCandidates]; 165 174 yongsun return; 166 174 yongsun } 167 266 yongsun 168 266 yongsun [_attr setObject:_fgColor forKey:NSForegroundColorAttributeName]; 169 266 yongsun [_attr setObject:_font forKey:NSFontAttributeName]; 170 174 yongsun 171 174 yongsun int i; 172 174 yongsun NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init]; 173 174 yongsun for (i=0; i<[candiArray count]; i++) { 174 183 yongsun NSString *str = [NSString stringWithFormat:@"%d.%@ ", i+1, [candiArray objectAtIndex:i]]; 175 183 yongsun NSAttributedString *astr = [[[NSAttributedString alloc] initWithString:str attributes:_attr] autorelease]; 176 183 yongsun [string appendAttributedString:astr]; 177 174 yongsun 178 174 yongsun if (i==0) 179 174 yongsun [string addAttribute:NSForegroundColorAttributeName 180 183 yongsun value:_hlColor 181 174 yongsun range:NSMakeRange(0, [str length])]; 182 174 yongsun } 183 174 yongsun 184 174 yongsun NSRect winRect = [_window frame]; 185 174 yongsun NSSize strSize = [string size]; 186 174 yongsun 187 174 yongsun tuningFrameForScreen (&winRect, strSize, cursorRect); 188 174 yongsun [_window setFrame:winRect display:NO]; 189 174 yongsun 190 177 yongsun [(CandidateView*)_view setAttributedString:string]; 191 183 yongsun [string release]; 192 183 yongsun 193 174 yongsun [_window orderFront:nil]; 194 174 yongsun } 195 174 yongsun 196 174 yongsun -(void)hideCandidates 197 174 yongsun { 198 174 yongsun [_window orderOut:self]; 199 174 yongsun } 200 174 yongsun 201 174 yongsun - (void) dealloc 202 174 yongsun { 203 183 yongsun [_font release]; 204 183 yongsun [_bgColor release]; 205 183 yongsun [_fgColor release]; 206 183 yongsun [_hlColor release]; 207 174 yongsun [_attr release]; 208 183 yongsun [_view release]; 209 183 yongsun [_window release]; 210 174 yongsun [super dealloc]; 211 174 yongsun } 212 174 yongsun 213 174 yongsun @end 214 174 yongsun 215 174 yongsun static void tuningFrameForScreen (NSRect *winRect, NSSize strSize, NSRect cursorRect) 216 174 yongsun { 217 273 yongsun /* caculate the initial window's size */ 218 174 yongsun winRect->size.height = strSize.height+5; 219 174 yongsun winRect->size.width = strSize.width+5; 220 273 yongsun winRect->origin.x = cursorRect.origin.x + 2; 221 273 yongsun winRect->origin.y = cursorRect.origin.y - winRect->size.height -2; 222 174 yongsun 223 273 yongsun /* find a proper screen by input cursor */ 224 273 yongsun NSRect screenRect = [[NSScreen mainScreen] frame]; 225 273 yongsun NSArray *screens =[NSScreen screens]; 226 273 yongsun int i, num_of_scrs = [screens count]; 227 174 yongsun 228 273 yongsun /* no choices, just use mainScreen */ 229 273 yongsun if (num_of_scrs == 1) 230 273 yongsun goto FOUND_SCREEN; 231 273 yongsun 232 273 yongsun for (i=0; i<num_of_scrs; i++) { 233 273 yongsun NSScreen *screen = [screens objectAtIndex:i]; 234 273 yongsun NSRect rect = [screen frame]; 235 273 yongsun if (NSPointInRect (cursorRect.origin, rect)) { 236 273 yongsun screenRect = rect; 237 273 yongsun goto FOUND_SCREEN; 238 273 yongsun } 239 273 yongsun } 240 273 yongsun 241 273 yongsun /* find a proper screen by mouse position */ 242 273 yongsun HIPoint p; 243 273 yongsun HIGetMousePosition (kHICoordSpaceScreenPixel, NULL, &p); 244 273 yongsun NSPoint mousePosition; 245 273 yongsun mousePosition.x = p.x; 246 273 yongsun mousePosition.y = screenRect.size.height - p.y; 247 273 yongsun 248 273 yongsun for (i=0; i<num_of_scrs; i++) { 249 273 yongsun NSScreen *screen = [screens objectAtIndex:i]; 250 273 yongsun NSRect rect = [screen frame]; 251 273 yongsun if (NSPointInRect (mousePosition, rect)) { 252 273 yongsun screenRect = rect; 253 273 yongsun goto FOUND_SCREEN; 254 273 yongsun } 255 273 yongsun } 256 273 yongsun 257 273 yongsun FOUND_SCREEN:; 258 273 yongsun CGFloat min_x = NSMinX (screenRect), max_x = NSMaxX (screenRect); 259 273 yongsun CGFloat min_y = NSMinY (screenRect); 260 273 yongsun 261 273 yongsun if (winRect->origin.x > max_x - winRect->size.width) 262 273 yongsun winRect->origin.x = max_x - winRect->size.width; 263 273 yongsun 264 273 yongsun if (winRect->origin.x < min_x) 265 273 yongsun winRect->origin.x = min_x; 266 273 yongsun 267 273 yongsun if (winRect->origin.y < min_y) 268 273 yongsun winRect->origin.y = cursorRect.origin.y > min_y? 269 273 yongsun cursorRect.origin.y + cursorRect.size.height + 2: 270 273 yongsun min_y; 271 174 yongsun } 272