comparison flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/CrossSectionChartThemePanel.java @ 3717:3b4cef59836a

KMSpinner refactoring flys-client/trunk@5482 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Christian Lins <christian.lins@intevation.de>
date Sun, 16 Sep 2012 12:38:24 +0000
parents 8e6b1df7c3b0
children bbd82bd8e541
comparison
equal deleted inserted replaced
3716:4e33aa341e51 3717:3b4cef59836a
1 package de.intevation.flys.client.client.ui.chart; 1 package de.intevation.flys.client.client.ui.chart;
2 2
3 import com.google.gwt.core.client.GWT; 3 import com.google.gwt.core.client.GWT;
4
5 import com.google.gwt.i18n.client.NumberFormat;
6
7 import com.google.gwt.user.client.rpc.AsyncCallback; 4 import com.google.gwt.user.client.rpc.AsyncCallback;
8
9 import com.smartgwt.client.data.Record;
10
11 import com.smartgwt.client.types.ListGridFieldType; 5 import com.smartgwt.client.types.ListGridFieldType;
12
13 import com.smartgwt.client.util.SC; 6 import com.smartgwt.client.util.SC;
14
15 import com.smartgwt.client.widgets.Button;
16 import com.smartgwt.client.widgets.Canvas; 7 import com.smartgwt.client.widgets.Canvas;
17 import com.smartgwt.client.widgets.Label;
18
19 import com.smartgwt.client.widgets.events.ClickEvent;
20
21 import com.smartgwt.client.widgets.form.DynamicForm; 8 import com.smartgwt.client.widgets.form.DynamicForm;
22 import com.smartgwt.client.widgets.form.FormItemValueFormatter;
23 import com.smartgwt.client.widgets.form.FormItemValueParser;
24
25 import com.smartgwt.client.widgets.form.fields.FormItem;
26 import com.smartgwt.client.widgets.form.fields.SelectItem; 9 import com.smartgwt.client.widgets.form.fields.SelectItem;
27 import com.smartgwt.client.widgets.form.fields.SpinnerItem;
28 import com.smartgwt.client.widgets.form.fields.TextItem;
29
30 import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
31 import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
32 import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; 10 import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
33 import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; 11 import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
34 import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
35 import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
36
37 import com.smartgwt.client.widgets.grid.ListGrid; 12 import com.smartgwt.client.widgets.grid.ListGrid;
38 import com.smartgwt.client.widgets.grid.ListGridField; 13 import com.smartgwt.client.widgets.grid.ListGridField;
39 import com.smartgwt.client.widgets.grid.ListGridRecord; 14 import com.smartgwt.client.widgets.grid.ListGridRecord;
40
41 import com.smartgwt.client.widgets.layout.HLayout;
42 import com.smartgwt.client.widgets.layout.VLayout; 15 import com.smartgwt.client.widgets.layout.VLayout;
43
44 import com.smartgwt.client.widgets.menu.Menu; 16 import com.smartgwt.client.widgets.menu.Menu;
45 import com.smartgwt.client.widgets.menu.MenuItem; 17 import com.smartgwt.client.widgets.menu.MenuItem;
46
47 import com.smartgwt.client.widgets.menu.events.ClickHandler; 18 import com.smartgwt.client.widgets.menu.events.ClickHandler;
48 import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent; 19 import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
49 20
50 import de.intevation.flys.client.client.Config; 21 import de.intevation.flys.client.client.Config;
51
52 import de.intevation.flys.client.client.services.CrossSectionKMServiceAsync; 22 import de.intevation.flys.client.client.services.CrossSectionKMServiceAsync;
53 import de.intevation.flys.client.client.services.LoadArtifactService; 23 import de.intevation.flys.client.client.services.LoadArtifactService;
54 import de.intevation.flys.client.client.services.LoadArtifactServiceAsync; 24 import de.intevation.flys.client.client.services.LoadArtifactServiceAsync;
55
56 import de.intevation.flys.client.client.ui.CollectionView; 25 import de.intevation.flys.client.client.ui.CollectionView;
57 26 import de.intevation.flys.client.client.widgets.KMSpinner;
27 import de.intevation.flys.client.client.widgets.KMSpinnerChangeListener;
58 import de.intevation.flys.client.shared.model.Artifact; 28 import de.intevation.flys.client.shared.model.Artifact;
59 import de.intevation.flys.client.shared.model.Data; 29 import de.intevation.flys.client.shared.model.Data;
60 import de.intevation.flys.client.shared.model.DefaultArtifact; 30 import de.intevation.flys.client.shared.model.DefaultArtifact;
61 import de.intevation.flys.client.shared.model.DefaultData; 31 import de.intevation.flys.client.shared.model.DefaultData;
62 import de.intevation.flys.client.shared.model.FacetRecord; 32 import de.intevation.flys.client.shared.model.FacetRecord;
78 * declare which cross section profile is "master" (waterlevels refer to the 48 * declare which cross section profile is "master" (waterlevels refer to the
79 * chosen kilometer of that cross section profile). 49 * chosen kilometer of that cross section profile).
80 * Also can show 'area creation' context menus. 50 * Also can show 'area creation' context menus.
81 */ 51 */
82 public class CrossSectionChartThemePanel 52 public class CrossSectionChartThemePanel
83 extends ChartThemePanel { 53 extends ChartThemePanel
54 implements KMSpinnerChangeListener
55 {
84 /** Artifact Clone/Creation service. */ 56 /** Artifact Clone/Creation service. */
85 protected LoadArtifactServiceAsync loadService = 57 protected LoadArtifactServiceAsync loadService =
86 GWT.create(LoadArtifactService.class); 58 GWT.create(LoadArtifactService.class);
87 59
88 /** Service to query measurement points of cross sections. */ 60 /** Service to query measurement points of cross sections. */
268 return layout; 240 return layout;
269 } 241 }
270 242
271 243
272 /** Disable the UI (becomes gray, inresponsive to user input). */ 244 /** Disable the UI (becomes gray, inresponsive to user input). */
245 @Override
273 public void disable() { 246 public void disable() {
274 this.layout.setDisabled(true); 247 this.layout.setDisabled(true);
275 } 248 }
276 249
277 250
278 /** DisDisable the UI (becomes ungray, responsive to user input). */ 251 /** DisDisable the UI (becomes ungray, responsive to user input). */
252 @Override
279 public void enable() { 253 public void enable() {
280 this.layout.setDisabled(false); 254 this.layout.setDisabled(false);
281 } 255 }
282 256
283 257
420 * @param facetRecord The underlying datastores record. 394 * @param facetRecord The underlying datastores record.
421 * @param up If true, numerically higher values are preferred if 395 * @param up If true, numerically higher values are preferred if
422 * two values in \param in are in the same distance to 396 * two values in \param in are in the same distance to
423 * \param to. 397 * \param to.
424 */ 398 */
425 public void spinnerValueEntered(final SpinnerItem item, 399 public void spinnerValueEntered(KMSpinner spinner, final double enteredKm, final FacetRecord facetRecord, final boolean up) {
426 final double enteredKm, final FacetRecord facetRecord, final boolean up
427 ) {
428 disable(); 400 disable();
429 Config config = Config.getInstance(); 401 Config config = Config.getInstance();
430 final String locale = config.getLocale(); 402 final String locale = config.getLocale();
431 403
432 Map<Integer, Double> map = new HashMap<Integer,Double>(); 404 Map<Integer, Double> map = new HashMap<Integer,Double>();
453 SC.warn(MSG.getString(caught.getMessage())); 425 SC.warn(MSG.getString(caught.getMessage()));
454 updateCollection(); 426 updateCollection();
455 //updateGrid(); 427 //updateGrid();
456 enable(); 428 enable();
457 } 429 }
430
458 @Override 431 @Override
459 public void onSuccess(Map<Integer, Double[]> obj) { 432 public void onSuccess(Map<Integer, Double[]> obj) {
460 Double[] kms = obj.get(dbid); 433 Double[] kms = obj.get(dbid);
461 double closest = 434 double closest =
462 CrossSectionChartThemePanel.closest(kms, enteredKm, up); 435 CrossSectionChartThemePanel.closest(kms, enteredKm, up);
490 }); 463 });
491 } 464 }
492 465
493 466
494 /** 467 /**
495 * Create a "kilometer spinner" for CrossSection Facets.
496 * @param facetRecord The respective Facet/Theme.
497 * @return label, intialized SpinnerItem.
498 */
499 public SpinnerItem createSpinnerItem(FacetRecord facetRecord) {
500 SpinnerItem spinnerItem = new SpinnerItem();
501 spinnerItem.setShowTitle(false);
502 spinnerItem.setTitle("Waterlevel-Spinner");
503 spinnerItem.setWidth(45);
504 spinnerItem.setDefaultValue(Double.valueOf(facetRecord.getTheme()
505 .getCollectionItem()
506 .getData().get(CS_KM)));
507
508 spinnerItem.setMin(0);
509 spinnerItem.setMax(2000);
510 spinnerItem.setStep(0.1d);
511 spinnerItem.setChangeOnKeypress(true);
512 return spinnerItem;
513 }
514
515
516 /**
517 * SpinnerItem-like element with text label and up/down buttons.
518 */
519 public class KmSpinner extends HLayout {
520 protected Label label;
521
522 protected FacetRecord facetRecord;
523
524 protected double currentValue;
525
526 public KmSpinner(FacetRecord facetRecord) {
527 super(2);
528 this.facetRecord = facetRecord;
529 final FacetRecord _facetRecord = facetRecord;
530 currentValue = Double.valueOf(facetRecord.getTheme()
531 .getCollectionItem().getData().get(CS_KM));
532 // Buttons and labels.
533 int height = 18;
534 // minusButton shall ask service for previous available cs.
535 Button minusButton = new Button("-");
536 minusButton.setWidth(10);
537 minusButton.setHeight(height);
538 minusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
539 public void onClick(ClickEvent evt) {
540 spinnerValueEntered(null, currentValue - 0.1d, _facetRecord, false);
541 }
542 });
543
544 DynamicForm form = new DynamicForm();
545 final TextItem kmField = new TextItem();
546 kmField.setValue(currentValue);
547 kmField.setWidth(35);
548 kmField.setTitle("");
549 kmField.setHeight(height);
550
551 FormItemValueFormatter doubleFormat = new FormItemValueFormatter() {
552 public String formatValue(Object value, Record record,
553 DynamicForm form, FormItem item) {
554 if (value != null) {
555 NumberFormat nf = NumberFormat.getDecimalFormat();
556 try {
557 double d = Double.valueOf(value.toString()).doubleValue();
558 return nf.format(d);
559 } catch (Exception e) {
560 return value.toString();
561 }
562 }
563 else {
564 return null;
565 }
566 }
567 };
568 kmField.setEditorValueFormatter(doubleFormat);
569
570 FormItemValueParser doubleParser = new FormItemValueParser() {
571 public Object parseValue(String value,
572 DynamicForm form,
573 FormItem item) {
574 if (value == null)
575 return null;
576 try {
577 NumberFormat nf = NumberFormat.getDecimalFormat();
578 double d = nf.parse(value.toString());
579 return (new Double(d)).toString();
580 }
581 catch(NumberFormatException nfe) {
582 return value;
583 }
584 }
585 };
586 kmField.setEditorValueParser(doubleParser);
587
588 // Update on focus lost and enter-pressed.
589 kmField.addBlurHandler(new BlurHandler() {
590 @Override
591 public void onBlur(BlurEvent be) {
592 if (kmField.getValue() != null) {
593 try {
594 spinnerValueEntered(null,
595 Double.parseDouble(kmField.getValue().toString()),
596 _facetRecord, true);
597 }
598 catch(NumberFormatException nfe) {
599 GWT.log("entered string cannot be parsed to double.");
600 }
601 }
602 }
603 });
604 kmField.addKeyPressHandler(new KeyPressHandler(){
605 @Override
606 public void onKeyPress(KeyPressEvent kpe) {
607 if (kpe.getKeyName().equals("Enter")) {
608 kmField.blurItem();
609 }
610 }
611 });
612 // TODO: i18n Now add all the validators, formatters, editors/parsers etc.
613 form.setFields(kmField);
614 form.setTitle("");
615 form.setTitlePrefix("");
616 form.setTitleSuffix("");
617 form.setTitleWidth(0);
618 form.setWidth(40);
619 form.setHeight(height);
620 // PlusButton shall ask service for next available cs.
621 Button plusButton = new Button("+");
622 plusButton.setWidth(10);
623 plusButton.setHeight(height);
624 plusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
625 public void onClick(ClickEvent evt) {
626 spinnerValueEntered(null, currentValue + 0.1d, _facetRecord, true);
627 }
628 });
629 this.addMember(minusButton);
630 this.addMember(form);
631 this.addMember(plusButton);
632
633 this.setHeight(height*2);
634 this.setWidth(60);
635 }
636 }
637
638
639 /**
640 * Create and configure the Grid to display. 468 * Create and configure the Grid to display.
641 * @return ListGrid with Themes and related controls inside. 469 * @return ListGrid with Themes and related controls inside.
642 */ 470 */
643 @Override 471 @Override
644 protected ListGrid createGrid() { 472 protected ListGrid createGrid() {
473 final CrossSectionChartThemePanel parent = this;
474
645 ListGrid list = new ListGrid() { 475 ListGrid list = new ListGrid() {
646 @Override 476 @Override
647 protected Canvas createRecordComponent( 477 protected Canvas createRecordComponent(
648 final ListGridRecord record, 478 final ListGridRecord record,
649 Integer colNum) 479 Integer colNum)
657 } 487 }
658 488
659 String fieldName = this.getFieldName(colNum); 489 String fieldName = this.getFieldName(colNum);
660 490
661 if (fieldName.equals(GRID_FIELD_ACTIONS)) { 491 if (fieldName.equals(GRID_FIELD_ACTIONS)) {
662 /* 492 double currentValue =
663 TODO: 493 Double.valueOf(facetRecord.getTheme().getCollectionItem().getData().get(CS_KM));
664 if (facetRecord.getTheme().getActive() != 1) { 494 KMSpinner kmSpinner = new KMSpinner(currentValue, facetRecord);
665 spinnerItem.disable(); 495 kmSpinner.addChangeListener(parent);
666 } 496 return kmSpinner;
667 */
668
669 /*
670 // To have visual representation of synchronous
671 // navigation or not per theme, snip:
672 if (synchronCrossSectionThemes.contains (themeHash
673 (facetRecord.getTheme()))) {
674 spinnerItem.setTextBoxStyle("bgBlueDark");
675 }
676 */
677
678 return new KmSpinner(facetRecord);
679 } 497 }
680 else { 498 else {
681 return null; 499 return null;
682 } 500 }
683 } 501 }
713 ListGridField name = new ListGridField( 531 ListGridField name = new ListGridField(
714 GRID_FIELD_NAME, MSG.chart_themepanel_header_themes()); 532 GRID_FIELD_NAME, MSG.chart_themepanel_header_themes());
715 name.setType(ListGridFieldType.TEXT); 533 name.setType(ListGridFieldType.TEXT);
716 534
717 ListGridField actions = new ListGridField(GRID_FIELD_ACTIONS, 535 ListGridField actions = new ListGridField(GRID_FIELD_ACTIONS,
718 MSG.chart_themepanel_header_actions(), 65); 536 MSG.chart_themepanel_header_actions(), 100);
719 537
720 list.setFields(active, name, actions); 538 list.setFields(active, name, actions);
721 } 539 }
722 540
723 541
732 this.currentCSMasterUUID = currentMasterUuid; 550 this.currentCSMasterUUID = currentMasterUuid;
733 } 551 }
734 552
735 553
736 /** Returns name of cross section area facets. */ 554 /** Returns name of cross section area facets. */
555 @Override
737 protected String getAreaFacetName() { 556 protected String getAreaFacetName() {
738 return "cross_section.area"; 557 return "cross_section.area";
739 } 558 }
740 559
741 560
743 * Return true if two themes are canditates for an area being 562 * Return true if two themes are canditates for an area being
744 * rendered between them. 563 * rendered between them.
745 * TODO join with canArea, generalize to allow easier modification 564 * TODO join with canArea, generalize to allow easier modification
746 * in subclasses. 565 * in subclasses.
747 */ 566 */
567 @Override
748 protected boolean areAreaCompatible(Theme a, Theme b) { 568 protected boolean areAreaCompatible(Theme a, Theme b) {
749 if (a.equals(b)) { 569 if (a.equals(b)) {
750 return false; 570 return false;
751 } 571 }
752 return (a.getFacet().equals("cross_section") 572 return (a.getFacet().equals("cross_section")
758 578
759 /** 579 /**
760 * True if context menu should contain 'create area' submenu on 580 * True if context menu should contain 'create area' submenu on
761 * this theme. 581 * this theme.
762 */ 582 */
583 @Override
763 protected boolean canArea(Theme a) { 584 protected boolean canArea(Theme a) {
764 return a.getFacet().equals("cross_section") 585 return a.getFacet().equals("cross_section")
765 || a.getFacet().equals("cross_section_water_line") 586 || a.getFacet().equals("cross_section_water_line")
766 || a.getFacet().endsWith("line"); 587 || a.getFacet().endsWith("line");
767 } 588 }

http://dive4elements.wald.intevation.org