diff options
author | Scott Kovatch | 2010-11-02 18:53:54 +0000 |
---|---|---|
committer | Scott Kovatch | 2010-11-02 18:53:54 +0000 |
commit | e72e9087ac8af1d51d4e6e0c8ad970934acd8882 (patch) | |
tree | 8f910a6a71e100af147b4c396ffea17811f8bde7 | |
parent | e379287ec5e166c277b3a4f8df3f70c1e5720d36 (diff) | |
download | eclipse.platform.swt-e72e9087ac8af1d51d4e6e0c8ad970934acd8882.tar.gz eclipse.platform.swt-e72e9087ac8af1d51d4e6e0c8ad970934acd8882.tar.xz eclipse.platform.swt-e72e9087ac8af1d51d4e6e0c8ad970934acd8882.zip |
227638 - implement DROP_DOWN for the date picker.
6 files changed, 231 insertions, 3 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras index cfb06f2049..e80d35512b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras @@ -1173,6 +1173,10 @@ <arg swt_gen="true"></arg> <retval swt_gen="true"></retval> </method> + <method selector="setBordered:" swt_gen="true"> + <arg swt_gen="true"></arg> + <retval swt_gen="true"></retval> + </method> <method selector="setDatePickerElements:" swt_gen="true"> <arg swt_gen="true"></arg> <retval swt_gen="true"></retval> @@ -4604,6 +4608,7 @@ <enum name="NSLineBreakByTruncatingTail" swt_gen="true"></enum> <enum name="NSLineBreakByWordWrapping" swt_gen="true"></enum> <enum name="NSLineToBezierPathElement" swt_gen="true"></enum> + <enum name="NSMiniControlSize" swt_gen="true"></enum> <enum name="NSMiniaturizableWindowMask" swt_gen="true"></enum> <enum name="NSMiterLineJoinStyle" swt_gen="true"></enum> <enum name="NSMixedState" swt_gen="true"></enum> @@ -4650,6 +4655,7 @@ <enum name="NSRoundLineCapStyle" swt_gen="true"></enum> <enum name="NSRoundLineJoinStyle" swt_gen="true"></enum> <enum name="NSRoundedBezelStyle" swt_gen="true"></enum> + <enum name="NSRoundedDisclosureBezelStyle" swt_gen="true"></enum> <enum name="NSScaleNone" swt_gen="true"></enum> <enum name="NSScrollWheel" swt_gen="true"></enum> <enum name="NSScrollerDecrementLine" swt_gen="true"></enum> @@ -4677,6 +4683,7 @@ <enum name="NSTerminateCancel" swt_gen="true"></enum> <enum name="NSTerminateNow" swt_gen="true"></enum> <enum name="NSTextFieldAndStepperDatePickerStyle" swt_gen="true"></enum> + <enum name="NSTextFieldDatePickerStyle" swt_gen="true"></enum> <enum name="NSTitledWindowMask" swt_gen="true"></enum> <enum name="NSToolbarDisplayModeIconOnly" swt_gen="true"></enum> <enum name="NSUnderlineStyleDouble" swt_gen="true"></enum> diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSDatePicker.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSDatePicker.java index e64ffb4c52..42391c774a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSDatePicker.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSDatePicker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -33,6 +33,10 @@ public void setBackgroundColor(NSColor color) { OS.objc_msgSend(this.id, OS.sel_setBackgroundColor_, color != null ? color.id : 0); } +public void setBordered(boolean flag) { + OS.objc_msgSend(this.id, OS.sel_setBordered_, flag); +} + public void setDatePickerElements(int /*long*/ elementFlags) { OS.objc_msgSend(this.id, OS.sel_setDatePickerElements_, elementFlags); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index 5e23fd5770..9986e08997 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -2209,6 +2209,7 @@ public static final int NSLineBreakByTruncatingMiddle = 5; public static final int NSLineBreakByTruncatingTail = 4; public static final int NSLineBreakByWordWrapping = 0; public static final int NSLineToBezierPathElement = 1; +public static final int NSMiniControlSize = 2; public static final int NSMiniaturizableWindowMask = 4; public static final int NSMiterLineJoinStyle = 0; public static final int NSMixedState = -1; @@ -2255,6 +2256,7 @@ public static final int NSRightTextAlignment = 1; public static final int NSRoundLineCapStyle = 1; public static final int NSRoundLineJoinStyle = 1; public static final int NSRoundedBezelStyle = 1; +public static final int NSRoundedDisclosureBezelStyle = 14; public static final int NSScaleNone = 2; public static final int NSScrollWheel = 22; public static final int NSScrollerDecrementLine = 4; @@ -2282,6 +2284,7 @@ public static final int NSTableViewSolidVerticalGridLineMask = 1; public static final int NSTerminateCancel = 0; public static final int NSTerminateNow = 1; public static final int NSTextFieldAndStepperDatePickerStyle = 0; +public static final int NSTextFieldDatePickerStyle = 2; public static final int NSTitledWindowMask = 1; public static final int NSToolbarDisplayModeIconOnly = 2; public static final int NSUnderlineStyleDouble = 9; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/DateTime.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/DateTime.java index 24115d2f90..dfc220e8a1 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/DateTime.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/DateTime.java @@ -48,6 +48,13 @@ public class DateTime extends Composite { static final int MIN_YEAR = 1752; // Gregorian switchover in North America: September 19, 1752 static final int MAX_YEAR = 9999; + /* Emulated DROP_DOWN calendar fields for DATE */ + NSButton buttonView; + Shell popupShell; + DateTime popupCalendar; + boolean popupWasShowing; + int savedYear, savedMonth, savedDay; + /** * Constructs a new instance of this class given its parent * and a style value describing its behavior and appearance. @@ -96,6 +103,7 @@ static int checkStyle (int style) { */ style &= ~(SWT.H_SCROLL | SWT.V_SCROLL); style = checkBits (style, SWT.MEDIUM, SWT.SHORT, SWT.LONG, 0, 0, 0); + if ((style & SWT.DATE) == 0) style &=~ SWT.DROP_DOWN; return checkBits (style, SWT.DATE, SWT.TIME, SWT.CALENDAR, 0, 0, 0); } @@ -142,6 +150,11 @@ public Point computeSize (int wHint, int hHint, boolean changed) { NSSize size = widget.cell ().cellSize (); width = (int)Math.ceil (size.width); height = (int)Math.ceil (size.height); + if ((style & SWT.DROP_DOWN) != 0) { + size = buttonView.cell ().cellSize (); + width += (int)Math.ceil (size.width) - getBezelSize() * 2; + height = Math.max(height, (int)Math.ceil (size.height)); + } if (width == 0) width = DEFAULT_WIDTH; if (height == 0) height = DEFAULT_HEIGHT; if (wHint != SWT.DEFAULT) width = wHint; @@ -154,7 +167,7 @@ public Point computeSize (int wHint, int hHint, boolean changed) { void createHandle () { NSDatePicker widget = (NSDatePicker)new SWTDatePicker().alloc(); widget.init(); - int pickerStyle = OS.NSTextFieldAndStepperDatePickerStyle; + int pickerStyle = (style & SWT.DROP_DOWN) != 0 ? OS.NSTextFieldDatePickerStyle : OS.NSTextFieldAndStepperDatePickerStyle; int elementFlags = 0; if ((style & SWT.CALENDAR) != 0) { pickerStyle = OS.NSClockAndCalendarDatePickerStyle; @@ -167,6 +180,7 @@ void createHandle () { elementFlags = (style & SWT.SHORT) != 0 ? OS.NSYearMonthDatePickerElementFlag : OS.NSYearMonthDayDatePickerElementFlag; } } + widget.setBordered((style & SWT.BORDER) != 0); widget.setDrawsBackground(true); widget.setDatePickerStyle(pickerStyle); widget.setDatePickerElements(elementFlags); @@ -175,22 +189,144 @@ void createHandle () { widget.setTarget(widget); widget.setAction(OS.sel_sendSelection); view = widget; + + if ((this.style & SWT.DROP_DOWN) != 0) { + NSButton buttonWidget = (NSButton)new SWTButton().alloc(); + buttonWidget.init(); + buttonWidget.setButtonType(OS.NSMomentaryLightButton); + buttonWidget.setBezelStyle(OS.NSRoundedDisclosureBezelStyle); + buttonWidget.setFocusRingType(OS.NSFocusRingTypeNone); + buttonWidget.setTitle(NSString.stringWith("")); + buttonWidget.setImagePosition(OS.NSNoImage); + buttonWidget.setTarget(view); + buttonWidget.setAction(OS.sel_sendVerticalSelection); + view.addSubview(buttonWidget); + buttonView = buttonWidget; + + createPopupShell(-1, -1, -1); + } +} + +void createPopupShell(int year, int month, int day) { + popupShell = new Shell (getShell (), SWT.NO_TRIM | SWT.ON_TOP); + popupShell.isPopup = true; + popupShell.window.setHasShadow(true); + popupCalendar = new DateTime (popupShell, SWT.CALENDAR); + if (font != null) popupCalendar.setFont (font); + + popupCalendar.addListener (SWT.Selection, new Listener() { + public void handleEvent(Event event) { + int year = popupCalendar.getYear (); + int month = popupCalendar.getMonth (); + int day = popupCalendar.getDay (); + setDate(year, month, day); + Event e = new Event (); + e.time = event.time; + notifyListeners (SWT.Selection, e); + hideCalendar(); + } + }); + + addListener (SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + if (popupShell != null && !popupShell.isDisposed ()) { + disposePopupShell(); + } + } + }); + addListener(SWT.FocusOut, new Listener() { + public void handleEvent(Event event) { + popupWasShowing = (popupShell != null && popupShell.isVisible()); + hideCalendar(); + } + }); + addListener(SWT.FocusIn, new Listener() { + public void handleEvent(Event event) { + if (popupWasShowing) showCalendar(); + } + }); + + if (year != -1) popupCalendar.setDate(year, month, day); } NSFont defaultNSFont() { return display.datePickerFont; } +void deregister() { + super.deregister(); + if (buttonView != null) { + display.removeWidget(buttonView); + display.removeWidget(buttonView.cell()); + } + +} + +void disposePopupShell() { + popupShell.dispose (); + popupShell = null; + popupCalendar = null; +} + void drawBackground (int /*long*/ id, NSGraphicsContext context, NSRect rect) { if (id != view.id) return; fillBackground (view, context, rect, -1); } +void showCalendar() { + if (isDropped ()) return; + savedYear = getYear (); + savedMonth = getMonth (); + savedDay = getDay (); + if (getShell() != popupShell.getParent ()) { + disposePopupShell(); + createPopupShell (savedYear, savedMonth, savedDay); + } + Point dateBounds = getSize (); + Point calendarSize = popupCalendar.computeSize (SWT.DEFAULT, SWT.DEFAULT, false); + popupCalendar.setBounds (1, 1, Math.max (dateBounds.x - 2, calendarSize.x), calendarSize.y); + popupCalendar.setDate(savedYear, savedMonth, savedDay); + Rectangle parentRect = display.map (getParent (), null, getBounds ()); + Rectangle displayRect = getMonitor ().getClientArea (); + int width = Math.max (dateBounds.x, calendarSize.x + 2); + int height = calendarSize.y + 2; + int x = parentRect.x; + int y = parentRect.y + dateBounds.y; + if (y + height > displayRect.y + displayRect.height) y = parentRect.y - height; + if (x + width > displayRect.x + displayRect.width) x = displayRect.x + displayRect.width - calendarSize.x; + popupShell.setBounds (x, y, width, height); + popupShell.setVisible (true); + if (isFocusControl()) popupCalendar.setFocus (); +} + +void hideCalendar() { + if (!isDropped ()) return; + popupShell.setVisible (false); + if (!isDisposed () && isFocusControl()) { + setFocus(); + } +} + +int getBezelInset() { + //TODO: Determine this value from the system instead of using constants + return (buttonView.cell ().controlSize () == OS.NSMiniControlSize) ? 3 : 1; +} + +int getBezelSize() { + //TODO: Determine this value from the system instead of using constants + return (buttonView.cell ().controlSize () == OS.NSMiniControlSize) ? 6 : 4; +} + NSCalendarDate getCalendarDate () { NSDate date = ((NSDatePicker)view).dateValue(); return date.dateWithCalendarFormat(null, null); } +public Control [] getChildren () { + checkWidget(); + return new Control [0]; +} + /** * Returns the receiver's date, or day of the month. * <p> @@ -304,6 +440,10 @@ public int getYear () { return (int)/*64*/getCalendarDate().yearOfCommonEra(); } +boolean isDropped () { + return popupShell.getVisible (); +} + boolean isEventView (int /*long*/ id) { return true; } @@ -313,6 +453,52 @@ boolean isFlipped (int /*long*/ id, int /*long*/ sel) { return true; } +void keyDown(int /*long*/ id, int /*long*/ sel, int /*long*/ theEvent) { + if ((style & SWT.DROP_DOWN) != 0) { + NSEvent nsEvent = new NSEvent (theEvent); + int keyCode = Display.translateKey (nsEvent.keyCode ()); + boolean alt = (nsEvent.modifierFlags() & OS.NSAlternateKeyMask) != 0; + if (alt && (keyCode == SWT.ARROW_UP || keyCode == SWT.ARROW_DOWN)) { + if (isDropped ()) { + hideCalendar(); + } else { + showCalendar(); + } + return; + } + if (keyCode == SWT.ESC) { + /* Escape key cancels popupCalendar and reverts date */ + popupCalendar.setDate (savedYear, savedMonth, savedDay); + setDate(savedYear, savedMonth, savedDay); + hideCalendar(); + return; + } + } + super.keyDown(id, sel, theEvent); + + if ((style & SWT.DROP_DOWN) != 0 && popupCalendar != null) { + // Re-sync the calendar to the current date in the field. + int month = getMonth(); + int day = getDay(); + int year = getYear(); + popupCalendar.setDate(year, month, day); + } +} + +void register () { + super.register (); + if (buttonView != null) { + display.addWidget (buttonView, this); + display.addWidget (buttonView.cell(), this); + } +} + +void releaseHandle () { + super.releaseHandle (); + if (buttonView != null) buttonView.release(); + buttonView = null; +} + /** * Removes the listener from the collection of listeners who will * be notified when the control is selected by the user. @@ -338,6 +524,18 @@ public void removeSelectionListener (SelectionListener listener) { eventTable.unhook (SWT.DefaultSelection, listener); } +void resized () { + super.resized (); + if (buttonView == null) return; + NSSize buttonSize = buttonView.cell ().cellSize (); + NSRect rect = view.bounds(); + rect.x = rect.width - buttonSize.width + getBezelSize(); + rect.y = - getBezelInset(); + rect.width = buttonSize.width; + rect.height = buttonSize.height; + buttonView.setFrame(rect); +} + boolean sendKeyEvent (NSEvent nsEvent, int type) { boolean result = super.sendKeyEvent (nsEvent, type); if (!result) return result; @@ -347,6 +545,7 @@ boolean sendKeyEvent (NSEvent nsEvent, int type) { switch (keyCode) { case 76: /* KP Enter */ case 36: /* Return */ + hideCalendar(); sendSelectionEvent (SWT.DefaultSelection); } } @@ -366,6 +565,15 @@ void sendSelection () { } } +/* Drop-down arrow button has been pressed. */ +void sendVerticalSelection () { + if (isDropped ()) { + hideCalendar(); + } else { + showCalendar(); + } +} + void setBackgroundColor(NSColor nsColor) { ((NSDatePicker)view).setBackgroundColor(nsColor); } @@ -535,6 +743,10 @@ public void setSeconds (int seconds) { ((NSDatePicker)view).setDateValue(newDate); } +void setSmallSize () { + if (buttonView != null) buttonView.cell ().setControlSize (OS.NSMiniControlSize); +} + /** * Sets the receiver's hours, minutes, and seconds in a single operation. * diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java index 98c8c1ce50..0357874a61 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java @@ -2359,6 +2359,7 @@ void initClasses () { OS.class_addIvar(cls, SWT_OBJECT, size, (byte)align, types); OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:"); OS.class_addMethod(cls, OS.sel_sendSelection, proc2, "@:"); + OS.class_addMethod(cls, OS.sel_sendVerticalSelection, proc2, "@:"); addEventMethods(cls, proc2, proc3, drawRectProc, hitTestProc, setNeedsDisplayInRectProc); addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc); addAccessibilityMethods(cls, proc2, proc3, proc4, accessibilityHitTestProc); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java index fd65e87c95..49cbd8a37b 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java @@ -119,7 +119,7 @@ public class Shell extends Decorations { SWTWindowDelegate windowDelegate; int /*long*/ currWindowClass; int /*long*/ tooltipOwner, tooltipTag, tooltipUserData; - boolean opened, moved, resized, fullScreen, center, deferFlushing; + boolean opened, moved, resized, fullScreen, center, deferFlushing, isPopup; Control lastActive; Rectangle normalBounds; boolean keyInputHappened; @@ -503,6 +503,7 @@ void bringToTop (boolean force) { } boolean canBecomeKeyWindow (int /*long*/ id, int /*long*/ sel) { + if (isPopup) return false; // Only answer if SWT created the window. if (window != null) if (window.styleMask () == OS.NSBorderlessWindowMask) return true; return super.canBecomeKeyWindow (id, sel); |