1/* TShelfView.m 2 * 3 * Copyright (C) 2003-2012 Free Software Foundation, Inc. 4 * 5 * Author: Enrico Sersale <enrico@imago.ro> 6 * Riccardo Mottola <rm@gnu.org> 7 * Date: August 2001 8 * 9 * This file is part of the GNUstep GWorkspace application 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. 24 */ 25 26#import <AppKit/AppKit.h> 27#import <GNUstepBase/GNUstep.h> 28 29#import "TShelfView.h" 30#import "TShelfViewItem.h" 31#import "TShelfIconsView.h" 32#import "GWorkspace.h" 33 34 35#define SPECIAL_TAB_W 54 36#define BUTTORX 25 37#define BUTTSZ 9 38#define BUTTSPACE 12 39#define TAB_H 24 40#define LAB_MARGIN 13 41#define BEZ_TAB_W 14 42 43@implementation TShelfView 44 45- (id)initWithFrame:(NSRect)rect 46{ 47 self = [super initWithFrame: rect]; 48 49 if (self) { 50 NSRect r = NSZeroRect; 51 52 ASSIGN (items, [NSMutableArray array]); 53 54 font = [NSFont fontWithName: @"Helvetica-Bold" size: 12]; 55 if (font == nil) { 56 font = [NSFont boldSystemFontOfSize: 0]; 57 } 58 RETAIN (font); 59 60 italicFont = [NSFont fontWithName: @"Helvetica-BoldOblique" size: 12]; 61 if (italicFont == nil) { 62 italicFont = [NSFont boldSystemFontOfSize: 0]; 63 } 64 RETAIN (italicFont); 65 66 r.size = NSMakeSize(BUTTSZ, BUTTSZ); 67 r.origin.y = rect.size.height - TAB_H + (int)((TAB_H - BUTTSZ) / 2); 68 r.origin.x = rect.size.width - (BUTTSZ * 2 + BUTTSPACE); 69 70 rewButt = [[NSButton alloc] initWithFrame: r]; 71 [rewButt setButtonType: NSMomentaryLight]; 72 [rewButt setBordered: NO]; 73 [rewButt setTarget: self]; 74 [rewButt setAction: @selector (buttonsAction:)]; 75 [self addSubview: rewButt]; 76 RELEASE (rewButt); 77 78 r.origin.x += BUTTSPACE; 79 80 ffButt = [[NSButton alloc] initWithFrame: r]; 81 [ffButt setButtonType: NSMomentaryLight]; 82 [ffButt setBordered: NO]; 83 [ffButt setTarget: self]; 84 [ffButt setAction: @selector (buttonsAction:)]; 85 [self addSubview: ffButt]; 86 RELEASE (ffButt); 87 88 [self setButtonsEnabled: NO]; 89 90 lastItem = nil; 91 selected = nil; 92 } 93 94 return self; 95} 96 97- (void)dealloc 98{ 99 RELEASE (items); 100 RELEASE (font); 101 RELEASE (italicFont); 102 103 [super dealloc]; 104} 105 106- (void)addTabItem:(TShelfViewItem *)item 107{ 108 [self insertTabItem: item atIndex: [items count]]; 109} 110 111- (BOOL)insertTabItem:(TShelfViewItem *)item 112 atIndex:(NSUInteger)index 113{ 114 if (lastItem) { 115 if (index == [items count]) { 116 index--; 117 } 118 RETAIN (lastItem); 119 [items removeObject: lastItem]; 120 } 121 122 [item setTShelfView: self]; 123 [items insertObject: item atIndex: index]; 124 125 if (lastItem) { 126 [items insertObject: lastItem atIndex: [items count]]; 127 RELEASE (lastItem); 128 } 129 130 return YES; 131} 132 133- (void)setLastTabItem:(TShelfViewItem *)item 134{ 135 lastItem = item; 136 [item setTShelfView: self]; 137 [items insertObject: item atIndex: [items count]]; 138} 139 140- (BOOL)removeTabItem:(TShelfViewItem *)item 141{ 142 NSUInteger i = [items indexOfObject: item]; 143 144 if ((i == NSNotFound) || (item == lastItem)) { 145 return NO; 146 } 147 148 if (item == selected) { 149 [[selected view] removeFromSuperview]; 150 selected = nil; 151 } 152 153 [items removeObjectAtIndex: i]; 154 155 return YES; 156} 157 158- (NSUInteger)indexOfItem:(TShelfViewItem *)item 159{ 160 return [items indexOfObject: item]; 161} 162 163- (TShelfViewItem *)selectedTabItem 164{ 165 if ((selectedItem == NSNotFound) || ([items count] == 0)) { 166 return nil; 167 } 168 169 return [items objectAtIndex: selectedItem]; 170} 171 172- (void)selectTabItem:(TShelfViewItem *)item 173{ 174 TShelfIconsView *selectedView; 175 176 if (item == nil) 177 return; 178 179 if (selected != nil) 180 { 181 [selected setTabState: NSBackgroundTab]; 182 selectedView = (TShelfIconsView *)[selected view]; 183 if ([selectedView iconsType] == DATA_TAB) { 184 [selectedView setCurrentPBIcon: nil]; 185 } 186 [[selected view] removeFromSuperview]; 187 } 188 189 selected = item; 190 191 selectedItem = [items indexOfObject: selected]; 192 [selected setTabState: NSSelectedTab]; 193 194 selectedView = (TShelfIconsView *)[selected view]; 195 196 if (selectedView != nil) 197 { 198 [self addSubview: selectedView]; 199 [selectedView setFrame: [self contentRect]]; 200 [selectedView resizeWithOldSuperviewSize: [selectedView frame].size]; 201 [selectedView unselectOtherIcons: nil]; 202 if ([selectedView iconsType] == DATA_TAB) 203 { 204 [selectedView setCurrentPBIcon: nil]; 205 } 206 [[self window] makeFirstResponder: [selected initialFirstResponder]]; 207 } 208 209 [self setButtonsEnabled: (lastItem && (lastItem == selected))]; 210 211 [self setNeedsDisplay: YES]; 212} 213 214- (void)selectTabItemAtIndex:(NSUInteger)index 215{ 216 [self selectTabItem: [items objectAtIndex: index]]; 217} 218 219- (void)selectLastItem 220{ 221 if (lastItem) 222 { 223 [self selectTabItem: lastItem]; 224 } 225} 226 227- (NSFont *)font 228{ 229 return font; 230} 231 232- (NSFont *)italicFont 233{ 234 return italicFont; 235} 236 237- (NSRect)contentRect 238{ 239 NSRect cRect = [self bounds]; 240 241 cRect.origin.y += 1; 242 cRect.size.height -= 26.5; 243 244 return cRect; 245} 246 247void drawLeftTabBezier(NSPoint origin, float tabh, 248 NSColor *sc, NSColor *fc, BOOL seltab) 249{ 250 NSBezierPath *path = [NSBezierPath bezierPath]; 251 NSPoint endp = NSMakePoint(origin.x + BEZ_TAB_W, origin.y + tabh); 252 NSPoint cp1 = NSMakePoint(origin.x + (BEZ_TAB_W / 2), origin.y); 253 NSPoint cp2 = NSMakePoint(origin.x + BEZ_TAB_W - (BEZ_TAB_W / 2), origin.y + tabh); 254 255 [path moveToPoint: origin]; 256 [path curveToPoint: endp controlPoint1: cp1 controlPoint2: cp2]; 257 [sc set]; 258 [path stroke]; 259 260 [path lineToPoint: NSMakePoint(origin.x + BEZ_TAB_W, origin.y)]; 261 [path closePath]; 262 [fc set]; 263 [path fill]; 264 265 if (seltab) { 266 path = [NSBezierPath bezierPath]; 267 [path moveToPoint: origin]; 268 [path lineToPoint: NSMakePoint(origin.x + BEZ_TAB_W, origin.y)]; 269 [path stroke]; 270 } 271} 272 273void drawRightTabBezier(NSPoint origin, float tabh, 274 NSColor *sc, NSColor *fc, BOOL seltab) 275{ 276 NSBezierPath *path = [NSBezierPath bezierPath]; 277 NSPoint endp = NSMakePoint(origin.x - BEZ_TAB_W, origin.y + tabh); 278 NSPoint cp1 = NSMakePoint(origin.x - (BEZ_TAB_W / 2), origin.y); 279 NSPoint cp2 = NSMakePoint(origin.x - BEZ_TAB_W + (BEZ_TAB_W / 2), origin.y + tabh); 280 281 [path moveToPoint: origin]; 282 [path curveToPoint: endp controlPoint1: cp1 controlPoint2: cp2]; 283 [sc set]; 284 [path stroke]; 285 286 [path lineToPoint: NSMakePoint(origin.x - BEZ_TAB_W, origin.y)]; 287 [path closePath]; 288 [fc set]; 289 [path fill]; 290 291 if (seltab) { 292 path = [NSBezierPath bezierPath]; 293 [path moveToPoint: origin]; 294 [path lineToPoint: NSMakePoint(origin.x - BEZ_TAB_W, origin.y)]; 295 [path stroke]; 296 } 297} 298 299- (void)drawRect:(NSRect)rect 300{ 301 NSRect aRect = [self bounds]; 302 NSPoint p = aRect.origin; 303 NSSize s = aRect.size; 304 NSUInteger count; 305 int itemxspace; 306 NSImage *backImage; 307 NSColor *scolor; 308 NSColor *fcolor; 309 NSPoint selp[2]; 310 NSBezierPath *bpath; 311 int i; 312 NSPoint ipoint; 313 314 backImage = [[GWorkspace gworkspace] tshelfBackground]; 315 if (backImage) 316 [backImage compositeToPoint: NSZeroPoint operation: NSCompositeSourceOver]; 317 318 count = [items count]; 319 itemxspace = (int)((aRect.size.width - SPECIAL_TAB_W) / (count - 1)); 320 321 [[NSColor controlColor] set]; 322 NSRectFill(NSMakeRect(p.x, p.y, s.width, s.height - TAB_H)); 323 324 if (selected == NO) { 325 [self selectTabItemAtIndex: 0]; 326 } 327 328 selp[0] = NSZeroPoint; 329 selp[1] = NSZeroPoint; 330 331 aRect.size.height -= TAB_H; 332 333 ipoint = NSMakePoint (0,0); 334 for (i = count - 1; i >= 0; i--) 335 { 336 TShelfViewItem *anItem = [items objectAtIndex: i]; 337 NSRect r; 338 339 if (i == (count - 1)) 340 { 341 ipoint.x = (int)(aRect.size.width - SPECIAL_TAB_W); 342 ipoint.y = aRect.size.height; 343 344 if ([anItem tabState] == NSSelectedTab) 345 { 346 selp[0] = ipoint; 347 fcolor = [NSColor controlColor]; 348 } 349 else 350 { 351 fcolor = [NSColor controlBackgroundColor]; 352 } 353 354 scolor = [NSColor whiteColor]; 355 356 drawLeftTabBezier(ipoint, TAB_H, scolor, fcolor, NO); 357 358 r.origin.x = ipoint.x + LAB_MARGIN; 359 r.origin.y = aRect.size.height; 360 r.size.width = SPECIAL_TAB_W - LAB_MARGIN; 361 r.size.height = TAB_H -1; 362 363 bpath = [NSBezierPath bezierPath]; 364 [bpath setLineWidth: 1]; 365 [bpath moveToPoint: NSMakePoint(r.origin.x, r.origin.y + TAB_H)]; 366 [bpath relativeLineToPoint: NSMakePoint(r.size.width, 0)]; 367 [scolor set]; 368 [bpath stroke]; 369 370 [anItem drawImage: nil inRect: r]; 371 372 } 373 else 374 { 375 ipoint.y = aRect.size.height; 376 377 if ([anItem tabState] == NSSelectedTab) 378 { 379 selp[1] = NSMakePoint(ipoint.x + BEZ_TAB_W, ipoint.y); 380 fcolor = [NSColor controlColor]; 381 } 382 else 383 { 384 fcolor = [NSColor controlBackgroundColor]; 385 } 386 387 scolor = [NSColor blackColor]; 388 drawRightTabBezier(NSMakePoint(ipoint.x + BEZ_TAB_W, ipoint.y), 389 TAB_H, scolor, fcolor, NO); 390 ipoint.x -= itemxspace; 391 392 if (i != 0) { 393 if ([anItem tabState] == NSSelectedTab) { 394 selp[0] = ipoint; 395 } 396 397 scolor = [NSColor whiteColor]; 398 drawLeftTabBezier(ipoint, TAB_H, scolor, fcolor, NO); 399 400 r.origin.x = ipoint.x + LAB_MARGIN; 401 r.origin.y = aRect.size.height; 402 r.size.width = itemxspace - LAB_MARGIN; 403 r.size.height = TAB_H -1; 404 405 } else { 406 r.origin.x = ipoint.x; 407 r.origin.y = aRect.size.height; 408 r.size.width = itemxspace; 409 r.size.height = TAB_H -1; 410 } 411 412 scolor = [NSColor whiteColor]; 413 414 bpath = [NSBezierPath bezierPath]; 415 [bpath setLineWidth: 1]; 416 [bpath moveToPoint: NSMakePoint(r.origin.x, r.origin.y + TAB_H)]; 417 [bpath relativeLineToPoint: NSMakePoint(r.size.width, 0)]; 418 [scolor set]; 419 [bpath stroke]; 420 421 [anItem drawLabelInRect: r]; 422 } 423 } 424 425 fcolor = [NSColor controlColor]; 426 427 if (NSEqualPoints(selp[0], NSZeroPoint) == NO) { 428 scolor = [NSColor whiteColor]; 429 drawLeftTabBezier(selp[0], TAB_H, scolor, fcolor, YES); 430 431 bpath = [NSBezierPath bezierPath]; 432 [bpath setLineWidth: 1]; 433 [bpath moveToPoint: NSMakePoint(p.x - 2, aRect.size.height)]; 434 [bpath lineToPoint: selp[0]]; 435 [scolor set]; 436 [bpath stroke]; 437 } 438 439 if (NSEqualPoints(selp[1], NSZeroPoint) == NO) { 440 scolor = [NSColor blackColor]; 441 drawRightTabBezier(selp[1], TAB_H, scolor, fcolor, YES); 442 443 scolor = [NSColor whiteColor]; 444 bpath = [NSBezierPath bezierPath]; 445 [bpath setLineWidth: 1]; 446 [bpath moveToPoint: selp[1]]; 447 [bpath lineToPoint: NSMakePoint(s.width, aRect.size.height)]; 448 [scolor set]; 449 [bpath stroke]; 450 } 451} 452 453- (BOOL)isOpaque 454{ 455 return YES; 456} 457 458- (TShelfViewItem *)tabItemAtPoint:(NSPoint)point 459{ 460 NSUInteger count = [items count]; 461 NSUInteger i; 462 463 point = [self convertPoint: point fromView: nil]; 464 465 for (i = 0; i < count; i++) { 466 TShelfViewItem *anItem = [items objectAtIndex: i]; 467 468 if (NSPointInRect(point, [anItem tabRect])) { 469 return anItem; 470 } 471 } 472 473 return nil; 474} 475 476- (TShelfViewItem *)lastTabItem 477{ 478 return lastItem; 479} 480 481- (NSArray *)items 482{ 483 return items; 484} 485 486- (void)buttonsAction:(id)sender 487{ 488 489} 490 491- (void)setButtonsEnabled:(BOOL)enabled 492{ 493 [rewButt setEnabled: enabled]; 494 [ffButt setEnabled: enabled]; 495 496 if (enabled) { 497 [rewButt setImage: [NSImage imageNamed: @"REWArrow.tiff"]]; 498 [ffButt setImage: [NSImage imageNamed: @"FFArrow.tiff"]]; 499 } else { 500 [rewButt setImage: [NSImage imageNamed: @"REWArrow_disabled.tiff"]]; 501 [ffButt setImage: [NSImage imageNamed: @"FFArrow_disabled.tiff"]]; 502 } 503} 504 505- (void)mouseDown:(NSEvent *)theEvent 506{ 507 NSPoint location = [theEvent locationInWindow]; 508 TShelfViewItem *anItem = [self tabItemAtPoint: location]; 509 510 if (anItem && (anItem != selected)) { 511 [self selectTabItem: anItem]; 512 } 513} 514 515- (BOOL)acceptsFirstResponder 516{ 517 return YES; 518} 519 520- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent 521{ 522 return YES; 523} 524 525@end 526