/* ** CriterionObjectView.m ** ** Copyright (c) 2004 ** ** Author: Yen-Ju Chen ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "CriterionObjectView.h" #include "CriterionView.h" #include "Constants.h" #ifdef GNUSTEP static id clickedPopUpCell = nil; #endif #define CellSpace 3 @implementation CriterionObjectView - (NSString *) _stringFromCriterionDateUnit: (CriterionDateUnit) unit { switch (unit) { case CriterionSecondUnit: return sCriterionSecondUnit; case CriterionMinuteUnit: return sCriterionMinuteUnit; case CriterionHourUnit: return sCriterionHourUnit; case CriterionDayUnit: return sCriterionDayUnit; case CriterionWeekUnit: return sCriterionWeekUnit; case CriterionMonthUnit: return sCriterionMonthUnit; case CriterionYearUnit: return sCriterionYearUnit; } return nil; } - (CriterionDateUnit) _criterionDateUnitFromString: (NSString *) string { if ([string isEqualToString: sCriterionSecondUnit]) return CriterionSecondUnit; else if ([string isEqualToString: sCriterionMinuteUnit]) return CriterionMinuteUnit; else if ([string isEqualToString: sCriterionHourUnit]) return CriterionHourUnit; else if ([string isEqualToString: sCriterionDayUnit]) return CriterionDayUnit; else if ([string isEqualToString: sCriterionWeekUnit]) return CriterionWeekUnit; else if ([string isEqualToString: sCriterionMonthUnit]) return CriterionMonthUnit; else if ([string isEqualToString: sCriterionYearUnit]) return CriterionYearUnit; else return CriterionErrorUnit; } - (NSRect) _frameOfToTextFieldCell { NSRect bounds = [self bounds]; NSSize size = [toTextFieldCell cellSize]; float text_width = (bounds.size.width-size.width)/2; return NSMakeRect(text_width, 0, size.width, size.height); } - (NSRect) _frameOfUnitPopUpCell { NSRect bounds = [self bounds]; float button_width, button_height; button_width = [unitPopUpCell cellSize].width; button_height = [unitPopUpCell cellSize].height; if (unitPopUpCellWidth < button_width) unitPopUpCellWidth = button_width; return NSMakeRect(bounds.size.width-unitPopUpCellWidth, -1, unitPopUpCellWidth, button_height); } - (NSRect) _frameOfSelectionPopUpCell { NSRect bounds = [self bounds]; float button_height, button_width; button_height = [selectionPopUpCell cellSize].height; //button_width = bounds.size.width; button_width = [selectionPopUpCell cellSize].width; return NSMakeRect(0, -1, button_width, button_height); } - (void) controlTextDidEndEditing: (NSNotification *) not { //NSLog(@"controlTextDidEndEditing"); id sender = [not object]; [self controlAction: sender]; } - (void) controlAction: (id) sender { //NSLog(@"controlAction"); [target performSelector: selector withObject: self]; } - (void) setObjectValue: (id) o { NSString *unit; id object = AUTORELEASE([o copy]); //NSLog(@"CriterionObjectView: set %@", o); if ([object isKindOfClass: [NSArray class]] == NO) { switch(type) { case CriterionObjectViewTextFieldType: [textField setObjectValue: object]; break; case CriterionObjectViewIsSelectionType: [selectionPopUpCell selectItemWithTitle: object]; break; } } else { if ([object count] < 1) return; [textField setObjectValue: [object objectAtIndex: 0]]; switch(type) { case CriterionObjectViewInTheRangeType: [toField setObjectValue: [object lastObject]]; break; case CriterionObjectViewInTheLastType: unit = [self _stringFromCriterionDateUnit: [[object lastObject] intValue]]; if (unit != nil) [unitPopUpCell selectItemWithTitle: unit]; break; } } } /* return nil if textField is empty */ - (id) objectValue { switch(type) { case CriterionObjectViewTextFieldType: { return AUTORELEASE([[textField stringValue] copy]); } case CriterionObjectViewInTheRangeType: { NSArray *array = [NSArray arrayWithObjects: AUTORELEASE([[textField stringValue] copy]), AUTORELEASE([[toField stringValue] copy]), nil]; return array; } case CriterionObjectViewInTheLastType: { NSString *title = [unitPopUpCell titleOfSelectedItem]; CriterionDateUnit unit = [self _criterionDateUnitFromString: title]; NSArray *array = [NSArray arrayWithObjects: AUTORELEASE([[textField stringValue] copy]), [NSNumber numberWithInt: unit], nil]; return array; } case CriterionObjectViewIsSelectionType: { return AUTORELEASE([[selectionPopUpCell titleOfSelectedItem] copy]); } } } - (void) setSelectionPopUpButtonTitles: (NSArray *) titles { unsigned int index; NSString *title; [selectionPopUpCell removeAllItems]; if (([titles count] < 1) || (titles == nil)) return; [selectionPopUpCell addItemsWithTitles: AUTORELEASE([titles copy])]; title = [selectionPopUpCell titleOfSelectedItem]; if (title) index = [selectionPopUpCell indexOfItemWithTitle: title]; else index = 0; if (index != NSNotFound) [selectionPopUpCell selectItemAtIndex: index]; else [selectionPopUpCell selectItemAtIndex: 0]; [selectionPopUpCell synchronizeTitleAndSelectedItem]; } - (void) setFrameSize: (NSSize) size { float text_width, button_width; NSRect rect; switch(type) { case CriterionObjectViewTextFieldType: { [textField setFrameSize: size]; break; } case CriterionObjectViewInTheRangeType: { NSSize cellSize = [self _frameOfToTextFieldCell].size; text_width = (size.width-cellSize.width)/2; [textField setFrameSize: NSMakeSize(text_width-CellSpace, size.height)]; rect = NSMakeRect(text_width+cellSize.width+CellSpace, 0, text_width-CellSpace, size.height); [toField setFrame: rect]; break; } case CriterionObjectViewInTheLastType: { button_width = [self _frameOfUnitPopUpCell].size.width; [textField setFrameSize: NSMakeSize(size.width-button_width-CellSpace, size.height)]; break; } } [super setFrameSize: size]; } - (void) setType: (CriterionObjectViewType) t { NSRect frame = [self bounds]; NSRect rect; float text_width, button_width; if (type != t) { type = t; switch(type) { case CriterionObjectViewTextFieldType: { /* Remove others */ if ([toField superview]) [toField removeFromSuperviewWithoutNeedingDisplay]; [textField setFrame: frame]; if ([textField superview] == nil) [self addSubview: textField]; break; } case CriterionObjectViewInTheRangeType: { /* Remove others */ NSSize cellSize = [self _frameOfToTextFieldCell].size; text_width = (frame.size.width-cellSize.width)/2; rect = NSMakeRect(0, 0, text_width-CellSpace, frame.size.height); [textField setFrame: rect]; rect = NSMakeRect(text_width+cellSize.width+CellSpace, 0, text_width-CellSpace, frame.size.height); [toField setFrame: rect]; if ([textField superview] == nil) [self addSubview: textField]; if ([toField superview] == nil) [self addSubview: toField]; break; } case CriterionObjectViewInTheLastType: { /* Remove others */ if ([toField superview]) [toField removeFromSuperviewWithoutNeedingDisplay]; button_width = [self _frameOfUnitPopUpCell].size.width; rect = NSMakeRect(0, 0, frame.size.width-button_width-CellSpace, frame.size.height); [textField setFrame: rect]; if ([textField superview] == nil) [self addSubview: textField]; break; } case CriterionObjectViewIsSelectionType: { /* Remove others */ if ([textField superview]) [textField removeFromSuperviewWithoutNeedingDisplay]; if ([toField superview]) [toField removeFromSuperviewWithoutNeedingDisplay]; break; } } [self display]; } } #ifdef GNUSTEP - (void) _handleNotification: (NSNotification*) not { NSString *name = [not name]; if ([name isEqual: NSMenuDidSendActionNotification] == YES) { [clickedPopUpCell dismissPopUp]; [clickedPopUpCell synchronizeTitleAndSelectedItem]; [self setNeedsDisplay: YES]; } } #endif - (void) mouseDown: (NSEvent *) event { NSPoint initialLocation = [event locationInWindow]; NSPoint p = [self convertPoint: initialLocation fromView: nil]; NSRect rect, bounds = [self bounds]; switch(type) { case CriterionObjectViewInTheLastType: { rect = [self _frameOfUnitPopUpCell]; if (NSMouseInRect(p, rect, YES)) { #ifdef GNUSTEP clickedPopUpCell = unitPopUpCell;; [unitPopUpCell attachPopUpWithFrame: rect inView: self]; NSWindow *menuWindow = [[[unitPopUpCell menu] menuRepresentation] window]; NSPoint p = [menuWindow convertScreenToBase: [[self window] convertBaseToScreen: [event locationInWindow]]]; NSEvent *e = [NSEvent mouseEventWithType: [event type] location: p modifierFlags: [event modifierFlags] timestamp: [event timestamp] windowNumber: [menuWindow windowNumber] context: [event context] eventNumber: [event eventNumber] clickCount: [event clickCount] pressure: [event pressure]]; [NSApp sendEvent: e]; #else BOOL result = [unitPopUpCell trackMouse: event inRect: rect ofView: self untilMouseUp: YES]; #endif /* cell size change with title * recalculate its size */ rect = [self _frameOfUnitPopUpCell]; rect = NSMakeRect(0, 0, bounds.size.width-rect.size.width-CellSpace, bounds.size.height); [textField setFrame: rect]; [self display]; [self controlAction: self]; break; } } case CriterionObjectViewIsSelectionType: { rect = [self _frameOfSelectionPopUpCell]; if (NSMouseInRect(p, rect, YES)) { #ifdef GNUSTEP clickedPopUpCell = selectionPopUpCell; [selectionPopUpCell attachPopUpWithFrame: rect inView: self]; NSWindow *menuWindow = [[[selectionPopUpCell menu] menuRepresentation] window]; NSPoint p = [menuWindow convertScreenToBase: [[self window] convertBaseToScreen: [event locationInWindow]]]; NSEvent *e = [NSEvent mouseEventWithType: [event type] location: p modifierFlags: [event modifierFlags] timestamp: [event timestamp] windowNumber: [menuWindow windowNumber] context: [event context] eventNumber: [event eventNumber] clickCount: [event clickCount] pressure: [event pressure]]; [NSApp sendEvent: e]; #else BOOL result = [selectionPopUpCell trackMouse: event inRect: rect ofView: self untilMouseUp: YES]; #endif [self display]; [self controlAction: self]; break; } } default: [super mouseDown: event]; } } - (void) drawRect: (NSRect) frame { [super drawRect: frame]; float button_width, button_height; NSRect rect, bounds = [self bounds]; switch(type) { case CriterionObjectViewInTheRangeType: { rect = [self _frameOfToTextFieldCell]; [self lockFocus]; [toTextFieldCell drawWithFrame: rect inView: self]; [self unlockFocus]; } case CriterionObjectViewInTheLastType: { rect = [self _frameOfUnitPopUpCell]; [self lockFocus]; [unitPopUpCell drawWithFrame: rect inView: self]; [self unlockFocus]; break; } case CriterionObjectViewIsSelectionType: { rect = [self _frameOfSelectionPopUpCell]; [self lockFocus]; [selectionPopUpCell drawWithFrame: rect inView: self]; [self unlockFocus]; break; } } } - (CriterionObjectViewType) type { return type; } - (id) initWithFrame: (NSRect) frame { NSRect bounds; self = [super initWithFrame: frame]; bounds = [self bounds]; type = CriterionObjectViewTextFieldType; textField = [[NSTextField alloc] initWithFrame: bounds]; [textField setTarget: self]; [textField setAction: @selector(controlAction:)]; [textField setDelegate: self]; toField = [[NSTextField alloc] initWithFrame: bounds]; [toField setTarget: self]; [toField setAction: @selector(controlAction:)]; [toField setDelegate: self]; toTextFieldCell = [[NSTextFieldCell alloc] initTextCell: sTo]; unitPopUpCell = [[NSPopUpButtonCell alloc] initTextCell: @"" pullsDown: NO]; [unitPopUpCell addItemWithTitle: sCriterionSecondUnit]; [unitPopUpCell addItemWithTitle: sCriterionMinuteUnit]; [unitPopUpCell addItemWithTitle: sCriterionHourUnit]; [unitPopUpCell addItemWithTitle: sCriterionDayUnit]; [unitPopUpCell addItemWithTitle: sCriterionWeekUnit]; [unitPopUpCell addItemWithTitle: sCriterionMonthUnit]; [unitPopUpCell addItemWithTitle: sCriterionYearUnit]; [unitPopUpCell selectItemWithTitle: sCriterionDayUnit]; selectionPopUpCell = [[NSPopUpButtonCell alloc] initTextCell: @"" pullsDown: NO]; [self addSubview: textField]; isSmallControlSize = NO; unitPopUpCellWidth = 0; return self; } - (void) dealloc { RELEASE(textField); RELEASE(toField); RELEASE(toTextFieldCell); RELEASE(unitPopUpCell); RELEASE(selectionPopUpCell); [super dealloc]; } - (void) setAction: (SEL) s { selector = s; } - (SEL) selector { return selector; } - (void) setTarget: (id) t { ASSIGN(target, t); } - (id) target { return target; } - (void) setSmallControlSize: (BOOL) flag { float font_size; NSFont *controlFont; isSmallControlSize = flag; if (isSmallControlSize) { font_size = [NSFont smallSystemFontSize]; [unitPopUpCell setControlSize: NSSmallControlSize]; [selectionPopUpCell setControlSize: NSSmallControlSize]; } else { font_size = [NSFont systemFontSize]; [unitPopUpCell setControlSize: NSRegularControlSize]; [selectionPopUpCell setControlSize: NSRegularControlSize]; } controlFont = [NSFont controlContentFontOfSize: font_size]; [textField setFont: controlFont]; [toField setFont: controlFont]; [toTextFieldCell setFont: controlFont]; [unitPopUpCell setFont: controlFont]; [selectionPopUpCell setFont: controlFont]; } - (BOOL) isSmallControlSize { return isSmallControlSize; } - (BOOL) isFlipped { return YES; } @end