Drop-down mostly working in Cocoa
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSCell.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSCell.java
index a846080..a8ba599 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSCell.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSCell.java
@@ -36,6 +36,10 @@
return result;
}
+public int /*long*/ controlSize() {
+ return OS.objc_msgSend(this.id, OS.sel_controlSize);
+}
+
public void drawInteriorWithFrame(NSRect cellFrame, NSView controlView) {
OS.objc_msgSend(this.id, OS.sel_drawInteriorWithFrame_inView_, cellFrame, controlView != null ? controlView.id : 0);
}
@@ -115,5 +119,4 @@
public boolean wraps() {
return OS.objc_msgSend_bool(this.id, OS.sel_wraps);
}
-
}
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 60715d3..d76261c 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,11 +48,11 @@
/* Emulated DROP_DOWN calendar fields for DATE */
NSButton buttonView;
- boolean hasFocus;
- int savedYear, savedMonth, savedDay;
Shell popupShell;
- DateTime popupCalendar, popupOwner;
+ DateTime popupCalendar;
Listener popupListener, popupFilter;
+ boolean popupHasFocus;
+ int savedYear, savedMonth, savedDay;
/**
* Constructs a new instance of this class given its parent
@@ -141,18 +141,17 @@
public Point computeSize (int wHint, int hHint, boolean changed) {
checkWidget ();
int width = 0, height = 0;
- NSControl widget = (NSControl)view; //TODO: Ask SSQ why cast? The call to cell() works fine on view
+ NSControl widget = (NSControl)view;
NSSize size = widget.cell ().cellSize ();
width = (int)Math.ceil (size.width);
height = (int)Math.ceil (size.height);
- if (width == 0) width = DEFAULT_WIDTH;
- if (height == 0) height = DEFAULT_HEIGHT;
if ((style & SWT.DROP_DOWN) != 0) {
- widget = (NSControl)buttonView;
- size = widget.cell ().cellSize ();
- width += (int)Math.ceil (size.width) - 8;
+ 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;
if (hHint != SWT.DEFAULT) height = hHint;
int border = getBorderWidth ();
@@ -205,7 +204,6 @@
void createPopupShell(int year, int month, int day) {
popupShell = new Shell (getShell (), SWT.NO_TRIM | SWT.ON_TOP);
popupCalendar = new DateTime (popupShell, SWT.CALENDAR);
- popupCalendar.popupOwner = this;
if (font != null) popupCalendar.setFont (font);
popupListener = new Listener () {
@@ -218,12 +216,8 @@
popupCalendarEvent (event);
return;
}
- if (event.widget == DateTime.this) {
- dateTimeEvent (event);
- return;
- }
if (event.widget == getShell ()) {
- getDisplay().asyncExec(new Runnable() {
+ display.asyncExec(new Runnable() {
public void run() {
if (isDisposed()) return;
popupCalendarFocus (SWT.FocusOut);
@@ -245,44 +239,22 @@
for (int i=0; i < listeners.length; i++) {
popupShell.addListener (listeners [i], popupListener);
}
- listeners = new int [] {SWT.MouseUp, SWT.Selection, SWT.Traverse, SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.Dispose};
+ listeners = new int [] {SWT.Selection, SWT.Traverse, SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.Dispose};
for (int i=0; i < listeners.length; i++) {
popupCalendar.addListener (listeners [i], popupListener);
}
-
- if (year != -1) popupCalendar.setDate(year, month, day);
-}
-
-void dateTimeEvent (Event event) {
- switch (event.type) {
- case SWT.Dispose:
+ addListener (SWT.Dispose, new Listener() {
+ public void handleEvent(Event event) {
if (popupShell != null && !popupShell.isDisposed ()) {
- popupCalendar.removeListener (SWT.Dispose, popupListener);
- popupShell.dispose ();
+ disposePopupShell();
}
Shell shell = getShell ();
shell.removeListener (SWT.Deactivate, popupListener);
- Display display = getDisplay ();
display.removeFilter (SWT.FocusIn, popupFilter);
- popupShell = null;
- popupCalendar = null;
- break;
- case SWT.FocusIn:
- Control focusControl = getDisplay ().getFocusControl ();
- if (focusControl == popupCalendar) return;
- if (isDropped()) {
- popupCalendar.setFocus();
- } else {
- setFocus();
- }
- break;
- case SWT.Move:
- dropDownCalendar (false);
- break;
-// case SWT.Resize:
-// internalLayout (false);
-// break;
- }
+ }
+ });
+
+ if (year != -1) popupCalendar.setDate(year, month, day);
}
NSFont defaultNSFont() {
@@ -298,39 +270,26 @@
}
-void dropDownCalendar(boolean drop) {
- if (drop == isDropped ()) return;
- if (!drop) {
- popupShell.setVisible (false);
- if (!isDisposed () && isFocusControl()) {
- setFocus();
- }
- return;
- }
+void disposePopupShell() {
+ popupCalendar.removeListener (SWT.Dispose, popupListener);
+ popupShell.dispose ();
+ popupShell = null;
+ popupCalendar = null;
+}
+void showCalendar() {
+ if (isDropped ()) return;
savedYear = getYear ();
savedMonth = getMonth ();
savedDay = getDay ();
if (getShell() != popupShell.getParent ()) {
- int year = popupCalendar.getYear ();
- int month = popupCalendar.getMonth ();
- int day = popupCalendar.getDay ();
- popupCalendar.removeListener (SWT.Dispose, popupListener);
- popupShell.dispose();
- popupShell = null;
- popupCalendar = null;
- createPopupShell (year, month, day);
+ 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);
-
- int year = popupCalendar.getYear ();
- int month = popupCalendar.getMonth ();
- int day = popupCalendar.getDay ();
- popupCalendar.setDate(year, month, day);
- Display display = getDisplay ();
+ 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);
@@ -344,11 +303,34 @@
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>
@@ -470,6 +452,23 @@
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;
+ }
+ }
+ super.keyDown(id, sel, theEvent);
+}
+
void popupCalendarEvent (Event event) {
switch (event.type) {
case SWT.Dispose:
@@ -486,11 +485,6 @@
popupCalendarFocus (SWT.FocusIn);
break;
}
- case SWT.MouseUp: {
- if (event.button != 1) return;
- dropDownCalendar (false);
- break;
- }
case SWT.Selection: {
int year = popupCalendar.getYear ();
int month = popupCalendar.getMonth ();
@@ -498,25 +492,24 @@
setDate(year, month, day);
Event e = new Event ();
e.time = event.time;
- e.stateMask = event.stateMask;
- e.doit = event.doit;
notifyListeners (SWT.Selection, e);
- event.doit = e.doit;
+ hideCalendar();
break;
}
case SWT.Traverse: {
switch (event.detail) {
case SWT.TRAVERSE_RETURN:
case SWT.TRAVERSE_ESCAPE:
+ event.doit = false;
+ break;
case SWT.TRAVERSE_ARROW_PREVIOUS:
case SWT.TRAVERSE_ARROW_NEXT:
- event.doit = false;
break;
case SWT.TRAVERSE_TAB_NEXT:
case SWT.TRAVERSE_TAB_PREVIOUS:
- event.doit = traverse(event.detail);
+ event.doit = traverse(event);
event.detail = SWT.TRAVERSE_NONE;
- if (event.doit) dropDownCalendar (false);
+ if (event.doit) hideCalendar();
return;
case SWT.TRAVERSE_PAGE_NEXT:
case SWT.TRAVERSE_PAGE_PREVIOUS:
@@ -526,8 +519,6 @@
e.time = event.time;
e.detail = event.detail;
e.doit = event.doit;
- e.character = event.character;
- e.keyCode = event.keyCode;
notifyListeners (SWT.Traverse, e);
event.doit = e.doit;
event.detail = e.detail;
@@ -546,11 +537,13 @@
if (event.character == SWT.ESC) {
/* Escape key cancels popupCalendar and reverts date */
popupCalendar.setDate (savedYear, savedMonth, savedDay);
- dropDownCalendar (false);
+ hideCalendar();
+ return;
}
if (event.keyCode == SWT.CR || (event.stateMask & SWT.ALT) != 0 && (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN)) {
/* Return, Alt+Down, and Alt+Up cancel popupCalendar and select date. */
- dropDownCalendar (false);
+ hideCalendar();
+ return;
}
/* At this point the widget may have been disposed.
* If so, do not continue. */
@@ -570,12 +563,11 @@
if (isDisposed ()) return;
switch (type) {
case SWT.FocusIn: {
- if (hasFocus) return;
- hasFocus = true;
+ if (popupHasFocus) return;
+ popupHasFocus = true;
Shell shell = getShell ();
shell.removeListener (SWT.Deactivate, popupListener);
shell.addListener (SWT.Deactivate, popupListener);
- Display display = getDisplay ();
display.removeFilter (SWT.FocusIn, popupFilter);
display.addFilter (SWT.FocusIn, popupFilter);
Event e = new Event ();
@@ -583,13 +575,12 @@
break;
}
case SWT.FocusOut: {
- if (!hasFocus) return;
- Control focusControl = getDisplay ().getFocusControl ();
+ if (!popupHasFocus) return;
+ Control focusControl = display.getFocusControl ();
if (focusControl == popupCalendar || focusControl == this) return;
- hasFocus = false;
+ popupHasFocus = false;
Shell shell = getShell ();
shell.removeListener(SWT.Deactivate, popupListener);
- Display display = getDisplay ();
display.removeFilter (SWT.FocusIn, popupFilter);
Event e = new Event ();
notifyListeners (SWT.FocusOut, e);
@@ -603,19 +594,16 @@
case SWT.Paint:
/* Draw black rectangle around popupCalendar */
Rectangle bounds = popupCalendar.getBounds();
- Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK);
+ Color black = display.getSystemColor(SWT.COLOR_BLACK);
event.gc.setForeground(black);
event.gc.drawRectangle(0, 0, bounds.width + 1, bounds.height + 1);
break;
case SWT.Close:
event.doit = false;
- dropDownCalendar (false);
+ hideCalendar();
break;
case SWT.Deactivate:
-// Point point = down.toControl(getDisplay().getCursorLocation());
-// Point size = down.getSize();
-// Rectangle rect = new Rectangle(0, 0, size.x, size.y);
-// if (!rect.contains(point)) dropDownCalendar (false);
+ hideCalendar();
break;
}
}
@@ -664,8 +652,8 @@
if (buttonView == null) return;
NSSize buttonSize = buttonView.cell ().cellSize ();
NSRect rect = view.bounds();
- rect.x = rect.width - buttonSize.width + 4;
- rect.y = -1;
+ rect.x = rect.width - buttonSize.width + getBezelSize();
+ rect.y = - getBezelInset();
rect.width = buttonSize.width;
rect.height = buttonSize.height;
buttonView.setFrame(rect);
@@ -675,8 +663,13 @@
postEvent (SWT.Selection);
}
+/* Drop-down arrow button has been pressed. */
void sendVerticalSelection () {
- dropDownCalendar (!isDropped());
+ if (isDropped ()) {
+ hideCalendar();
+ } else {
+ showCalendar();
+ }
}
void setBackground (float /*double*/ [] color) {