Mercurial > dive4elements > river
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 } |