| Summary: | DCR: date/time widget would be useful | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Karice McIntyre <Karice_McIntyre> | ||||||||||||||
| Component: | SWT | Assignee: | Felipe Heidrich <eclipse.felipe> | ||||||||||||||
| Status: | RESOLVED FIXED | QA Contact: | |||||||||||||||
| Severity: | enhancement | ||||||||||||||||
| Priority: | P4 | CC: | belldj, bogofilter+eclipse.org, boyge03, bradleyjames, brockj, contact, dirk.rademann, dwhare, ebrunetta, ekuleshov, frydzewski, jeremyd, Konstantin.Scheglov, markus.kell.r, mik.kersten, mlists, mseele, nedelec, olibralo, peter, pombredanne, rngadam, robert.elves, rsqrd, snorthov, steven.wasleski, sun, taivo, tbs, thirstynellan, villane, w-zwicky, whtiger | ||||||||||||||
| Version: | 2.0 | Keywords: | helpwanted | ||||||||||||||
| Target Milestone: | 3.3 M3 | ||||||||||||||||
| Hardware: | All | ||||||||||||||||
| OS: | All | ||||||||||||||||
| Whiteboard: | |||||||||||||||||
| Bug Depends on: | |||||||||||||||||
| Bug Blocks: | 69655 | ||||||||||||||||
| Attachments: |
|
||||||||||||||||
|
Description
Karice McIntyre
Created attachment 1362 [details]
date-time widget look
I have attached what I think the widget might look like. Each aspect of the date/time (month, day, year, hours, minutes, seconds) is a separate editable field that the user can navigate through by clicking or using the left/right cursors (or perhaps tabbing, I suppose). Each of the fields can also be edited by typing numbers. The up/down arrows on the left increment or decrement the number in the currently selected field. The single, larger drop down arrow drops down a month calendar which you can scroll through (using left/right arrows) by month or by year (using double left/right arrows). I will also attach a pic of what the calendar might look like. Created attachment 1363 [details]
month calendar
Could be considered as a new custom widget post R2.0. Feel free to contribute an implementation as well. Moving from Later. Chrix, is this the date and time picker thing? If so, link this bug. *** Bug 21959 has been marked as a duplicate of this bug. *** Created attachment 19151 [details] using text widget as a datetime picker // I use a Text widget as a date-time picker, it does the job: /* * Created on Mar 23, 2005 Michael Permana mpermana@hotmail.com Siebel Systems */ package com.siebel.analytics.build; import java.text.DateFormat; import java.text.FieldPosition; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.Vector; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; /** * @author mpermana */ public class DateField { Text text; GregorianCalendar calendar = new GregorianCalendar(); DateFormat dateFormat; private FieldPosition[] fieldPositions; private int[] gregorianFields; public DateField(DateFormat dateFormat) { this.dateFormat = dateFormat; fieldPositions = new FieldPosition[] { new FieldPosition(DateFormat.YEAR_FIELD), new FieldPosition(DateFormat.MONTH_FIELD), new FieldPosition(DateFormat.DATE_FIELD), new FieldPosition(DateFormat.HOUR_OF_DAY0_FIELD), new FieldPosition(DateFormat.HOUR_OF_DAY1_FIELD), new FieldPosition(DateFormat.HOUR0_FIELD), new FieldPosition(DateFormat.HOUR1_FIELD), new FieldPosition(DateFormat.MINUTE_FIELD), new FieldPosition(DateFormat.SECOND_FIELD), new FieldPosition(DateFormat.AM_PM_FIELD) }; gregorianFields = new int[] { GregorianCalendar.YEAR, GregorianCalendar.MONTH, GregorianCalendar.DAY_OF_MONTH, GregorianCalendar.HOUR_OF_DAY, GregorianCalendar.HOUR_OF_DAY, GregorianCalendar.HOUR, GregorianCalendar.HOUR, GregorianCalendar.MINUTE, GregorianCalendar.SECOND, GregorianCalendar.AM_PM, }; } public DateField() { this(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.US)); } /** * @param shell */ public Text create(Composite composite) { text = new Text(composite, SWT.BORDER | SWT.READ_ONLY); text.setBackground(new Color(null, 255,255,255)); text.setToolTipText("Use arrow key to "); onDateChange(); KeyListener keyListener = new KeyListener() { public void keyPressed(KeyEvent e) { int multiply = 1; switch (e.keyCode) { case SWT.ARROW_DOWN: multiply = -1; case SWT.ARROW_UP: addCalendar(multiply, 0 < (e.stateMask & SWT.CONTROL)); e.doit = false; break; case SWT.ARROW_LEFT: selectDateFormatField(nextDateFormatField( getDateFormatField(text.getSelection().x), -1)); e.doit = false; break; case SWT.ARROW_RIGHT: selectDateFormatField(nextDateFormatField( getDateFormatField(text.getSelection().x), 1)); e.doit = false; break; } } public void keyReleased(KeyEvent e) { } }; text.addKeyListener(keyListener); return text; } /** * @param b * */ protected void addCalendar(int amount, boolean big) { int x = text.getSelection().x; int dateFormatField = getDateFormatField(x); int gregorianField = dateFormatFieldToGregorianField(dateFormatField); if (GregorianCalendar.AM_PM == gregorianField) { calendar.set(gregorianField, 1 - calendar.get(gregorianField)); } else if (-1 != gregorianField) { int value = calendar.get(gregorianField); calendar.set(gregorianField, value + amount); } onDateChange(); selectDateFormatField(dateFormatField); } /** * @param dateFormatField * @return */ private int dateFormatFieldToGregorianField(int dateFormatField) { for (int i = 0; i < fieldPositions.length; i++) { if (fieldPositions[i].getField() == dateFormatField) return gregorianFields[i]; } return -1; } /** * @param dateFormatField */ private void selectDateFormatField(int dateFormatField) { int correctPosition = 0; for (int i = 0; i < fieldPositions.length; i++) { if (fieldPositions[i].getField() == dateFormatField) correctPosition = fieldPositions[i].getBeginIndex(); } text.setSelection(correctPosition); } /** * @return DateFormat.HOUR0_FIELD etc.. */ protected int getDateFormatField(int position) { for (int i = 0; i < fieldOrder.size(); i++) { int[] fieldPosition = (int[]) fieldOrder.get(i); int beginIndex = fieldPosition[1]; int endIndex = fieldPosition[2]; if (beginIndex <= position && position < endIndex) return fieldPosition[3]; } return -1; } Vector fieldOrder = new Vector(); public void onDateChange() { fieldOrder.removeAllElements(); Date date = calendar.getTime(); for (int i = 0; i < fieldPositions.length; i++) { FieldPosition fieldPosition = fieldPositions[i]; dateFormat.format(date, new StringBuffer(), fieldPosition); if (fieldPosition.getBeginIndex() < fieldPosition.getEndIndex()) addFieldOrder(gregorianFields[i], fieldPosition); } text.setText(dateFormat.format(calendar.getTime())); } /** * @param year * @param beginIndex */ private void addFieldOrder(int field, FieldPosition fieldPosition) { int[] entry = new int[] { field, fieldPosition.getBeginIndex(), fieldPosition.getEndIndex(), fieldPosition.getField() }; for (int i = 0; i < fieldOrder.size(); i++) { int[] fieldPositions = (int[]) fieldOrder.get(i); if (fieldPosition.getBeginIndex() < fieldPositions[1]) { fieldOrder.add(i, entry); return; } } fieldOrder.add(entry); } private int nextDateFormatField(int dateFormatField, int step) { for (int i = 0; i < fieldOrder.size(); i++) { int[] fieldPosition = (int[]) fieldOrder.get(i); if (fieldPosition[3] == dateFormatField) { return ((int[]) fieldOrder.get((i + fieldOrder.size() + step) % fieldOrder.size()))[3]; } } return -1; } /** * @return Returns the dateFormat. */ public DateFormat getDateFormat() { return dateFormat; } /** * @param dateFormat * The dateFormat to set. */ public void setDateFormat(DateFormat dateFormat) { this.dateFormat = dateFormat; } /** * @return Returns the calendar. */ public GregorianCalendar getCalendar() { return calendar; } /** * @param calendar * The calendar to set. */ public void setCalendar(GregorianCalendar calendar) { this.calendar = calendar; } public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 3; shell.setLayout(gridLayout); try { Locale[] locales = { Locale.CHINA, Locale.US, Locale.KOREA, Locale.JAPAN }; DateField dateField; GridData gridData; int width = 150; for (int i = 0; i < locales.length; i++) { dateField = new DateField(DateFormat.getDateInstance( DateFormat.SHORT, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getDateInstance( DateFormat.MEDIUM, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getDateInstance( DateFormat.LONG, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getTimeInstance( DateFormat.SHORT, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getTimeInstance( DateFormat.MEDIUM, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getTimeInstance( DateFormat.LONG, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getDateTimeInstance( DateFormat.MEDIUM, DateFormat.MEDIUM, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); dateField = new DateField(DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG, locales[i])); gridData = new GridData(); gridData.widthHint = width; dateField.create(shell).setLayoutData(gridData); } // createScheduleSection(shell); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } } It's possible that we will add a native date/time picker widget to SWT in the future. Assigning to FH. Created attachment 23709 [details]
A Date picker widget
I wrote a datepicker widget, hope it is useful for others until the native
widget is out.
Created attachment 24129 [details]
datepicker updated
Updated the widget. Some small fixes.
*** Bug 87505 has been marked as a duplicate of this bug. *** Created attachment 26397 [details]
Native Date and Time widget for windows
I create a very simple native Date and Time widget.
It works in win32 OS only.
Feel free to use and to improve it.
Hello, is there any progress on the date widget issue? This is really a needed widget, we notice this all the time in our own Eclipse RCP project ;-) Other solutions on the market are usually not that good as none of those we found uses the native (Windows) Date Picker. We tried Oliveira's native widget, but while it runs okay in its own main() test method, we couldn't get it run in our Eclipse RCP application as it seems the widget ain't visible outside its plugin. It's declared in org.eclipse.swt.widgets but in our own plugin of course (we didn't hack the eclipse swt.jar ;-) Guess the plugin classloader does not see it (..?) Any progress on a Eclipse' provided widget? :) is there any possibility to get it in 3.2 ? On Mac OS X, there is a new "Date Picker" control as of 10.4. It provides a native implementation of both text-box-like and graphical controls for dates and times. Unfortunately, it's in Cocoa only! There is a Carbon clock control, but it only supports limited text-box-like functionality. (It cannot combine both date and time into a single control, and it lacks support for custom formats other than by changing the system-wide locale settings.) We can only hope that the Cocoa version is eventually ported. http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_3.html#//apple_ref/doc/uid/TP30000359-DontLinkElementID_2 Summary of native functionality on various platforms, with functionality implemented by a single control grouped by parentheses: GD - Graphical Date GT - Graphical Time GC - Graphical Date/Time Combo TD - Textual Date TT - Textual Time TC - Textual Date/Time Combo Mac OS X (Cocoa) - (All) Mac OS X (Carbon) - (TD, TT) Windows (95+/NT4+) - (TD, TT, TC), (GD) GTK (2.x) - (GD) Motif - None Given all of this, I recommend that the SWT API should expose two Controls -- one for the text-based date/time and one for the graphical date. On every platform except Windows, the text-based date/time will need to be simulated by other controls. If custom date format support is abandoned on the Mac, it can use a native control. Motif and Mac will need simulated graphical date controls. *** Bug 147359 has been marked as a duplicate of this bug. *** With the recent fixes to the SWT_AWT support on Mac OS, it should be possible to use the graphical calendar from Cocoa in a child Shell. This would work like the child shells used for autocomplete results. The only tricky part would be doing this in a thread-safe way from the perspective of the SWT Display, since the calendar control would be in its own Cocoa window on a different event queue. After reviewing the native widgets for Windows and GTK, it does not look like native backed SWT widgets will work for my application. So I'm wondering if there are plans for a custom version (like with the CTabFoler), perhaps even an extendible one? Would Nebula be the place for this? Also, is there an API, or any other specification, that the SWT team has been working on which I could use to make my CDatepicker/Combo code like the forthcoming components? (has a name for the components been settled on?) Thus far my API is as shown here: http://calypsorcp.sourceforge.net/widgets.php?detail=cdatepicker#api http://calypsorcp.sourceforge.net/widgets.php?detail=cdatepickercombo#api I would be interested in hearing what others have done in this regard. cheers Existing alternatives for SWT date picker (http://www.eclipsezone.com/eclipse/forums/t62966.rhtml) http://swtcalendar.sourceforge.net/demos.html SWTCalendar is a port of Kai Toedter's JCalendar to SWT 0.5 2004-01-26:2006-05-19 [GPL, LGPL] http://www.cwroethel.com/Projects/JPopupCalendar/ An SWT version of JPopupCalendar is now available. V02-02pre, 2005-12-17, EPL http://sourceforge.net/projects/twist/ swt-datepicker; Twist is an open-source Java add-on collection for the Standard Widget Toolkit (SWT) 1.3, 2004-05-18, [BSD, CPL, GPL, LGPL] http://www.jaret.de/datechooser.html The jaret datechooser is a classic drop down date chooser widget for use with the SWT toolkit. 0.96, 2004-12-24:2006-05-03, CPL http://gface.sourceforge.net/ Date Picker - UI widget for visually picking a day in a month. 0.9.1, 2005-07-05:2006-05-06, EPL Jeremy Dowdall (comment #20): how does your CDatepickerCombo fit with GFace Date Picker/Date Combo/Hour Selection Combo? GFace is also talking about donating to the Nebula project, maybe you could work together... http://jroller.com/page/nirpaz?entry=gface_update "I contacted Chris Gross the leader of the Nebula project in eclipse and offered to merge GFace into the Nebula project. Chris was very excited, and once the project will get organized we‘ll examine together what is the best way to donate GFace to eclipse." This bug has been opened since 2002 for something pretty basic so it would be great if it would be solved before the next eclipse... Ricky Ng-Adam (comment #22) > Jeremy Dowdall (comment #20): how does your CDatepickerCombo fit with GFace > Date Picker/Date Combo/Hour Selection Combo? First impressions: The CDatepickerCombo is masked and editable, so the user can enter a date textually in a number of ways, either with the keyboard or the mouse, and it will always be a valid date/time in the format set - date, time, both, or any pattern possible with SimpleDateFormat. When the CDatepickerCombo is not of a DROP_DOWN style, it has a spinner to inc/dec calendar fields. The CDatepicker, which is the drop component of the CDatepickerCombo, uses (as best it can) the native colors and native buttons for the dates (a button is visible under the cursor as the user moves the mouse over the days - similar to how most toolbars look). It can also scroll its days vertically, edit the year via keyboad, and has an analog clock for graphically selecting times (click and drag the clock hands). More complete descriptions of the CDatepicker and CDatepickerCombo are on the website given above. Overall, I greatly appreciated comment #17 by Peter Centgraf and tried to take as much there to heart as possible. Unfortunately though, I also need these widgets to support some additional features: durations, timespans, and ordinals - "A 1 hour Meeting Starting at 10:45 on Friday, August 4th". I also need the graphical date picker's calendar to show tasks/workload per day and the clock to show durations. > donating to the Nebula project, maybe you could work together... That is always a good thing, and the reason I posted here. I don't see why we shouldn't all be working together on this, like you said: "This bug has been opened since 2002". More and more I think that this shouldn't be a native solution... IMHO of course :) So, to finish, I have a question: What is the best way to set the format to be used by the textual date picker? Presently, the CDatepickerCombo uses four methods, which were supposed to coorespond to the date formatter object being used internally: setDateStyle(int) setDateTimeStyle(int, int) setTimeStyle(int) setPattern(String) This seems unnecessarily confusing and should be reduced to an overloaded method such as: setFormat(int, int) - replaces setDateStyle and setTimeStyle setFormat(int, int, int) - replaces setDateTimeStyle setFormat(String) - replaces setPattern thoughts? Jeremy, could you explain your proposed API a bit? It's hard to comment on the appropriateness of a bunch of unlabeled int params. ;-) For example, why three params for the setFormat() that replaces setDateTimeStyle()? I like your implementation a lot. If I have to use custom code, I'll probably go with yours. My recommendation for the API would be to stick to SWT conventions as much as possible. To me, that means using a single packed-int style param for as much as possible and also exposing typed get/set methods for things that can be changed after construction. AFAIK, all of the current controls have just the one style param. Personally, I prefer consistency over optimality for this situation. As for the native/custom debate, I would prefer a native solution whenever possible, even if that is somewhat limiting in the breadth of features. I buy the founding arguments of the SWT project -- catching up with platform integration is an unwinnable race. (For example, when will CCombo get fixed to respond to keyboard events like a native Windows Combo?) Just writing wrappers for native features is hard enough to keep up with. More power to you if you want a custom implementation, but that doesn't solve the core SWT problem, IMHO. Like I said, though, CDatepickerCombo looks pretty darn good. It will also be the only game in town for some platforms. Don't stop working on it or anything. :-) Glad to be helpful, btw. Thanks for doing the difficult part. I agree with Peter, first and foremost we need a wrapper to the native widget, and maybe a custom implementation for platforms not providing a native date/time control. I also can't understand why this is taking so long, as was said, this bug has been here since 2002 . With RCP out and running, it still comes without date/time picker, a control almost every business application needs. This should have a much higher priority, IMHO. they said in a newsgroup it is planned for 3.3 to support a native calendar widget. @eclipse: is that right? comment #26: do you mean this? http://dev.eclipse.org/newslists/news.eclipse.platform/msg56450.html "This was submitted as a proposed 3.3 plan item, but is subject to PMC approval. I believe that a first kick of the 3.3 plan will be available quite soon." the plan is here but there isn't much yet: http://www.eclipse.org/swt/R3_3/plan.html comment #23: Jeremy, I've tried your widget and really like it - in fact, we will use it in our application until Eclipse RCP provides a standard one. I think I would also prefer the API as it is instead of a more complicated setFormat() method that does it all. I did also find another (!) calendar/date chooser widget: http://www.wdev91.com/comp4swt CCalendar : Calendar widget DateChooser : Date field editor that combine a text field and a popup calendar. 0.9.1, 2006-05-21:2006-07-28, EPL (In reply to comment #24) > appropriateness of a bunch of unlabeled int params. ;-) For example, why > three params for the setFormat() that replaces setDateTimeStyle()? I'm afraid the best reasoning I can come up with is that I've been inside the widget for so long that I had trouble looking at it from the outside :) > I like your implementation a lot. Thanks - always great to hear (though critism and bugs are helpfull, so is inspiration!) > My recommendation for the API would be to stick to SWT > conventions as much as possible. To me, that means using a single packed-int > style param for as much as possible and also exposing typed get/set methods > for things that can be changed after construction. AFAIK, all of the current > controls have just the one style param. Personally, I prefer consistency over > optimality for this situation. Agreed, and this could give us the following: setFormat(int format) setFormat(String pattern) possible bits for the "format" parameter: DATE_SHORT DATE_MEDIUM DATE_LONG TIME_SHORT TIME_MEDIUM (too my knowledge a TIME_LONG is not supported in java) Only one of the date and one of the time bits would be valid at a time and if no valid bits were sent nothing would be changed. Initial setting upon construction will be DATE_SHORT unless the contstructor's style int contains valid format bits. Setting the format this way will null the internal "pattern" String. The "pattern" parameter, in the second set method, is the pattern which will be used to set the format with SimpleDateFormat. When setting the format this way, the internal format int (as to be returned with getFormat() ) should be set with one of the following, as appropriate for the given pattern: DATE_CUSTOM TIME_CUSTOM I also propose that the date picker (CDatepicker in my case) follow the same suit and use: setFormat(int format) to determine whether or not to show its calendar, clock, or both. This would have the added advantage that in order to sync styles with the combo, you can simply do: CDatepicker.setFormat(CDatepickerCombo.getFormat()); As a note, the way the current API is, CDatepickerCombo does not have a get method for its format - not good. With this change the get methods, int getFormat() and String getPattern() can be implemented. > As for the native/custom debate I should choose my words more carefully :) Seriously though, I too am a big believer in the founding args of SWT (SWT is actually why I started using Eclipse) and have plenty of frustration with CCombo (like when will it work outside of Windows!). However, unlike buttons and combos, date selection widgets are not very well implemented across different platforms. This will require custom widgetry at some point regardless and therefore why not bring out a custom widget first, rather than continuing to wait? My guess is that once it is out they can't change the API and want to see how others will implement it, but overall I feel pretty in the dark on this whole issue. > Don't stop working on it or anything. :-) No worries there - Calypso doesn't like the GTK or Windows date pickers :) (In reply to comment #27) Apparently we were replying at the same time - how does the updated version(s) of setFormat look to you. A big part for me is the get method. New Question: What is the best way to handle the case when setting one field can influence another? Part 1: when setting the field via direct keyboard input; 2. when using an Increment/Decrement method (arrow keys, mouse wheel, spinner, etc.) Example 1: An end user types "21" into the month field. Example 2: An end user selects the month field, which is currently 5, and clicks the increment part of the spinner 8 times. Are they indicating they want the date "8 months later", or are they just trying to scroll the month field back to 1? Possible Solutions: 1. Consider this value out of range and throw it away; 2. Consider this value out of range and set the field to its maximum (12); 3. Consider this value out of range and set the field to its minimum (1) thus allowing it wrap-around; or 4. Go ahead and set the internal MONTH field to the out of range value, which will have the side affect of incrementing the YEAR field. Present Solution in CDatepickerCombo: Leave it up to the programmer and provide the following set method: setLinkFields(boolean link) If link is true, the fields are "linked" and setting one can influence the others (solution #4). If link is false, the fields are "not linked" and setting one cannot influence the others; for this case solution #3 is used (eg: holding the up arrow key just continually cycles through all values of the selected field). The present solution does not distinguish between the two parts of the question. thoughts and opinions? Jeremy, is there a more appropriate place for bug/RFE submissions for CDatepicker? I'd be happy to summarize some features from platform widgets for you to prioritize. Interpreting keyboard input on a date field is context-dependent. In your example, there is no valid interpretation of "21", but the user could have attempted to follow an initial "Febuary" with "2001". Keyboard input should never "wrap", since the user intention is much more likely to be a straightforward multi-field date entry. E.g. in the US, "1265" means "December 6, 2005" not "Febuary 3". In the UK, that string would be interpreted as "12 June, 2005" not "12 May". Some users get in the habit of typing delimiters to disambiguate, so you should handle various non-numeric characters as part of the input. Have you surveyed the natives on how they handle increment? Of the non-standard apps I have handy, iCal wraps, the Windows "Date and Time" control panel does not, and Mozilla Sunbird 0.2 has no increment at all. P.S. The more I survey current apps, the more I understand why SWT has no widget for this. There's very little consistency on any platform. Windows is the only platform where the widget has been available for any length of time, and Windows apps aren't exactly prized for standards-compliance. You're in a good position to create a custom widget that surpasses all of the attempts I've seen. I should amend my last comment. A lot of motor memory has been developed based on the Visual Basic date widget. Maintaining keyboard-stream compatibility with that widget would be a worthwhile goal, since I suspect many RCP apps are targeted to replace VB predecessors. (In reply to comment #31) > Jeremy, is there a more appropriate place for bug/RFE submissions for > CDatepicker? I'd be happy to summarize some features from platform widgets > for you to prioritize. Thank you for the offer, this is very helpfull (especially Mac, to which I have no access). There is always the Sourceforge site: http://sourceforge.net/projects/calypsorcp But both Felipe and Grant have pointed people to this Bug for question regarding date selectors, so unless it is really CDatepicker specific, perhaps this is the better place... Nice to see all this great discussion going on here. I'm working to get a native verion of this widget on the 3.3 plan. (In reply to comment #32) > Keyboard input should never "wrap", since the user intention is much more > likely to be a straightforward multi-field date entry. Agreed. > Have you surveyed the natives on how they handle increment? Of the > non-standard apps I have handy, iCal wraps, the Windows "Date and Time" > control panel does not, and Mozilla Sunbird 0.2 has no increment at all. I have surveyed more end users than appliations as most of my target audience is non-technical, and so far they've all expected it to wrap (they also couldn't remember where they'd seen a date widget before - if anything, Quicken was mentioned). My conclusion at this point is to remove setLinkFields from the API (keeping it simple) and use Solution #1 for keyboard entry and Solution #3 for incrementing & decrementing. > Some users get in the habit of typing delimiters to disambiguate, so you > should handle various non-numeric characters as part of the input. Very true; here are my current navigation and edit thoughts: Focus: When the widget gains focus, by a means other than a mouse click (such as tabbing through a form), its entire text area is selected. The intent is to allow it to be copied and has the side affect that no field is actually selected, and thus the widget cannot be edited. When the widget looses focus, by any means, all fields are unselected and again, the widget cannot be edited. Navigation: Before editing, an individual field must be selected; the primary way is to simply select the field to be edited by clicking on it with the mouse. Once the widget has focus, however, there are also many other ways of moving between and selecting fields: * Clicking the center mouse button will cycle through the fields * The left and right arrow keys move one field at time * Typing the first character of the next separation sequence will move to the next field. For example, given the pattern "MM/dd/yy", pressing the '/' key will move to the next field. Likewise, given the pattern "MM'long separation sequence'dd'another long sequence'yy", typing 'l' when on the "MM" field will move to the "dd" field, and then typing 'a' will move to the last field. * If the user is entering the field's value via the keyboard and the maximum number of digits for that field have been typed, selection is automatically moved to the next field. Note that two digit fields will always require two digits to be input: the first day must be entered as "01" unless the user wishes to move fields by the above method: "1/", for example. Editing: Once the user has navigated to a field they want to change, they again have multiple options: * A Spinner, which will be present if the CDatepickerCombo is not of DROP_DOWN style, can be used to increment and decrement the field's value * Scrolling with the mouse wheel will increase and decrease the field * The Up and Down arrow keys will increment and decrement the field * Enter the value directly with the keyboard (In reply to comment #35) > Nice to see all this great discussion going on here. I'm working to get a > native verion of this widget on the 3.3 plan. > Good to hear. Does this mean you've been thinking about the current discusion topics for awhile now, or are you in the proposal paperwork stage? I've been following a long a bit, however, the API and functionality of the SWT widget will need to take into account all of the platforms. An emulated widget doesn't need to do this. Felipe looked into this a while back and had a few initial hacks but 3.2 work ate him. Hopefully, it the same thing won't happen for 3.3. Tidbits from the VB DateTimePicker widget (testing VS 2003 aka: .NET 1.1): Cycling focus via tab will initially select the first field of the widget. If the user changes the active field and cycles focus out and back, they will return to the same field. E.g. in a US short date: tab in, type "/", tab, shift-tab, and you're back to the month field. If you click the drop-down and then tab out+back, you'll end up with a mystery focus in the limbo state between the last field and the first field. Various symbol characters will advance to the next field, regardless of the current display pattern: ",./" and non-keypad "-". Most other symbols just cause a system beep. Keypad + and - act as increment and decrement. You can also move between fields via left and right arrows, or inc/dec with up and down arrows. Attempts to use clipboard commands in the text part will cause a system beep. Attempts in the calendar drop-down silently do nothing. There is no contextual menu on the main combo, but there is a "Go to Today" item (all by itself) on the calendar. Field inc/dec is "unlinked", except when a change violates a calendar constraint. For example, if a US "2/29/2004" is selected, and the user inc.s the year field, the date will become "2/28/2005". These constraint-avoidance tweaks are one-way, i.e. the day field will never automatically return to "29". Min and max allowable values can be provided as properties. When this is done, field inc/dec will attempt to avoid constraint violations by setting all fields to the closest valid date to the one that would have been displayed by an unconstrained widget. For example, if the max date is "8/5/2006" and the user attempts to inc the year from "3/4/2006", the date will become "8/5/2006". The control can optionally include a checkbox, which acts as the first field for navigation order. If it is unchecked, the text portion of the widget is disabled, but clicking the drop-down will set it checked automatically. The VB date widget is a very odd beast, IMHO. ---- Given the above, Jeremy's proposed behavior seems mostly fine. Only two things might be odd for previous VB users: the control should always accept [.,/-] as valid separator characters, and the entire widget should be considered a single stop on the tab cycle. I personally think that returning the focus to exactly the field that was left is odd, but it's probably a good idea to keep compatibility. Everything else proposed would be non-disruptive icing on the cake. Stay tuned for my next installment, where I describe the madness that is the VB MonthCalendar control.... I forgot to mention: the DateTimePicker also supports validation events. This works very much like the VetoableChangeListener mechanism. Fixed > 20061030 (will be in 3.3 M3) Native controls used wherever possible: calendar, date, and time all native on Win; date and time native on Mac; calendar native on gtk. All other areas are emulated. Some things still need to be implemented, notably adding a setFormat API or style, accounting for locale changes (some things will currently only work well in EN_US locale), and possibly adding the "drop-down calendar" style. For anything else, please open a new bug report. That's great - is this currently or going to be part of the SWT examples? It is currently in ControlExample, on DateTime tab. >>possibly adding the "drop-down calendar" style
Would be highly appreciated.
And thanks for the good work!
That's very nice. Would it be possible to select multiple dates with this Calendar widget ? Nice if it display '0' instead of empty space in no value area. example :- / / -> 00/00/00 1/12/ 6 -> 01/12/06 with zero look nicer and more proper... Any ideas ? I would like the DateTime public API extended so that we can get/set the value using either a Date or Calendar object, rather than dealing with individual fields (month, day, year, hour, minute, second). Medium and Long date not working in Mac. This bug report is closed (a native date/time widget has been implemented). Enter a new bug report describing the problem you are seeing. +1 should a RFE be opened ? (In reply to comment #47) > I would like the DateTime public API extended so that we can get/set the value > using either a Date or Calendar object, rather than dealing with individual > fields (month, day, year, hour, minute, second). > Carolyn, why was 'Today' functionality removed from the DateTime widget. It seemed like a useful feature. Platform consistency? why does the date widget not support the "combo-box style" (SysDateTimePick32)? is it because platform consistency, too? |