You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractColorPicker.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.v7.ui;
  17. import java.io.Serializable;
  18. import java.lang.reflect.Method;
  19. import java.util.Collection;
  20. import java.util.Locale;
  21. import org.jsoup.nodes.Attributes;
  22. import org.jsoup.nodes.Element;
  23. import com.vaadin.ui.UI;
  24. import com.vaadin.ui.Window.CloseEvent;
  25. import com.vaadin.ui.Window.CloseListener;
  26. import com.vaadin.ui.declarative.DesignAttributeHandler;
  27. import com.vaadin.ui.declarative.DesignContext;
  28. import com.vaadin.v7.shared.ui.colorpicker.Color;
  29. import com.vaadin.v7.shared.ui.colorpicker.ColorPickerServerRpc;
  30. import com.vaadin.v7.shared.ui.colorpicker.ColorPickerState;
  31. import com.vaadin.v7.ui.components.colorpicker.ColorChangeEvent;
  32. import com.vaadin.v7.ui.components.colorpicker.ColorChangeListener;
  33. import com.vaadin.v7.ui.components.colorpicker.ColorPickerPopup;
  34. import com.vaadin.v7.ui.components.colorpicker.ColorSelector;
  35. /**
  36. * An abstract class that defines default implementation for a color picker
  37. * component.
  38. *
  39. * @since 7.0.0
  40. */
  41. @Deprecated
  42. public abstract class AbstractColorPicker extends AbstractLegacyComponent
  43. implements CloseListener, ColorSelector {
  44. private static final Method COLOR_CHANGE_METHOD;
  45. static {
  46. try {
  47. COLOR_CHANGE_METHOD = ColorChangeListener.class.getDeclaredMethod(
  48. "colorChanged", new Class[] { ColorChangeEvent.class });
  49. } catch (final NoSuchMethodException e) {
  50. // This should never happen
  51. throw new RuntimeException(
  52. "Internal error finding methods in ColorPicker");
  53. }
  54. }
  55. /**
  56. * Interface for converting 2d-coordinates to a Color.
  57. */
  58. @Deprecated
  59. public interface Coordinates2Color extends Serializable {
  60. /**
  61. * Calculate color from coordinates.
  62. *
  63. * @param x
  64. * the x-coordinate
  65. * @param y
  66. * the y-coordinate
  67. *
  68. * @return the color
  69. */
  70. public Color calculate(int x, int y);
  71. /**
  72. * Calculate coordinates from color.
  73. *
  74. * @param c
  75. * the c
  76. *
  77. * @return the integer array with the coordinates
  78. */
  79. public int[] calculate(Color c);
  80. }
  81. @Deprecated
  82. public enum PopupStyle {
  83. POPUP_NORMAL("normal"), POPUP_SIMPLE("simple");
  84. private String style;
  85. PopupStyle(String styleName) {
  86. style = styleName;
  87. }
  88. @Override
  89. public String toString() {
  90. return style;
  91. }
  92. }
  93. private ColorPickerServerRpc rpc = new ColorPickerServerRpc() {
  94. @Override
  95. public void openPopup(boolean open) {
  96. showPopup(open);
  97. }
  98. };
  99. protected static final String STYLENAME_DEFAULT = "v-colorpicker";
  100. protected static final String STYLENAME_BUTTON = "v-button";
  101. protected static final String STYLENAME_AREA = "v-colorpicker-area";
  102. protected PopupStyle popupStyle = PopupStyle.POPUP_NORMAL;
  103. /** The popup window. */
  104. private ColorPickerPopup window;
  105. /** The color. */
  106. protected Color color;
  107. /** The UI. */
  108. private UI parent;
  109. protected String popupCaption = null;
  110. private int positionX = 0;
  111. private int positionY = 0;
  112. protected boolean rgbVisible = true;
  113. protected boolean hsvVisible = true;
  114. protected boolean swatchesVisible = true;
  115. protected boolean historyVisible = true;
  116. protected boolean textfieldVisible = true;
  117. /**
  118. * Instantiates a new color picker.
  119. */
  120. public AbstractColorPicker() {
  121. this("Colors", Color.WHITE);
  122. }
  123. /**
  124. * Instantiates a new color picker.
  125. *
  126. * @param popupCaption
  127. * the caption of the popup window
  128. */
  129. public AbstractColorPicker(String popupCaption) {
  130. this(popupCaption, Color.WHITE);
  131. }
  132. /**
  133. * Instantiates a new color picker.
  134. *
  135. * @param popupCaption
  136. * the caption of the popup window
  137. * @param initialColor
  138. * the initial color
  139. */
  140. public AbstractColorPicker(String popupCaption, Color initialColor) {
  141. super();
  142. registerRpc(rpc);
  143. setColor(initialColor);
  144. this.popupCaption = popupCaption;
  145. setDefaultStyles();
  146. setCaption("");
  147. }
  148. @Override
  149. public void setColor(Color color) {
  150. this.color = color;
  151. if (window != null) {
  152. window.setColor(color);
  153. }
  154. getState().color = color.getCSS();
  155. }
  156. @Override
  157. public Color getColor() {
  158. return color;
  159. }
  160. /**
  161. * Set true if the component should show a default caption (css-code for the
  162. * currently selected color, e.g. #ffffff) when no other caption is
  163. * available.
  164. *
  165. * @param enabled
  166. */
  167. public void setDefaultCaptionEnabled(boolean enabled) {
  168. getState().showDefaultCaption = enabled;
  169. }
  170. /**
  171. * Returns true if the component shows the default caption (css-code for the
  172. * currently selected color, e.g. #ffffff) if no other caption is available.
  173. */
  174. public boolean isDefaultCaptionEnabled() {
  175. return getState(false).showDefaultCaption;
  176. }
  177. /**
  178. * Sets the position of the popup window.
  179. *
  180. * @param x
  181. * the x-coordinate
  182. * @param y
  183. * the y-coordinate
  184. */
  185. public void setPosition(int x, int y) {
  186. positionX = x;
  187. positionY = y;
  188. if (window != null) {
  189. window.setPositionX(x);
  190. window.setPositionY(y);
  191. }
  192. }
  193. @Override
  194. public void addColorChangeListener(ColorChangeListener listener) {
  195. addListener(ColorChangeEvent.class, listener, COLOR_CHANGE_METHOD);
  196. }
  197. @Override
  198. public void removeColorChangeListener(ColorChangeListener listener) {
  199. removeListener(ColorChangeEvent.class, listener);
  200. }
  201. @Override
  202. public void windowClose(CloseEvent e) {
  203. if (e.getWindow() == window) {
  204. getState().popupVisible = false;
  205. }
  206. }
  207. /**
  208. * Fired when a color change event occurs.
  209. *
  210. * @param event
  211. * The color change event
  212. */
  213. protected void colorChanged(ColorChangeEvent event) {
  214. setColor(event.getColor());
  215. fireColorChanged();
  216. }
  217. /**
  218. * Notifies the listeners that the selected color has changed.
  219. */
  220. public void fireColorChanged() {
  221. fireEvent(new ColorChangeEvent(this, color));
  222. }
  223. /**
  224. * The style for the popup window.
  225. *
  226. * @param style
  227. * The style
  228. */
  229. public void setPopupStyle(PopupStyle style) {
  230. popupStyle = style;
  231. switch (style) {
  232. case POPUP_NORMAL: {
  233. setRGBVisibility(true);
  234. setHSVVisibility(true);
  235. setSwatchesVisibility(true);
  236. setHistoryVisibility(true);
  237. setTextfieldVisibility(true);
  238. break;
  239. }
  240. case POPUP_SIMPLE: {
  241. setRGBVisibility(false);
  242. setHSVVisibility(false);
  243. setSwatchesVisibility(true);
  244. setHistoryVisibility(false);
  245. setTextfieldVisibility(false);
  246. break;
  247. }
  248. }
  249. }
  250. /**
  251. * Gets the style for the popup window.
  252. *
  253. * @since 7.5.0
  254. * @return popup window style
  255. */
  256. public PopupStyle getPopupStyle() {
  257. return popupStyle;
  258. }
  259. /**
  260. * Set the visibility of the RGB Tab.
  261. *
  262. * @param visible
  263. * The visibility
  264. */
  265. public void setRGBVisibility(boolean visible) {
  266. if (!visible && !hsvVisible && !swatchesVisible) {
  267. throw new IllegalArgumentException("Cannot hide all tabs.");
  268. }
  269. rgbVisible = visible;
  270. if (window != null) {
  271. window.setRGBTabVisible(visible);
  272. }
  273. }
  274. /**
  275. * Gets the visibility of the RGB Tab.
  276. *
  277. * @since 7.5.0
  278. * @return visibility of the RGB tab
  279. */
  280. public boolean getRGBVisibility() {
  281. return rgbVisible;
  282. }
  283. /**
  284. * Set the visibility of the HSV Tab.
  285. *
  286. * @param visible
  287. * The visibility
  288. */
  289. public void setHSVVisibility(boolean visible) {
  290. if (!visible && !rgbVisible && !swatchesVisible) {
  291. throw new IllegalArgumentException("Cannot hide all tabs.");
  292. }
  293. hsvVisible = visible;
  294. if (window != null) {
  295. window.setHSVTabVisible(visible);
  296. }
  297. }
  298. /**
  299. * Gets the visibility of the HSV Tab.
  300. *
  301. * @since 7.5.0
  302. * @return visibility of the HSV tab
  303. */
  304. public boolean getHSVVisibility() {
  305. return hsvVisible;
  306. }
  307. /**
  308. * Set the visibility of the Swatches Tab.
  309. *
  310. * @param visible
  311. * The visibility
  312. */
  313. public void setSwatchesVisibility(boolean visible) {
  314. if (!visible && !hsvVisible && !rgbVisible) {
  315. throw new IllegalArgumentException("Cannot hide all tabs.");
  316. }
  317. swatchesVisible = visible;
  318. if (window != null) {
  319. window.setSwatchesTabVisible(visible);
  320. }
  321. }
  322. /**
  323. * Gets the visibility of the Swatches Tab.
  324. *
  325. * @since 7.5.0
  326. * @return visibility of the swatches tab
  327. */
  328. public boolean getSwatchesVisibility() {
  329. return swatchesVisible;
  330. }
  331. /**
  332. * Sets the visibility of the Color History.
  333. *
  334. * @param visible
  335. * The visibility
  336. */
  337. public void setHistoryVisibility(boolean visible) {
  338. historyVisible = visible;
  339. if (window != null) {
  340. window.setHistoryVisible(visible);
  341. }
  342. }
  343. /**
  344. * Gets the visibility of the Color History.
  345. *
  346. * @since 7.5.0
  347. * @return visibility of color history
  348. */
  349. public boolean getHistoryVisibility() {
  350. return historyVisible;
  351. }
  352. /**
  353. * Sets the visibility of the CSS color code text field.
  354. *
  355. * @param visible
  356. * The visibility
  357. */
  358. public void setTextfieldVisibility(boolean visible) {
  359. textfieldVisible = visible;
  360. if (window != null) {
  361. window.setPreviewVisible(visible);
  362. }
  363. }
  364. /**
  365. * Gets the visibility of CSS color code text field.
  366. *
  367. * @since 7.5.0
  368. * @return visibility of css color code text field
  369. */
  370. public boolean getTextfieldVisibility() {
  371. return textfieldVisible;
  372. }
  373. @Override
  374. protected ColorPickerState getState() {
  375. return (ColorPickerState) super.getState();
  376. }
  377. @Override
  378. protected ColorPickerState getState(boolean markAsDirty) {
  379. return (ColorPickerState) super.getState(markAsDirty);
  380. }
  381. /**
  382. * Sets the default styles of the component.
  383. *
  384. */
  385. protected abstract void setDefaultStyles();
  386. /**
  387. * Shows a popup-window for color selection.
  388. */
  389. public void showPopup() {
  390. showPopup(true);
  391. }
  392. /**
  393. * Hides a popup-window for color selection.
  394. */
  395. public void hidePopup() {
  396. showPopup(false);
  397. }
  398. /**
  399. * Shows or hides popup-window depending on the given parameter. If there is
  400. * no such window yet, one is created.
  401. *
  402. * @param open
  403. */
  404. protected void showPopup(boolean open) {
  405. if (open && !isReadOnly()) {
  406. if (parent == null) {
  407. parent = getUI();
  408. }
  409. if (window == null) {
  410. // Create the popup
  411. window = new ColorPickerPopup(color);
  412. window.setCaption(popupCaption);
  413. window.setRGBTabVisible(rgbVisible);
  414. window.setHSVTabVisible(hsvVisible);
  415. window.setSwatchesTabVisible(swatchesVisible);
  416. window.setHistoryVisible(historyVisible);
  417. window.setPreviewVisible(textfieldVisible);
  418. window.addCloseListener(this);
  419. window.addColorChangeListener(new ColorChangeListener() {
  420. @Override
  421. public void colorChanged(ColorChangeEvent event) {
  422. AbstractColorPicker.this.colorChanged(event);
  423. }
  424. });
  425. window.getHistory().setColor(color);
  426. parent.addWindow(window);
  427. window.setVisible(true);
  428. window.setPositionX(positionX);
  429. window.setPositionY(positionY);
  430. } else if (!parent.equals(window.getParent())) {
  431. window.setRGBTabVisible(rgbVisible);
  432. window.setHSVTabVisible(hsvVisible);
  433. window.setSwatchesTabVisible(swatchesVisible);
  434. window.setHistoryVisible(historyVisible);
  435. window.setPreviewVisible(textfieldVisible);
  436. window.setColor(color);
  437. window.getHistory().setColor(color);
  438. window.setVisible(true);
  439. parent.addWindow(window);
  440. }
  441. } else if (window != null) {
  442. window.setVisible(false);
  443. parent.removeWindow(window);
  444. }
  445. getState().popupVisible = open;
  446. }
  447. /**
  448. * Set whether the caption text is rendered as HTML or not. You might need
  449. * to re-theme component to allow higher content than the original text
  450. * style.
  451. *
  452. * If set to true, the captions are passed to the browser as html and the
  453. * developer is responsible for ensuring no harmful html is used. If set to
  454. * false, the content is passed to the browser as plain text.
  455. *
  456. * @param htmlContentAllowed
  457. * <code>true</code> if caption is rendered as HTML,
  458. * <code>false</code> otherwise
  459. * @deprecated as of , use {@link #setCaptionAsHtml(boolean)} instead
  460. */
  461. @Deprecated
  462. public void setHtmlContentAllowed(boolean htmlContentAllowed) {
  463. setCaptionAsHtml(htmlContentAllowed);
  464. }
  465. /**
  466. * Return HTML rendering setting.
  467. *
  468. * @return <code>true</code> if the caption text is to be rendered as HTML,
  469. * <code>false</code> otherwise
  470. * @deprecated as of , use {@link #isCaptionAsHtml()} instead
  471. */
  472. @Deprecated
  473. public boolean isHtmlContentAllowed() {
  474. return isCaptionAsHtml();
  475. }
  476. @Override
  477. public void readDesign(Element design, DesignContext designContext) {
  478. super.readDesign(design, designContext);
  479. Attributes attributes = design.attributes();
  480. if (design.hasAttr("color")) {
  481. // Ignore the # character
  482. String hexColor = DesignAttributeHandler
  483. .readAttribute("color", attributes, String.class)
  484. .substring(1);
  485. setColor(new Color(Integer.parseInt(hexColor, 16)));
  486. }
  487. if (design.hasAttr("popup-style")) {
  488. setPopupStyle(PopupStyle.valueOf("POPUP_"
  489. + attributes.get("popup-style").toUpperCase(Locale.ROOT)));
  490. }
  491. if (design.hasAttr("position")) {
  492. String[] position = attributes.get("position").split(",");
  493. setPosition(Integer.parseInt(position[0]),
  494. Integer.parseInt(position[1]));
  495. }
  496. }
  497. @Override
  498. public void writeDesign(Element design, DesignContext designContext) {
  499. super.writeDesign(design, designContext);
  500. Attributes attribute = design.attributes();
  501. DesignAttributeHandler.writeAttribute("color", attribute,
  502. color.getCSS(), Color.WHITE.getCSS(), String.class,
  503. designContext);
  504. DesignAttributeHandler.writeAttribute("popup-style", attribute,
  505. popupStyle == PopupStyle.POPUP_NORMAL ? "normal" : "simple",
  506. "normal", String.class, designContext);
  507. DesignAttributeHandler.writeAttribute("position", attribute,
  508. positionX + "," + positionY, "0,0", String.class,
  509. designContext);
  510. }
  511. @Override
  512. protected Collection<String> getCustomAttributes() {
  513. Collection<String> result = super.getCustomAttributes();
  514. result.add("color");
  515. result.add("position");
  516. result.add("popup-style");
  517. return result;
  518. }
  519. }