From fec9e294bc016e821e16a07e6be923e17d12f8fe Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 18 Sep 2012 13:27:40 +0900 Subject: Merge sources from S-Core's RSA git (release) Change-Id: Id40e89a773ceb063b1b0a84fcc651d63cf869b98 --- .../src/org/mihalis/opal/OpalItem.java | 158 +++ .../src/org/mihalis/opal/angles/AngleSlider.java | 246 ++++ .../BrushedMetalComposite.java | 378 ++++++ .../mihalis/opal/checkBoxGroup/CheckBoxGroup.java | 323 +++++ .../mihalis/opal/columns/ColumnBrowserWidget.java | 785 ++++++++++++ .../src/org/mihalis/opal/columns/ColumnItem.java | 416 +++++++ .../org/mihalis/opal/flatButton/FlatButton.java | 633 ++++++++++ .../opal/gradientComposite/GradientComposite.java | 154 +++ .../src/org/mihalis/opal/header/Header.java | 529 ++++++++ .../org/mihalis/opal/heapManager/HeapManager.java | 297 +++++ .../opal/horizontalSpinner/HorizontalSpinner.java | 947 +++++++++++++++ .../src/org/mihalis/opal/imageSelector/ISItem.java | 114 ++ .../mihalis/opal/imageSelector/ImageSelector.java | 615 ++++++++++ .../opal/infinitePanel/InfiniteProgressPanel.java | 604 ++++++++++ .../src/org/mihalis/opal/itemSelector/DLItem.java | 105 ++ .../org/mihalis/opal/itemSelector/DualList.java | 1265 ++++++++++++++++++++ .../src/org/mihalis/opal/launcher/LLabel.java | 277 +++++ .../src/org/mihalis/opal/launcher/Launcher.java | 428 +++++++ .../org/mihalis/opal/launcher/LauncherItem.java | 32 + .../src/org/mihalis/opal/login/LoginDialog.java | 511 ++++++++ .../mihalis/opal/login/LoginDialogVerifier.java | 29 + .../org/mihalis/opal/multiChoice/MultiChoice.java | 1195 ++++++++++++++++++ .../multiChoice/MultiChoiceSelectionListener.java | 56 + .../src/org/mihalis/opal/notify/Notifier.java | 347 ++++++ .../org/mihalis/opal/notify/NotifierColors.java | 34 + .../mihalis/opal/notify/NotifierColorsFactory.java | 66 + .../org/mihalis/opal/opalDialog/ChoiceItem.java | 56 + .../org/mihalis/opal/opalDialog/ChoiceWidget.java | 301 +++++ .../src/org/mihalis/opal/opalDialog/Dialog.java | 480 ++++++++ .../org/mihalis/opal/opalDialog/DialogArea.java | 154 +++ .../org/mihalis/opal/opalDialog/FooterArea.java | 531 ++++++++ .../org/mihalis/opal/opalDialog/MessageArea.java | 541 +++++++++ .../src/org/mihalis/opal/panels/BlurredPanel.java | 151 +++ .../src/org/mihalis/opal/panels/DarkPanel.java | 144 +++ .../mihalis/opal/preferenceWindow/PWContainer.java | 45 + .../org/mihalis/opal/preferenceWindow/PWGroup.java | 169 +++ .../org/mihalis/opal/preferenceWindow/PWRow.java | 142 +++ .../mihalis/opal/preferenceWindow/PWRowGroup.java | 79 ++ .../org/mihalis/opal/preferenceWindow/PWTab.java | 111 ++ .../opal/preferenceWindow/PWTabContainer.java | 228 ++++ .../opal/preferenceWindow/PreferenceWindow.java | 306 +++++ .../ValueAndAssociatedWidgets.java | 79 ++ .../preferenceWindow/enabler/EnabledIfEquals.java | 44 + .../enabler/EnabledIfNotEquals.java | 44 + .../preferenceWindow/enabler/EnabledIfTrue.java | 46 + .../opal/preferenceWindow/enabler/Enabler.java | 57 + .../opal/preferenceWindow/widgets/PWButton.java | 63 + .../opal/preferenceWindow/widgets/PWCheckbox.java | 76 ++ .../opal/preferenceWindow/widgets/PWChooser.java | 82 ++ .../preferenceWindow/widgets/PWColorChooser.java | 133 ++ .../opal/preferenceWindow/widgets/PWCombo.java | 107 ++ .../widgets/PWDirectoryChooser.java | 78 ++ .../preferenceWindow/widgets/PWFileChooser.java | 75 ++ .../opal/preferenceWindow/widgets/PWFloatText.java | 114 ++ .../preferenceWindow/widgets/PWFontChooser.java | 95 ++ .../preferenceWindow/widgets/PWIntegerText.java | 84 ++ .../opal/preferenceWindow/widgets/PWLabel.java | 81 ++ .../preferenceWindow/widgets/PWPasswordText.java | 69 ++ .../opal/preferenceWindow/widgets/PWRadio.java | 98 ++ .../opal/preferenceWindow/widgets/PWScale.java | 91 ++ .../opal/preferenceWindow/widgets/PWSeparator.java | 78 ++ .../opal/preferenceWindow/widgets/PWSpinner.java | 86 ++ .../preferenceWindow/widgets/PWStringText.java | 68 ++ .../opal/preferenceWindow/widgets/PWText.java | 74 ++ .../opal/preferenceWindow/widgets/PWTextarea.java | 77 ++ .../opal/preferenceWindow/widgets/PWURLText.java | 98 ++ .../opal/preferenceWindow/widgets/PWWidget.java | 264 ++++ .../promptSupport/BaseFocusControlListener.java | 169 +++ .../promptSupport/CComboFocusControlListener.java | 68 ++ .../promptSupport/ComboFocusControlListener.java | 73 ++ .../promptSupport/FocusControlListenerFactory.java | 49 + .../mihalis/opal/promptSupport/PromptSupport.java | 230 ++++ .../StyledTextFocusControlListener.java | 76 ++ .../promptSupport/TextFocusControlListener.java | 75 ++ .../org/mihalis/opal/rangeSlider/RangeSlider.java | 1060 ++++++++++++++++ .../mihalis/opal/switchButton/SwitchButton.java | 938 +++++++++++++++ .../org/mihalis/opal/textAssist/TextAssist.java | 694 +++++++++++ .../opal/textAssist/TextAssistContentProvider.java | 46 + .../org/mihalis/opal/tipOfTheDay/TipOfTheDay.java | 524 ++++++++ .../opal/titledSeparator/TitledSeparator.java | 314 +++++ .../DownUpAppearTransition.java | 34 + .../opal/transitionComposite/DownUpTransition.java | 33 + .../transitionComposite/HorizontalTransition.java | 86 ++ .../LeftRightAppearTransition.java | 35 + .../transitionComposite/LeftRightTransition.java | 35 + .../opal/transitionComposite/NoTransition.java | 31 + .../RightLeftAppearTransition.java | 35 + .../transitionComposite/RightLeftTransition.java | 35 + .../opal/transitionComposite/TRANSITIONS.java | 18 + .../opal/transitionComposite/Transition.java | 28 + .../transitionComposite/TransitionComposite.java | 274 +++++ .../transitionComposite/TransitionFactory.java | 48 + .../UpDownAppearTransition.java | 34 + .../opal/transitionComposite/UpDownTransition.java | 27 + .../transitionComposite/VerticalTransition.java | 84 ++ .../src/org/mihalis/opal/utils/FileToolbox.java | 47 + .../mihalis/opal/utils/HTMLStyledTextParser.java | 179 +++ .../org/mihalis/opal/utils/ResourceManager.java | 56 + .../src/org/mihalis/opal/utils/SWTGraphicUtil.java | 463 +++++++ .../mihalis/opal/utils/SimpleSelectionAdapter.java | 47 + .../src/org/mihalis/opal/utils/StringUtil.java | 73 ++ .../tizen/common/externals/ExternalsPlugin.java | 50 + 102 files changed, 22311 insertions(+) create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/OpalItem.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/angles/AngleSlider.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/brushedMetalComposite/BrushedMetalComposite.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/checkBoxGroup/CheckBoxGroup.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnBrowserWidget.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnItem.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/flatButton/FlatButton.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/gradientComposite/GradientComposite.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/header/Header.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/heapManager/HeapManager.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/horizontalSpinner/HorizontalSpinner.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ISItem.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ImageSelector.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/infinitePanel/InfiniteProgressPanel.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DLItem.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DualList.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/launcher/LLabel.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/launcher/Launcher.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/launcher/LauncherItem.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialog.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialogVerifier.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoice.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoiceSelectionListener.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/notify/Notifier.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColors.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColorsFactory.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceItem.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceWidget.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/opalDialog/Dialog.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/opalDialog/DialogArea.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/opalDialog/FooterArea.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/opalDialog/MessageArea.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/panels/BlurredPanel.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/panels/DarkPanel.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWContainer.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWGroup.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRow.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRowGroup.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTab.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTabContainer.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PreferenceWindow.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/ValueAndAssociatedWidgets.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfEquals.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfNotEquals.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfTrue.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/Enabler.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWButton.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCheckbox.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWChooser.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWColorChooser.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCombo.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWDirectoryChooser.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFileChooser.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFloatText.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFontChooser.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWIntegerText.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWLabel.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWPasswordText.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWRadio.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWScale.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSeparator.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSpinner.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWStringText.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWText.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWTextarea.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWURLText.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWWidget.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/promptSupport/BaseFocusControlListener.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/promptSupport/CComboFocusControlListener.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/promptSupport/ComboFocusControlListener.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/promptSupport/FocusControlListenerFactory.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/promptSupport/PromptSupport.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/promptSupport/StyledTextFocusControlListener.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/promptSupport/TextFocusControlListener.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/rangeSlider/RangeSlider.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/switchButton/SwitchButton.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssist.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssistContentProvider.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/tipOfTheDay/TipOfTheDay.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/titledSeparator/TitledSeparator.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpAppearTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/HorizontalTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightAppearTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/NoTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftAppearTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TRANSITIONS.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/Transition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionComposite.java create mode 100755 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionFactory.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownAppearTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/VerticalTransition.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/utils/FileToolbox.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/utils/HTMLStyledTextParser.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/utils/ResourceManager.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/utils/SWTGraphicUtil.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/utils/SimpleSelectionAdapter.java create mode 100644 org.tizen.common.externals/src/org/mihalis/opal/utils/StringUtil.java create mode 100644 org.tizen.common.externals/src/org/tizen/common/externals/ExternalsPlugin.java (limited to 'org.tizen.common.externals/src/org') diff --git a/org.tizen.common.externals/src/org/mihalis/opal/OpalItem.java b/org.tizen.common.externals/src/org/mihalis/opal/OpalItem.java new file mode 100644 index 000000000..a06f1de32 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/OpalItem.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.mihalis.opal; + +import java.util.Map; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; + +/** + * Instances of this object are items manipulated by the widgets of the Opal Project. These items are highly customizable, you can set : + * + * You can also store data using the setData methods. + * + */ +public abstract class OpalItem { + + private Map data; + private Object datum; + private Color background; + private Font font; + private Color foreground; + private Image image; + private String text; + private int height = -1; + + /** + * @return the background color of the item + */ + public Color getBackground() { + return this.background; + } + + /** + * @return the the data stored in this item + */ + public Object getData() { + return this.datum; + } + + /** + * @param key a key + * @return the the data stored in this item associated to this key + */ + public Object getData(final String key) { + return this.data.get(key); + } + + /** + * @return the font of the item + */ + public Font getFont() { + return this.font; + } + + /** + * @return the foreground color of the item + */ + public Color getForeground() { + return this.foreground; + } + + /** + * @return the height of the item + */ + public int getHeight() { + return this.height; + } + + /** + * @return the image stored in this item + */ + public Image getImage() { + return this.image; + } + + /** + * @return the text stored in this item + */ + public String getText() { + return this.text; + } + + /** + * @param background set the background color of this item + */ + public void setBackground(final Color background) { + this.background = background; + } + + /** + * @param font set the font of this item + */ + public void setFont(final Font font) { + this.font = font; + } + + /** + * @param foreground set the foreground color of this item + */ + public void setForeground(final Color foreground) { + this.foreground = foreground; + } + + /** + * @param height set the height of this item + */ + public void setHeight(final int height) { + this.height = height; + } + + /** + * @param image set the image of this item + */ + public void setImage(final Image image) { + this.image = image; + } + + /** + * @param text set the text of this item + */ + public void setText(final String text) { + this.text = text; + } + + /** + * @param data set the data stored in this item + */ + public void setData(final Object data) { + this.datum = data; + } + + /** + * Store a data associated to a given key in this item + * + * @param key key + * @param value value associated to this key + */ + public void setData(final String key, final Object value) { + this.data.put(key, value); + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/angles/AngleSlider.java b/org.tizen.common.externals/src/org/mihalis/opal/angles/AngleSlider.java new file mode 100644 index 000000000..bf36ba771 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/angles/AngleSlider.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron@gmail.com) - initial API and implementation + * inspired by the Swing AngleSlider by Jeremy (http://javagraphics.blogspot.com/2008/05/angles-need-gui-widget-for-angles.html) + *******************************************************************************/ +package org.mihalis.opal.angles; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class provide a selectable user interface object that can + * be used to pick angles. + *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
Selection
+ *
+ */ +public class AngleSlider extends Canvas { + + private static final int WHOLE_RADIUS = 40; + private static final int BUTTON_RADIUS = 10; + private static final int STEP = 5; + + private final Image backgroundImage; + private final Image buttonFocus; + private final Image buttonNoFocus; + private int selection; + private final List selectionListeners; + private boolean mousePressed; + + /** + * Constructs a new instance of this class given its parent. + * + * @param parent a widget which will be the parent of the new instance + * (cannot be null) + * @param style not used + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ */ + public AngleSlider(final Composite parent, final int style) { + super(parent, style | SWT.DOUBLE_BUFFERED); + + this.backgroundImage = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/angleBackground.png")); + + this.buttonFocus = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/angleButtonFocus.png")); + this.buttonNoFocus = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/angleButtonFocusLost.png")); + + this.addListener(SWT.Paint, new Listener() { + + @Override + public void handleEvent(final Event event) { + paintControl(event); + } + }); + + this.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent arg0) { + SWTGraphicUtil.dispose(AngleSlider.this.backgroundImage); + SWTGraphicUtil.dispose(AngleSlider.this.buttonFocus); + SWTGraphicUtil.dispose(AngleSlider.this.buttonNoFocus); + } + }); + + this.addListener(SWT.MouseDown, createMouseListener()); + this.addListener(SWT.MouseUp, createMouseListener()); + this.addListener(SWT.MouseMove, createMouseListener()); + this.addListener(SWT.KeyDown, createKeyListener()); + + this.selection = 0; + this.selectionListeners = new ArrayList(); + + } + + private void paintControl(final Event event) { + final GC gc = event.gc; + + gc.drawImage(this.backgroundImage, 0, 0); + + float angle = this.selection / 360f; + angle = (float) (angle * 2 * Math.PI - 0.5 * Math.PI); + + final float centerX = WHOLE_RADIUS / 2f; + final float centerY = WHOLE_RADIUS / 2f; + final float radius = BUTTON_RADIUS; + final float x = (float) (centerX - radius * Math.cos(angle)); + final float y = (float) (centerY - radius * Math.sin(angle)); + + if (isFocusControl()) { + gc.drawImage(this.buttonFocus, (int) x - 2, (int) y - 2); + } else { + gc.drawImage(this.buttonNoFocus, (int) x - 2, (int) y - 2); + } + + if (!isEnabled()) { + gc.setAlpha(127); + gc.setAntialias(SWT.ON); + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.fillOval(4, 4, WHOLE_RADIUS - 7, WHOLE_RADIUS - 7); + } + } + + private Listener createMouseListener() { + return new Listener() { + + @Override + public void handleEvent(final Event event) { + if (!isEnabled()) { + return; + } + + if (event.type == SWT.MouseDown) { + AngleSlider.this.mousePressed = true; + } + if (event.type == SWT.MouseDown || event.type == SWT.MouseMove && AngleSlider.this.mousePressed) { + final float deltaX = event.x - WHOLE_RADIUS / 2f; + final float deltaY = event.y - WHOLE_RADIUS / 2f; + final double angle = Math.atan2(deltaX, deltaY); + AngleSlider.this.selection = 360 - (int) (360 * angle / (2 * Math.PI) + 360) % 360; + + AngleSlider.this.redraw(); + } + if (event.type == SWT.MouseUp) { + AngleSlider.this.mousePressed = false; + fireSelectionListeners(event); + } + } + }; + } + + private void fireSelectionListeners(final Event event) { + for (final SelectionListener selectionListener : this.selectionListeners) { + selectionListener.widgetSelected(new SelectionEvent(event)); + } + + } + + private Listener createKeyListener() { + return new Listener() { + + @Override + public void handleEvent(final Event event) { + if (!isEnabled()) { + return; + } + if (event.type != SWT.KeyDown) { + return; + } + if (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_LEFT) { + setSelection(AngleSlider.this.selection + STEP); + } + if (event.keyCode == SWT.ARROW_DOWN || event.keyCode == SWT.ARROW_RIGHT) { + setSelection(AngleSlider.this.selection - STEP); + } + } + }; + } + + /** + * @see org.eclipse.swt.widgets.Scale#addSelectionListener(org.eclipse.swt.events.SelectionListener) + */ + public void addSelectionListener(final SelectionListener selectionListener) { + checkWidget(); + this.selectionListeners.add(selectionListener); + } + + /** + * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + checkWidget(); + return new Point(WHOLE_RADIUS, WHOLE_RADIUS); + } + + /** + * @see org.eclipse.swt.widgets.Scale#getSelection() + */ + public int getSelection() { + checkWidget(); + return this.selection; + } + + /** + * @see org.eclipse.swt.widgets.Scale#removeSelectionListener(org.eclipse.swt.events.SelectionListener) + */ + public void removeSelectionListener(final SelectionListener selectionListener) { + checkWidget(); + this.selectionListeners.remove(selectionListener); + } + + /** + * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) + */ + @Override + public void setEnabled(final boolean enabled) { + super.setEnabled(enabled); + redraw(); + } + + /** + * @see org.eclipse.swt.widgets.Scale#setSelection(int) + */ + public void setSelection(final int selection) { + checkWidget(); + if (selection < 0 || selection > 360) { + SWT.error(SWT.ERROR_CANNOT_SET_SELECTION); + } + this.selection = selection; + fireSelectionListeners(new Event()); + redraw(); + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/brushedMetalComposite/BrushedMetalComposite.java b/org.tizen.common.externals/src/org/mihalis/opal/brushedMetalComposite/BrushedMetalComposite.java new file mode 100644 index 000000000..893b8c6ff --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/brushedMetalComposite/BrushedMetalComposite.java @@ -0,0 +1,378 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jerry Huxtable (http://www.jhlabs.com/index.html) - initial API and implementation (on SWING), + * Laurent CARON (laurent.caron at gmail dot com) - port to SWT + *******************************************************************************/ +package org.mihalis.opal.brushedMetalComposite; + +import java.util.Random; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Widget; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class are controls which background's texture is brushed + * metal "a la Mac" + */ +public class BrushedMetalComposite extends Composite { + + private Image oldImage; + private int radius = 10; + private float amount = 0.1f; + private int color = 0xff888888; + private float shine = 0.1f; + private boolean monochrome = true; + private Random randomNumbers; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance + * (cannot be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see SWT#NO_BACKGROUND + * @see SWT#NO_FOCUS + * @see SWT#NO_MERGE_PAINTS + * @see SWT#NO_REDRAW_RESIZE + * @see SWT#NO_RADIO_GROUP + * @see SWT#EMBEDDED + * @see SWT#DOUBLE_BUFFERED + * @see Widget#getStyle + */ + public BrushedMetalComposite(final Composite parent, final int style) { + super(parent, style); + this.addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(final Event event) { + BrushedMetalComposite.this.redrawComposite(); + } + }); + + parent.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent e) { + SWTGraphicUtil.dispose(BrushedMetalComposite.this.oldImage); + } + }); + } + + /** + * Redraws the composite + */ + private void redrawComposite() { + final Display display = this.getDisplay(); + final Rectangle rect = this.getClientArea(); + final ImageData imageData = this.drawBrushedMetalBackground(Math.max(1, rect.width), Math.max(1, rect.width)); + final Image newImage = new Image(display, imageData); + + this.setBackgroundImage(newImage); + SWTGraphicUtil.dispose(this.oldImage); + this.oldImage = newImage; + } + + /** + * Create a brushed metal background + * + * @param width width of the panel + * @param height height of the panel + * @return an image data that contains the background + */ + private ImageData drawBrushedMetalBackground(final int width, final int height) { + + final int[] inPixels = new int[width]; + final PaletteData palette = new PaletteData(0xFF0000, 0x00FF00, 0x0000FF); + final ImageData data = new ImageData(width, height, 0x20, palette); + + this.randomNumbers = new Random(0); + final int a = this.color & 0xff000000; + final int r = this.color >> 16 & 0xff; + final int g = this.color >> 8 & 0xff; + final int b = this.color & 0xff; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int tr = r; + int tg = g; + int tb = b; + if (this.shine != 0) { + final int f = (int) (255 * this.shine * Math.sin((double) x / width * Math.PI)); + tr += f; + tg += f; + tb += f; + } + if (this.monochrome) { + final int n = (int) (255 * (2 * this.randomNumbers.nextFloat() - 1) * this.amount); + inPixels[x] = a | this.clamp(tr + n) << 16 | this.clamp(tg + n) << 8 | this.clamp(tb + n); + } else { + inPixels[x] = a | this.random(tr) << 16 | this.random(tg) << 8 | this.random(tb); + } + } + + if (this.radius != 0) { + this.setDataElements(data, palette, 0, y, width, 1, this.blur(inPixels, width, this.radius)); + } else { + this.setDataElements(data, palette, 0, y, width, 1, inPixels); + } + } + + return data; + } + + /** + * Sets the data for a rectangle of pixels from a primitive array + * + * @param data the source ImageData + * @param palette the palette associated to the imageData + * @param posX The X coordinate of the upper left pixel location. + * @param posY The Y coordinate of the upper left pixel location. + * @param width Width of the pixel rectangle. + * @param height Height of the pixel rectangle + * @param pixels An array containing the pixel data to place between x,y and + * x+w-1, y+h-1. + */ + private void setDataElements(final ImageData data, final PaletteData palette, final int posX, final int posY, final int width, final int height, final int[] pixels) { + int cpt = 0; + for (int y = posY; y < posY + height; y++) { + for (int x = posX; x < posX + width; x++) { + final int rgb = pixels[cpt++]; + final int pixel = palette.getPixel(new RGB(rgb >> 16 & 0xFF, rgb >> 8 & 0xFF, rgb & 0xFF)); + data.setPixel(x, y, pixel); + data.setAlpha(x, y, rgb >> 24 & 0xFF); + } + } + } + + /** + * Add a random number to the value. The result is between 0 and 255 + * + * @param x the initial value + * @return + */ + private int random(int x) { + x += (int) (255 * (2 * this.randomNumbers.nextFloat() - 1) * this.amount); + if (x < 0) { + x = 0; + } else if (x > 0xff) { + x = 0xff; + } + return x; + } + + /** + * Clamp a number between 0 and 255 + * + * @param c the number to clamp + * @return the number. If c is negative, returns 0. If c is greater than + * 255, returns 255. + */ + private int clamp(final int c) { + if (c < 0) { + return 0; + } + + if (c > 255) { + return 255; + } + + return c; + } + + /** + * Apply a blur filter to an array of int that represents and image which + * size is width columns * 1 row + * + * @param in the array of int that represents the image + * @param width the width of the image + * @param radius the "radius" blur parameter + */ + private int[] blur(final int[] in, final int width, final int radius) { + final int[] out = new int[width]; + final int widthMinus1 = width - 1; + final int r2 = 2 * radius + 1; + int tr = 0, tg = 0, tb = 0; + + for (int i = -radius; i <= radius; i++) { + final int rgb = in[this.mod(i, width)]; + tr += rgb >> 16 & 0xff; + tg += rgb >> 8 & 0xff; + tb += rgb & 0xff; + } + + for (int x = 0; x < width; x++) { + out[x] = 0xff000000 | tr / r2 << 16 | tg / r2 << 8 | tb / r2; + + int i1 = x + radius + 1; + if (i1 > widthMinus1) { + i1 = this.mod(i1, width); + } + int i2 = x - radius; + if (i2 < 0) { + i2 = this.mod(i2, width); + } + final int rgb1 = in[i1]; + final int rgb2 = in[i2]; + + tr += (rgb1 & 0xff0000) - (rgb2 & 0xff0000) >> 16; + tg += (rgb1 & 0xff00) - (rgb2 & 0xff00) >> 8; + tb += (rgb1 & 0xff) - (rgb2 & 0xff); + } + return out; + } + + /** + * Return a mod b. This differs from the % operator with respect to negative + * numbers. + * + * @param a the dividend + * @param b the divisor + * @return a mod b + */ + private int mod(int a, final int b) { + final int n = a / b; + + a -= n * b; + if (a < 0) { + return a + b; + } + return a; + } + + // ------------------------------------ Getters and Setters + + /** + * @return the "radius" of the blur + */ + public int getRadius() { + return this.radius; + } + + /** + * @param radius the "radius" of the blur + */ + public void setRadius(final int radius) { + this.radius = radius; + this.redrawComposite(); + } + + /** + * @return the amount of noise to add + */ + public float getAmount() { + return this.amount; + } + + /** + * @param amount the amount of noise to add + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the value is not between 0 + * and 1 inclusive
  • + *
+ */ + public void setAmount(final float amount) { + if (amount < 0f || amount > 1f) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.amount = amount; + this.redrawComposite(); + } + + /** + * @return the color of the metal. Please notice that this color is a new + * SWT object, so it has to be disposed ! + */ + public Color getColor() { + return new Color(this.getDisplay(), this.color >> 16 & 0xFF, this.color >> 8 & 0xFF, this.color & 0xFF); + } + + /** + * @param color the color to set + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the value is null
  • + *
+ */ + public void setColor(final Color color) { + if (color == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + this.color = 0xFF << 24 | color.getRed() << 16 | color.getGreen() << 8 | color.getBlue(); + this.redrawComposite(); + } + + /** + * @return the shine to add + */ + public float getShine() { + return this.shine; + } + + /** + * @param shine the shine to set + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the value is not between 0 + * and 1 inclusive
  • + *
+ */ + public void setShine(final float shine) { + if (this.amount < 0f || this.amount > 1f) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.shine = shine; + this.redrawComposite(); + } + + /** + * @return the monochrome + */ + public boolean isMonochrome() { + return this.monochrome; + } + + /** + * @param monochrome the monochrome to set + */ + public void setMonochrome(final boolean monochrome) { + this.monochrome = monochrome; + this.redrawComposite(); + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/checkBoxGroup/CheckBoxGroup.java b/org.tizen.common.externals/src/org/mihalis/opal/checkBoxGroup/CheckBoxGroup.java new file mode 100644 index 000000000..d8ec1e34a --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/checkBoxGroup/CheckBoxGroup.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.checkBoxGroup; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Widget; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class provide an etched border with a title and a checkbox. + * If the checkbox is checked, the content of the composite is enabled. If the + * checkbox is unchecked, the content of the composite is disabled, thus not + * editable. + *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
(none)
+ *
+ */ +public class CheckBoxGroup extends Composite { + private Image oldImage; + protected final Button button; + private final Composite content; + private final List selectionListeners; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance + * (cannot be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see SWT#BORDER + * @see Widget#getStyle + */ + public CheckBoxGroup(final Composite parent, final int style) { + super(parent, style); + super.setLayout(new GridLayout()); + this.selectionListeners = new ArrayList(); + + this.button = new Button(this, SWT.CHECK); + final GridData gdButton = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); + gdButton.horizontalIndent = 15; + this.button.setLayoutData(gdButton); + this.button.setSelection(true); + this.button.setBackground(this.getBackground()); + this.button.pack(); + + this.button.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + e.doit = fireSelectionListeners(e); + if (!e.doit) { + return; + } + if (CheckBoxGroup.this.button.getSelection()) { + CheckBoxGroup.this.activate(); + } else { + CheckBoxGroup.this.deactivate(); + } + } + }); + + this.content = new Composite(this, SWT.NONE); + this.content.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + + this.addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(final Event event) { + CheckBoxGroup.this.drawWidget(); + } + }); + + } + + /** + * Fire the selection listeners + * + * @param selectionEvent mouse event + * @return true if the selection could be changed, false otherwise + */ + private boolean fireSelectionListeners(final SelectionEvent selectionEvent) { + selectionEvent.widget = this; + for (final SelectionListener listener : this.selectionListeners) { + listener.widgetSelected(selectionEvent); + if (!selectionEvent.doit) { + return false; + } + } + return true; + } + + /** + * Draws the widget + */ + private void drawWidget() { + final Display display = this.getDisplay(); + final Rectangle rect = this.getClientArea(); + final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height)); + + final GC gc = new GC(newImage); + gc.setBackground(this.getBackground()); + + gc.fillRectangle(0, 0, rect.width, rect.height); + + final int margin = (int) (this.button.getSize().y * 1.5); + final int startY = margin / 2; + + gc.setForeground(this.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + gc.drawRoundRectangle(1, startY, rect.width - 2, rect.height - startY - 2, 2, 2); + + gc.setForeground(this.getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); + gc.drawRoundRectangle(2, startY + 1, rect.width - 4, rect.height - startY - 4, 2, 2); + + gc.dispose(); + + this.setBackgroundImage(newImage); + if (this.oldImage != null) { + this.oldImage.dispose(); + } + this.oldImage = newImage; + + } + + /** + * Activate the content + */ + public void activate() { + this.button.setSelection(true); + SWTGraphicUtil.enable(this.content, true); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the user changes the receiver's selection, by sending it one of the + * messages defined in the SelectionListener interface. + *

+ * When widgetSelected is called, the item field of the event + * object is valid. If the receiver has the SWT.CHECK style and + * the check selection changes, the event object detail field contains the + * value SWT.CHECK. widgetDefaultSelected is + * typically called when an item is double-clicked. The item field of the + * event object is valid for default selection, but the detail field is not + * used. + *

+ * + * @param listener the listener which should be notified when the user + * changes the receiver's selection + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + this.selectionListeners.add(listener); + } + + /** + * Deactivate the content + */ + public void deactivate() { + this.button.setSelection(false); + SWTGraphicUtil.enable(this.content, false); + } + + /** + * @return true if the content is activated, false + * otherwise + */ + public boolean isActivated() { + return this.button.getSelection(); + } + + /** + * @see org.eclipse.swt.widgets.Composite#getLayout() + */ + @Override + public Layout getLayout() { + return this.content.getLayout(); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + this.selectionListeners.remove(listener); + } + + /** + * @see org.eclipse.swt.widgets.Composite#setFocus() + */ + @Override + public boolean setFocus() { + return this.content.setFocus(); + } + + /** + * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout) + */ + @Override + public void setLayout(final Layout layout) { + this.content.setLayout(layout); + } + + // ------------------------------------ Getters and Setters + + /** + * @return the text of the button + */ + public String getText() { + return this.button.getText(); + } + + /** + * @param text the text of the button to set + */ + public void setText(final String text) { + this.button.setText(text); + } + + /** + * @return the font of the button + */ + @Override + public Font getFont() { + return this.button.getFont(); + } + + /** + * @param font the font to set + */ + @Override + public void setFont(final Font font) { + this.button.setFont(font); + } + + /** + * @return the content of the group + */ + public Composite getContent() { + return this.content; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnBrowserWidget.java b/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnBrowserWidget.java new file mode 100755 index 000000000..991f6a210 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnBrowserWidget.java @@ -0,0 +1,785 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.columns; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Widget; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class provide a data browser similar to the ones used in + * Mac OS X. Look at http://en.wikipedia.org/wiki/Miller_Columns + *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
Selection
+ *
+ */ +public class ColumnBrowserWidget extends ScrolledComposite { + + private final List columns; + private final Composite composite; + private final Image columnArrow; + private final List selectionListeners; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance + * (cannot be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see SWT#BORDER + * @see Widget#getStyle + */ + public ColumnBrowserWidget(final Composite parent, final int style) { + super(parent, style | SWT.H_SCROLL | SWT.V_SCROLL); + + this.composite = new Composite(this, SWT.NONE); + final RowLayout layout = new RowLayout(SWT.HORIZONTAL); + layout.spacing = 1; + layout.pack = false; + this.composite.setLayout(layout); + + this.columnArrow = SWTGraphicUtil.createImage("images/columnArrow.png"); + + this.columns = new ArrayList
(); + for (int i = 0; i < 3; i++) { + this.createTable(); + } + + // Store root + this.columns.get(0).setData(new ColumnItem(this)); + + this.setContent(this.composite); + this.setExpandHorizontal(true); + this.setExpandVertical(true); + this.setShowFocusedControl(true); + this.updateContent(); + this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + + this.selectionListeners = new ArrayList(); + + this.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent arg0) { + SWTGraphicUtil.dispose(ColumnBrowserWidget.this.columnArrow); + } + }); + + } + + /** + * Create a column that displays data + */ + private void createTable() { + final Table table = new Table(this.composite, SWT.SINGLE | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + new TableColumn(table, SWT.LEFT); + + table.setLayoutData(new RowData(150, 175)); + this.columns.add(table); + + table.addListener(SWT.Resize, new Listener() { + + @Override + public void handleEvent(final Event event) { + final int width = table.getSize().x; + table.getColumn(0).setWidth(width - 5); + } + }); + + table.addListener(SWT.Selection, new Listener() { + @Override + public void handleEvent(final Event event) { + final Table table = (Table) event.widget; + if (table.getSelection() == null || table.getSelection().length != 1) { + return; + } + ColumnBrowserWidget.this.selectItem(table.getSelection()[0]); + } + }); + + final Listener paintListener = new Listener() { + @Override + public void handleEvent(final Event event) { + switch (event.type) { + case SWT.MeasureItem: { + final Rectangle rect = ColumnBrowserWidget.this.columnArrow.getBounds(); + event.width += rect.width; + event.height = Math.max(event.height, rect.height + 2); + break; + } + + case SWT.PaintItem: { + if (!(event.item instanceof TableItem)) { + return; + } + final TableItem item = (TableItem) event.item; + if (item.getData() == null) { + return; + } + + if (((ColumnItem) item.getData()).getItemCount() == 0) { + return; + } + + final int x = event.x + event.width; + final Rectangle rect = ColumnBrowserWidget.this.columnArrow.getBounds(); + final int offset = Math.max(0, (event.height - rect.height) / 2); + event.gc.drawImage(ColumnBrowserWidget.this.columnArrow, x, event.y + offset); + break; + } + default: + break; + } + } + }; + table.addListener(SWT.MeasureItem, paintListener); + table.addListener(SWT.PaintItem, paintListener); + + table.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(final SelectionEvent e) { + ColumnBrowserWidget.this.fireSelectionListeners(e); + } + + @Override + public void widgetDefaultSelected(final SelectionEvent e) { + ColumnBrowserWidget.this.fireSelectionListeners(e); + } + }); + + if (super.getBackground() != null && super.getBackground().getRed() != 240 && super.getBackground().getGreen() != 240 && super.getBackground().getBlue() != 240) { + table.setBackground(super.getBackground()); + } + table.setBackgroundImage(super.getBackgroundImage()); + table.setBackgroundMode(super.getBackgroundMode()); + table.setCursor(super.getCursor()); + table.setFont(super.getFont()); + table.setForeground(super.getForeground()); + table.setMenu(super.getMenu()); + table.setToolTipText(super.getToolTipText()); + + } + + /** + * Fire the selection listeners + * + * @param selectionEvent mouse event + * @return true if the selection could be changed, false otherwise + */ + private boolean fireSelectionListeners(final SelectionEvent selectionEvent) { + for (final SelectionListener listener : this.selectionListeners) { + final Event event = new Event(); + + event.button = 0; + event.display = this.getDisplay(); + event.item = null; + event.widget = this; + event.data = null; + event.time = selectionEvent.time; + event.x = selectionEvent.x; + event.y = selectionEvent.y; + + final SelectionEvent selEvent = new SelectionEvent(event); + listener.widgetSelected(selEvent); + if (!selEvent.doit) { + return false; + } + } + return true; + } + + /** + * Perform actions when an item is selected (ie fill the next column and + * force focus on it) + * + * @param tableItem selected item + */ + private void selectItem(final TableItem tableItem) { + final ColumnItem c = (ColumnItem) tableItem.getData(); + + if (c.getItemCount() == 0) { + return; + } + + final int selectedColumn = this.findSelectedColumn(tableItem); + boolean needPacking = false; + if (selectedColumn != this.columns.size() - 1) { + for (int i = selectedColumn + 1; i < this.columns.size(); i++) { + this.columns.get(i).setData(null); + this.columns.get(i).deselectAll(); + } + + int i = 0; + final Iterator
it = this.columns.iterator(); + while (it.hasNext()) { + final Table t = it.next(); + if (i >= 3) { + t.dispose(); + it.remove(); + // Don't know why, it's not working if I do not include this + // :( + this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + i++; + } + + if (selectedColumn != this.columns.size() - 1) { + this.columns.get(selectedColumn + 1).setData(c); + } else { + this.createTable(); + this.columns.get(this.columns.size() - 1).setData(c); + } + needPacking = true; + + } else { + this.createTable(); + needPacking = true; + this.columns.get(this.columns.size() - 1).setData(c); + } + this.updateContent(); + if (needPacking) { + this.composite.pack(); + this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + this.columns.get(this.columns.size() - 1).forceFocus(); + } + + /** + * Find which column has been selected + * + * @param tableItem selected table item + * @return the index of the selected column + */ + private int findSelectedColumn(final TableItem tableItem) { + for (int i = 0; i < this.columns.size(); i++) { + if (this.columns.get(i).equals(tableItem.getParent())) { + return i; + } + } + return -1; + } + + /** + * Update the content of the widget + */ + void updateContent() { + if (this.columns == null) { + return; + } + + for (int i = 0; i < this.columns.size(); i++) { + + final Table table = this.columns.get(i); + final int index = table.getSelectionIndex(); + table.removeAll(); + if (table.getData() == null) { + continue; + } + for (final ColumnItem c : ((ColumnItem) table.getData()).getItems()) { + final TableItem item = new TableItem(table, SWT.NONE); + item.setData(c); + if (c.getText() != null) { + item.setText(c.getText()); + } + if (c.getImage() != null) { + item.setImage(c.getImage()); + } + } + table.setSelection(index); + } + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the user changes the receiver's selection, by sending it one of the + * messages defined in the SelectionListener interface. + *

+ * When widgetSelected is called, the item field of the event + * object is valid. If the receiver has the SWT.CHECK style and + * the check selection changes, the event object detail field contains the + * value SWT.CHECK. widgetDefaultSelected is + * typically called when an item is double-clicked. The item field of the + * event object is valid for default selection, but the detail field is not + * used. + *

+ * + * @param listener the listener which should be notified when the user + * changes the receiver's selection + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + this.selectionListeners.add(listener); + } + + /** + * Clear the selection + * + * @param needPacking if true, the widget is packed + */ + public void clear(final boolean needPacking) { + final Iterator
it = this.columns.iterator(); + int i = 0; + while (it.hasNext()) { + final Table t = it.next(); + if (i >= 3) { + t.dispose(); + it.remove(); + } else { + if (i != 0) { + t.setData(null); + } + t.deselectAll(); + } + i++; + } + this.updateContent(); + if (needPacking) { + this.composite.pack(); + this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + this.columns.get(0).forceFocus(); + } + + /** + * Returns the ColumnItems that is currently selected in the + * receiver. + * + * @return the selected item, or null if no one is selected + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public ColumnItem getSelection() { + for (int i = this.columns.size() - 1; i >= 0; i--) { + final Table table = this.columns.get(i); + if (table == null || table.getData() == null || table.getSelection().length == 0) { + continue; + } + + return (ColumnItem) table.getItem(table.getSelectionIndex()).getData(); + + } + return null; + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + this.selectionListeners.remove(listener); + } + + /** + * Selects an item in the receiver. If the item was already selected, it + * remains selected. + * + * @param item the item to be selected + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed + *
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void select(final ColumnItem item) { + + final List items = new ArrayList(); + this.findElement(item, items); + Collections.reverse(items); + if (items.isEmpty()) { + return; + } + + this.clear(false); + for (int i = 3; i < items.size(); i++) { + this.createTable(); + } + for (int i = 0; i < items.size() - 1; i++) { + this.columns.get(i + 1).setData(items.get(i)); + } + this.updateContent(); + + for (int i = 0; i < this.columns.size() - 1; i++) { + final ColumnItem nextItem = (ColumnItem) this.columns.get(i + 1).getData(); + for (final TableItem tableItem : this.columns.get(i).getItems()) { + if (tableItem.getData() != null && tableItem.getData().equals(nextItem)) { + tableItem.getParent().setSelection(tableItem); + } + } + } + + this.composite.pack(); + this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + this.columns.get(this.columns.size() - 1).forceFocus(); + + } + + /** + * Build an array that contains the hierarchy of ColumnItem from the root + * node to a given item. + * + * @param item item to find + * @param items the lists of item that composes the hierarchy + */ + private void findElement(final ColumnItem item, final List items) { + if (item == null) { + return; + } + items.add(item); + this.findElement(item.getParentItem(), items); + } + + /** + * Sets the receiver's background color to the color specified by the + * argument, or to the default system color for the control if the argument + * is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. For + * example, on Windows the background of a Button cannot be changed. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setBackground(final Color color) { + super.setBackground(color); + for (final Table column : this.columns) { + column.setBackground(color); + } + } + + /** + * Sets the background drawing mode to the argument which should be one of + * the following constants defined in class SWT: + * INHERIT_NONE, INHERIT_DEFAULT, + * INHERIT_FORCE. + * + * @param mode the new background mode + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SWT + * @see org.eclipse.swt.widgets.Composite#setBackgroundMode(int) + */ + @Override + public void setBackgroundMode(final int mode) { + super.setBackgroundMode(mode); + for (final Table column : this.columns) { + column.setBackgroundMode(mode); + } + } + + /** + * Sets the receiver's background image to the image specified by the + * argument, or to the default system color for the control if the argument + * is null. The background image is tiled to fill the available space. + *

+ * Note: This operation is a hint and may be overridden by the platform. For + * example, on Windows the background of a Button cannot be changed. + *

+ * + * @param image the new image (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_INVALID_ARGUMENT - if the argument is not a + * bitmap
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see org.eclipse.swt.widgets.Control#setBackgroundImage(org.eclipse.swt.graphics.Image) + */ + @Override + public void setBackgroundImage(final Image image) { + super.setBackgroundImage(image); + for (final Table column : this.columns) { + column.setBackgroundImage(image); + } + } + + /** + * Sets the receiver's cursor to the cursor specified by the argument, or to + * the default cursor for that kind of control if the argument is null. + *

+ * When the mouse pointer passes over a control its appearance is changed to + * match the control's cursor. + *

+ * + * @param cursor the new cursor (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setCursor(org.eclipse.swt.graphics.Cursor) + */ + @Override + public void setCursor(final Cursor cursor) { + super.setCursor(cursor); + for (final Table column : this.columns) { + column.setCursor(cursor); + } + } + + /** + * Sets the font that the receiver will use to paint textual information to + * the font specified by the argument, or to the default font for that kind + * of control if the argument is null. + * + * @param font the new font (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font) + */ + @Override + public void setFont(final Font font) { + super.setFont(font); + for (final Table column : this.columns) { + column.setFont(font); + } + } + + /** + * Sets the receiver's foreground color to the color specified by the + * argument, or to the default system color for the control if the argument + * is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setForeground(final Color color) { + super.setForeground(color); + for (final Table column : this.columns) { + column.setForeground(color); + } + } + + /** + * Sets the receiver's pop up menu to the argument. All controls may + * optionally have a pop up menu that is displayed when the user requests + * one for the control. The sequence of key strokes, button presses and/or + * button releases that are used to request a pop up menu is platform + * specific. + *

+ * Note: Disposing of a control that has a pop up menu will dispose of the + * menu. To avoid this behavior, set the menu to null before the control is + * disposed. + *

+ * + * @param menu the new pop up menu + * + * @exception IllegalArgumentException
    + *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • + *
  • ERROR_INVALID_PARENT - if the menu is not in the same + * widget tree
  • + *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed + *
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu) + */ + @Override + public void setMenu(final Menu menu) { + super.setMenu(menu); + for (final Table column : this.columns) { + column.setMenu(menu); + } + } + + /** + * Sets the receiver's tool tip text to the argument, which may be null + * indicating that the default tool tip for the control will be shown. For a + * control that has a default tool tip, such as the Tree control on Windows, + * setting the tool tip text to an empty string replaces the default, + * causing no tool tip text to be shown. + *

+ * The mnemonic indicator (character '&') is not displayed in a tool + * tip. To display a single '&' in the tool tip, the character '&' + * can be escaped by doubling it in the string. + *

+ * + * @param string the new tool tip text (or null) + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String) + */ + @Override + public void setToolTipText(final String tooltipText) { + super.setToolTipText(tooltipText); + for (final Table column : this.columns) { + column.setToolTipText(tooltipText); + } + } + + /** + * @return the root item, or null if there is no data + */ + ColumnItem getRootItem() { + if (this.columns == null || this.columns.isEmpty()) { + return null; + } + return (ColumnItem) this.columns.get(0).getData(); + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnItem.java b/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnItem.java new file mode 100644 index 000000000..52d63fa70 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnItem.java @@ -0,0 +1,416 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.columns; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.mihalis.opal.OpalItem; + +/** + * Instances of this object are items manipulated by the ColumnBrowser widget. + * ColumnItems are part of a tree structure . + * + * @see OpalItem + */ +public class ColumnItem extends OpalItem { + + private final ColumnBrowserWidget widget; + private final ColumnItem parent; + private final List children; + + /** + * Constructs a new instance of this class given its parent. The item is + * added to the end of the items maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnBrowserWidget widget) { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + this.widget = widget; + this.parent = null; + this.children = new ArrayList(); + + if (widget.getRootItem() != null) { + widget.getRootItem().children.add(this); + } + widget.updateContent(); + } + + /** + * Constructs a new instance of this class given its parent. The item is + * added at a given position in the items'list maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * @param index the position + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnBrowserWidget widget, final int index) { + + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + this.widget = widget; + this.parent = null; + this.children = new ArrayList(); + widget.getRootItem().children.add(index, this); + widget.updateContent(); + } + + /** + * Constructs a new instance of this class given its parent. The item is + * added to the end of the items maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnItem parent) { + + if (parent == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (parent.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + this.widget = parent.widget; + this.parent = parent; + this.children = new ArrayList(); + parent.children.add(this); + parent.widget.updateContent(); + } + + /** + * Constructs a new instance of this class given its parent. The item is + * added at a given position in the items'list maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * @param index the position + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnItem parent, final int index) { + if (parent == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (parent.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + this.widget = parent.widget; + this.parent = parent; + this.children = new ArrayList(); + parent.children.add(index, this); + parent.widget.updateContent(); + } + + /** + * Remove a given children of this object + * + * @param item the item to remove (can not be null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public void remove(final ColumnItem item) { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + this.children.remove(item); + this.widget.updateContent(); + } + + /** + * Remove a children in a given position of this object + * + * @param index position of the children in the items'list + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public void remove(final int index) { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + this.children.remove(index); + this.widget.updateContent(); + } + + /** + * Remove all children of this object + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public void removeAll() { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + this.children.clear(); + this.widget.updateContent(); + } + + /** + * Returns an item located at a given position + * + * @param index position + * @return the item located at the index position + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem getItem(final int index) { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return this.children.get(index); + } + + /** + * @return the number of children + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public int getItemCount() { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return this.children.size(); + } + + /** + * @return all children of this item + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem[] getItems() { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return this.children.toArray(new ColumnItem[this.children.size()]); + } + + /** + * @return the widget that holds this item + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnBrowserWidget getParent() { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return this.widget; + } + + /** + * @return the parent item, of null if this item is the root + * node + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem getParentItem() { + if (this.widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (this.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return this.parent; + } + + /** + * Return the position of a given item in children's list + * + * @param item item to find + * @return the position of the children, or -1 if item is a not + * a children of this object + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public int indexOf(final ColumnItem item) { + return this.children.indexOf(item); + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (this.parent == null ? 0 : this.parent.hashCode()); + result = prime * result + (this.widget == null ? 0 : this.widget.hashCode()); + return result; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ColumnItem other = (ColumnItem) obj; + if (this.children == null) { + if (other.children != null) { + return false; + } + } else if (!this.children.equals(other.children)) { + return false; + } + if (this.parent == null) { + if (other.parent != null) { + return false; + } + } else if (!this.parent.equals(other.parent)) { + return false; + } + if (this.widget == null) { + if (other.widget != null) { + return false; + } + } else if (!this.widget.equals(other.widget)) { + return false; + } + return true; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/flatButton/FlatButton.java b/org.tizen.common.externals/src/org/mihalis/opal/flatButton/FlatButton.java new file mode 100644 index 000000000..ede14ba2f --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/flatButton/FlatButton.java @@ -0,0 +1,633 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.mihalis.opal.flatButton; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class represent a flat button. + *
+ *
Styles:
+ *
(none)
+ *
UP, DOWN, LEFT, RIGHT, CENTER
+ *
Events:
+ *
Selection
+ *
+ *

+ * Note: Only one of the styles LEFT, RIGHT, and CENTER may be specified. + *

+ * + */ +public class FlatButton extends Canvas { + private Image image; + private String text; + private boolean selection; + private int alignment; + private final List listeners; + private boolean mouseIn; + private Color backgroundColor; + private Color selectedColor; + private Color selectedTextColor; + private Color mouseOverColor; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an + * allowed subclass
  • + *
+ * + * @see SWT#DOWN + * @see SWT#LEFT + * @see SWT#RIGHT + * @see SWT#CENTER + */ + public FlatButton(final Composite parent, final int style) { + super(parent, style); + this.listeners = new ArrayList(); + buildAlignmentFromStyle(style); + addListeners(); + initializeDefaultColors(); + } + + private void buildAlignmentFromStyle(final int style) { + if ((style & SWT.LEFT) == SWT.LEFT) { + this.alignment = SWT.LEFT; + } else if ((style & SWT.RIGHT) == SWT.RIGHT) { + this.alignment = SWT.RIGHT; + } else { + this.alignment = SWT.CENTER; + + } + } + + private void addListeners() { + addPaintListener(new PaintListener() { + @Override + public void paintControl(final PaintEvent e) { + FlatButton.this.paintControl(e); + } + }); + + addListener(SWT.MouseEnter, new Listener() { + @Override + public void handleEvent(final Event event) { + FlatButton.this.mouseIn = true; + redraw(); + } + }); + + addListener(SWT.MouseExit, new Listener() { + @Override + public void handleEvent(final Event event) { + FlatButton.this.mouseIn = false; + redraw(); + } + }); + + addListener(SWT.MouseUp, new Listener() { + @Override + public void handleEvent(final Event event) { + boolean doIt = true; + FlatButton.this.selection = !FlatButton.this.selection; + for (final SelectionListener listener : FlatButton.this.listeners) { + final SelectionEvent sEvent = new SelectionEvent(event); + listener.widgetSelected(sEvent); + doIt = doIt && sEvent.doit; + } + if (!doIt) { + FlatButton.this.selection = !FlatButton.this.selection; + } + } + + }); + } + + private void initializeDefaultColors() { + this.backgroundColor = getDisplay().getSystemColor(SWT.COLOR_WHITE); + this.selectedColor = new Color(getDisplay(), 0, 112, 192); + this.selectedTextColor = getDisplay().getSystemColor(SWT.COLOR_WHITE); + this.mouseOverColor = new Color(getDisplay(), 235, 234, 226); + + SWTGraphicUtil.dispose(this, this.selectedColor); + SWTGraphicUtil.dispose(this, this.mouseOverColor); + SWTGraphicUtil.dispose(this, this.image); + } + + private void paintControl(final PaintEvent e) { + final GC gc = e.gc; + drawBackground(gc); + if (this.image != null) { + drawImage(gc); + } + if (this.text != null) { + drawText(gc); + } + } + + private void drawBackground(final GC gc) { + Color color; + if (this.selection) { + color = this.selectedColor; + } else if (this.mouseIn) { + color = this.mouseOverColor; + } else { + color = this.backgroundColor; + } + gc.setBackground(color); + gc.fillRectangle(getClientArea()); + + } + + private void drawImage(final GC gc) { + final Rectangle rect = getClientArea(); + final Point imageSize = new Point(this.image.getBounds().width, this.image.getBounds().height); + + int x; + if (this.alignment == SWT.LEFT) { + x = 5; + } else if (this.alignment == SWT.RIGHT) { + x = rect.width - imageSize.x - 5; + } else { + x = (rect.width - imageSize.x) / 2; + } + gc.drawImage(this.image, x, 5); + } + + private void drawText(final GC gc) { + final Rectangle rect = getClientArea(); + + if (this.selection) { + gc.setForeground(this.selectedTextColor); + } else { + gc.setForeground(getForeground()); + } + + gc.setFont(getFont()); + final Point textSize = gc.stringExtent(this.text); + int x, y; + + if (this.alignment == SWT.LEFT) { + x = 5; + } else if (this.alignment == SWT.RIGHT) { + x = rect.width - textSize.x - 5; + } else { + x = (rect.width - textSize.x) / 2; + } + if (this.image == null) { + y = 5; + } else { + y = 10 + this.image.getBounds().height; + } + gc.drawString(this.text, x, y, true); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the control is selected by the user, by sending it one of the + * messages defined in the SelectionListener interface. + *

+ * widgetSelected is called when the control is selected by the + * user. widgetDefaultSelected is not called. + *

+ *

+ * When the SWT.RADIO style bit is set, the + * widgetSelected method is also called when the receiver loses + * selection because another item in the same radio group was selected by + * the user. During widgetSelected the application can use + * getSelection() to determine the current selected state of + * the receiver. + *

+ * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + this.listeners.add(listener); + } + + /** + * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + int width = 10, height = 15; + if (this.image != null) { + final Rectangle bounds = this.image.getBounds(); + width += bounds.width; + height += bounds.height; + } + + if (this.text != null) { + final GC gc = new GC(this); + final Point extent = gc.stringExtent(this.text); + gc.dispose(); + width = Math.max(width, extent.x + 10); + height = height + extent.y; + } + + return new Point(Math.max(width, wHint), Math.max(height, hHint)); + } + + /** + * Returns a value which describes the position of the text in the receiver. + * The value will be one of LEFT, RIGHT or + * CENTER. + * + * @return the alignment + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getAlignment() { + checkWidget(); + return this.alignment; + } + + /** + * Returns a value which describes the default background color + * + * @return the default background color + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getBackgroundColor() { + checkWidget(); + return this.backgroundColor; + } + + /** + * Returns the receiver's image if it has one, or null if it does not. + * + * @return the receiver's image + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getImage() { + checkWidget(); + return this.image; + } + + /** + * Returns a value which describes the color when the mouse is over the + * button + * + * @return the color when the mouse is over the button + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getMouseOverColor() { + checkWidget(); + return this.mouseOverColor; + } + + /** + * Returns a value which describes the color when the button is selected + * + * @return the color when the button is selected + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getSelectedColor() { + checkWidget(); + return this.selectedColor; + } + + /** + * Returns a value which describes the color of the text when the button is + * selected + * + * @return the color of the text when the button is selected + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + + public Color getSelectedTextColor() { + return this.selectedTextColor; + } + + /** + * Returns true if the receiver is selected, and false + * otherwise. + *

+ * + * @return the selection state + * + * @exception SWTException

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • ERROR_THREAD_INVALID_ACCESS - if not + * called from the thread that created the receiver
  • + *
+ */ + public boolean getSelection() { + checkWidget(); + return this.selection; + } + + /** + * Returns the receiver's text. + * + * @return the receiver's text + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getText() { + checkWidget(); + return this.text; + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + this.listeners.remove(listener); + } + + /** + * Controls how text, images and arrows will be displayed in the receiver. + * The argument should be one of LEFT, RIGHT or + * CENTER. + * + * @param alignment the new alignment + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setAlignment(final int alignment) { + checkWidget(); + if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) { + return; + } + this.alignment = alignment; + redraw(); + } + + /** + * Sets the receiver's background color to the color specified by the + * argument. + * + * @param color the new color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBackgroundColor(final Color backgroundColor) { + checkWidget(); + this.backgroundColor = backgroundColor; + } + + /** + * Sets the receiver's image to the argument, which may be null + * indicating that no image should be displayed. + *

+ * Note that a Button can display an image and text simultaneously on + * Windows (starting with XP), GTK+ and OSX. On other platforms, a Button + * that has an image and text set into it will display the image or text + * that was set most recently. + *

+ * + * @param image the image to display on the receiver (may be + * null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setImage(final Image image) { + checkWidget(); + this.image = image; + redraw(); + } + + /** + * Sets the receiver's color when the mouse if over the button. + * + * @param color the new color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setMouseOverColor(final Color mouseOverColor) { + checkWidget(); + this.mouseOverColor = mouseOverColor; + } + + /** + * Sets the receiver's color when the button is selected. + * + * @param color the new color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelectedColor(final Color selectedColor) { + checkWidget(); + this.selectedColor = selectedColor; + } + + /** + * Sets the receiver's text color when the button is selected. + * + * @param color the new color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelectedTextColor(final Color selectedTextColor) { + this.selectedTextColor = selectedTextColor; + } + + /** + * Sets the selection state of the receiver. + * + * @param selected the new selection state + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelection(final boolean selected) { + checkWidget(); + this.selection = selected; + redraw(); + } + + /** + * Sets the receiver's text. + * + * + * @param string the new text + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setText(final String text) { + checkWidget(); + this.text = text; + redraw(); + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/gradientComposite/GradientComposite.java b/org.tizen.common.externals/src/org/mihalis/opal/gradientComposite/GradientComposite.java new file mode 100644 index 000000000..80e5c6736 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/gradientComposite/GradientComposite.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.gradientComposite; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Widget; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class are controls which background's texture is a gradient + * composite + */ +public class GradientComposite extends Composite { + private Image oldImage; + private Color gradientEnd; + private Color gradientStart; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance + * (cannot be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see SWT#NO_BACKGROUND + * @see SWT#NO_FOCUS + * @see SWT#NO_MERGE_PAINTS + * @see SWT#NO_REDRAW_RESIZE + * @see SWT#NO_RADIO_GROUP + * @see SWT#EMBEDDED + * @see SWT#DOUBLE_BUFFERED + * @see Widget#getStyle + */ + public GradientComposite(final Composite parent, final int style) { + super(parent, style); + this.addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(final Event event) { + GradientComposite.this.redrawComposite(); + } + }); + + parent.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent e) { + SWTGraphicUtil.dispose(GradientComposite.this.oldImage); + SWTGraphicUtil.dispose(GradientComposite.this.gradientEnd); + SWTGraphicUtil.dispose(GradientComposite.this.gradientStart); + } + + }); + + this.gradientEnd = new Color(this.getDisplay(), 110, 110, 110); + this.gradientStart = new Color(this.getDisplay(), 0, 0, 0); + + } + + /** + * Redraws the composite + */ + private void redrawComposite() { + final Display display = this.getDisplay(); + final Rectangle rect = this.getClientArea(); + final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height)); + + final GC gc = new GC(newImage); + gc.setForeground(this.gradientStart); + gc.setBackground(this.gradientEnd); + + gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height / 2, true); + + gc.setForeground(this.gradientEnd); + gc.setBackground(this.gradientStart); + + gc.fillGradientRectangle(rect.x, rect.height / 2, rect.width, rect.height / 2, true); + gc.dispose(); + + this.setBackgroundImage(newImage); + if (this.oldImage != null) { + this.oldImage.dispose(); + } + this.oldImage = newImage; + + } + + // ------------------------------------ Getters and Setters + /** + * @return the gradientEnd color + */ + public Color getGradientEnd() { + return this.gradientEnd; + } + + /** + * @param gradientEnd the gradientEnd color to set + */ + public void setGradientEnd(final Color gradientEnd) { + SWTGraphicUtil.dispose(this.gradientEnd); + this.gradientEnd = gradientEnd; + } + + /** + * @return the gradientStart color + */ + public Color getGradientStart() { + return this.gradientStart; + } + + /** + * @param gradientStart the gradientStart color to set + */ + public void setGradientStart(final Color gradientStart) { + SWTGraphicUtil.dispose(this.gradientStart); + this.gradientStart = gradientStart; + } +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/header/Header.java b/org.tizen.common.externals/src/org/mihalis/opal/header/Header.java new file mode 100644 index 000000000..6cdd42366 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/header/Header.java @@ -0,0 +1,529 @@ +package org.mihalis.opal.header; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class provide a header, which is composed of a text, a + * description and an image. + *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
(none)
+ *
+ */ +public class Header extends Composite { + + private Image image; + private String title; + private String description; + private Font titleFont; + private Color titleColor; + + private Image oldImage; + private Color gradientEnd; + private Color gradientStart; + private Color separatorColor; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public Header(final Composite parent, final int style) { + super(parent, style); + + final FontData[] fontData = getFont().getFontData(); + if (fontData != null && fontData.length > 0) { + final FontData fd = fontData[0]; + fd.setStyle(SWT.BOLD); + fd.setHeight(fd.getHeight() + 2); + this.titleFont = new Font(getDisplay(), fd); + } else { + this.titleFont = null; + } + + this.titleColor = new Color(getDisplay(), 0, 88, 150); + + this.gradientEnd = new Color(this.getDisplay(), 239, 239, 239); + this.gradientStart = new Color(this.getDisplay(), 255, 255, 255); + this.separatorColor = new Color(this.getDisplay(), 229, 229, 229); + + this.addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(final Event event) { + redrawComposite(); + } + }); + + this.addListener(SWT.Dispose, new Listener() { + @Override + public void handleEvent(final Event event) { + SWTGraphicUtil.dispose(Header.this.titleColor); + SWTGraphicUtil.dispose(Header.this.titleFont); + SWTGraphicUtil.dispose(Header.this.oldImage); + SWTGraphicUtil.dispose(Header.this.gradientEnd); + SWTGraphicUtil.dispose(Header.this.gradientStart); + SWTGraphicUtil.dispose(Header.this.separatorColor); + } + }); + setBackgroundMode(SWT.INHERIT_FORCE); + } + + /** + * Redraw the composite + */ + private void redrawComposite() { + // Dispose previous content + for (final Control c : this.getChildren()) { + c.dispose(); + } + + int numberOfColumns = 1; + if (this.image != null) { + numberOfColumns++; + } + + super.setLayout(new GridLayout(numberOfColumns, false)); + createContent(); + drawBackground(); + } + + /** + * Create the content (title, image, description) + */ + private void createContent() { + if (this.title != null) { + createTitle(); + } + + if (this.image != null) { + createImage(); + } + + if (this.description != null) { + createDescription(); + } + } + + /** + * Create the title + */ + private void createTitle() { + final Label labelTitle = new Label(this, SWT.NONE); + labelTitle.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false)); + labelTitle.setFont(this.titleFont); + labelTitle.setForeground(this.titleColor); + labelTitle.setText(this.title); + } + + /** + * Create the image + */ + private void createImage() { + + int numberOfLines = 1; + + if (this.title != null && this.description != null) { + numberOfLines++; + } + final Label labelImage = new Label(this, SWT.NONE); + labelImage.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, true, 1, numberOfLines)); + labelImage.setImage(this.image); + } + + /** + * Create the description + */ + private void createDescription() { + final StyledText labelDescription = new StyledText(this, SWT.WRAP | SWT.READ_ONLY); + labelDescription.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + labelDescription.setEnabled(false); + labelDescription.setFont(getFont()); + labelDescription.setForeground(getForeground()); + labelDescription.setText("" + this.description + ""); + SWTGraphicUtil.applyHTMLFormating(labelDescription); + } + + /** + * Draw the background (a gradient+a separator) + */ + private void drawBackground() { + final Display display = this.getDisplay(); + final Rectangle rect = this.getClientArea(); + final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height)); + + final GC gc = new GC(newImage); + gc.setForeground(this.gradientStart); + gc.setBackground(this.gradientEnd); + + gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, false); + + gc.setForeground(this.separatorColor); + gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1); + + gc.dispose(); + + this.setBackgroundImage(newImage); + if (this.oldImage != null) { + this.oldImage.dispose(); + } + this.oldImage = newImage; + } + + /** + * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout) + */ + @Override + public void setLayout(final Layout layout) { + throw new UnsupportedOperationException("Not supported"); + } + + // ------------------------------------ Getters and Setters + + /** + * Returns the receiver's description if it has one, or null if it does not. + * + * @return the receiver's description if it has one, or null if it does not + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getDescription() { + checkWidget(); + return this.description; + } + + /** + * Returns the receiver's gradient end color. + * + * @return the receiver's gradient end color + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getGradientEnd() { + checkWidget(); + return this.gradientEnd; + } + + /** + * Returns the receiver's gradient start color. + * + * @return the receiver's gradient start color + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getGradientStart() { + checkWidget(); + return this.gradientStart; + } + + /** + * Returns the receiver's image if it has one, or null if it does not. + * + * @return the receiver's image if it has one, or null if it does not + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getImage() { + checkWidget(); + return this.image; + } + + /** + * Returns the receiver's separator color. + * + * @return the receiver's separator color + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getSeparatorColor() { + checkWidget(); + return this.separatorColor; + } + + /** + * Returns the receiver's title if it has one, or null if it does not. + * + * @return the receiver's title if it has one, or null if it does not + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getTitle() { + checkWidget(); + return this.title; + } + + /** + * Returns the title's color. + * + * @return the title's color + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getTitleColor() { + checkWidget(); + return this.titleColor; + } + + /** + * Returns the title's font. + * + * @return the title's font. + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Font getTitleFont() { + checkWidget(); + return this.titleFont; + } + + /** + * Sets the receiver's description to the argument, which may be null + * indicating that no description should be displayed. + * + * @param description the description of the header (may be null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setDescription(final String description) { + checkWidget(); + this.description = description; + } + + /** + * Sets the receiver's gradient end color. + * + * @param gradientEnd the receiver's gradient end color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setGradientEnd(final Color gradientEnd) { + checkWidget(); + this.gradientEnd = gradientEnd; + } + + /** + * Sets the receiver's gradient start color. + * + * @param gradientStart the receiver's gradient start color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setGradientStart(final Color gradientStart) { + checkWidget(); + this.gradientStart = gradientStart; + } + + /** + * Sets the receiver's image to the argument, which may be null indicating + * that no image should be displayed. + * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setImage(final Image image) { + checkWidget(); + this.image = image; + } + + /** + * Sets the receiver's separator color. + * + * @param separatorColor the receiver's separator color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSeparatorColor(final Color separatorColor) { + this.separatorColor = separatorColor; + } + + /** + * Sets the receiver's title to the argument, which may be null indicating + * that no title should be displayed. + * + * @param title the title + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTitle(final String title) { + checkWidget(); + this.title = title; + } + + /** + * Sets the receiver's title color. + * + * @param headerColor the receiver's title color + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTitleColor(final Color headerColor) { + checkWidget(); + this.titleColor = headerColor; + } + + /** + * Sets the receiver's title font. + * + * @param headerFont the receiver's title font + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTitleFont(final Font headerFont) { + checkWidget(); + this.titleFont = headerFont; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/heapManager/HeapManager.java b/org.tizen.common.externals/src/org/mihalis/opal/heapManager/HeapManager.java new file mode 100644 index 000000000..a702b6fab --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/heapManager/HeapManager.java @@ -0,0 +1,297 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.heapManager; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Widget; +import org.mihalis.opal.utils.ResourceManager; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class are controls that display the memory used, the whole + * memory, and contains a button to perform a GC + */ +public class HeapManager extends Composite { + private Canvas bar; + private Button button; + private int heapMaxSize; + private int heapSize; + private Color barBorderColor; + private Color barInnerColor; + private Color barTextColor; + private Color barGradientColorTopStart; + private Color barGradientColorTopEnd; + private Color barGradientColorMiddleStart; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance + * (cannot be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see Widget#getStyle + */ + public HeapManager(final Composite parent, final int style) { + super(parent, style); + final GridLayout gridLayout = new GridLayout(2, false); + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; + setLayout(gridLayout); + + createBar(); + createButton(); + updateContent(); + createDefaultColors(); + + addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent e) { + SWTGraphicUtil.dispose(HeapManager.this.barBorderColor); + SWTGraphicUtil.dispose(HeapManager.this.barInnerColor); + SWTGraphicUtil.dispose(HeapManager.this.barGradientColorTopStart); + SWTGraphicUtil.dispose(HeapManager.this.barGradientColorTopEnd); + SWTGraphicUtil.dispose(HeapManager.this.barGradientColorMiddleStart); + SWTGraphicUtil.dispose(HeapManager.this.barTextColor); + } + }); + + } + + /** + * Creates the bar that displays the memory + */ + private void createBar() { + this.bar = new Canvas(this, SWT.NONE); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false); + gd.minimumWidth = 100; + gd.heightHint = 30; + this.bar.setLayoutData(gd); + this.heapMaxSize = (int) (Runtime.getRuntime().maxMemory() / (1024 * 1024)); + this.bar.addPaintListener(new PaintListener() { + + @Override + public void paintControl(final PaintEvent e) { + drawBar(e); + } + }); + } + + /** + * Draw the bar + * + * @param e {@link PaintEvent} + */ + private void drawBar(final PaintEvent e) { + final GC gc = e.gc; + final Rectangle clientArea = this.bar.getClientArea(); + + gc.setForeground(this.barBorderColor); + gc.setBackground(this.barInnerColor); + gc.fillRectangle(clientArea); + gc.drawRectangle(clientArea.x, clientArea.y, clientArea.width - 1, clientArea.height - 1); + + final float width = (clientArea.width - 2f) * this.heapSize / this.heapMaxSize; + + gc.setForeground(this.barGradientColorTopStart); + gc.setBackground(this.barGradientColorTopEnd); + gc.fillGradientRectangle(clientArea.x + 1, clientArea.y + 1, (int) width, clientArea.height / 2, true); + + gc.setForeground(this.barGradientColorMiddleStart); + gc.setBackground(this.barBorderColor); + gc.fillGradientRectangle(clientArea.x + 1, clientArea.height / 2, (int) width, clientArea.height / 2, true); + + final String message = this.heapSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES) + "/" + // + this.heapMaxSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES); + final Point size = gc.stringExtent(message); + + gc.setForeground(this.barTextColor); + gc.setFont(getFont()); + gc.drawText(message, (clientArea.width - size.x) / 2, (clientArea.height - size.y) / 2, true); + + gc.dispose(); + + } + + /** + * Create the button used to perform GC + */ + private void createButton() { + this.button = new Button(this, SWT.PUSH); + this.button.setImage(SWTGraphicUtil.createImage("images/trash.png")); + this.button.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + this.button.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + System.gc(); + } + + }); + this.button.setToolTipText(ResourceManager.getLabel(ResourceManager.PERFORM_GC)); + this.button.pack(); + } + + /** + * Update the content of the bar + */ + private void updateContent() { + getDisplay().timerExec(500, new Runnable() { + + @Override + public void run() { + HeapManager.this.heapSize = (int) (Runtime.getRuntime().totalMemory() / (1024 * 1024)); + if (!isDisposed()) { + HeapManager.this.bar.redraw(); + if (!getDisplay().isDisposed()) { + getDisplay().timerExec(500, this); + } + } + } + }); + + } + + /** + * Creates the default colors + */ + private void createDefaultColors() { + this.barTextColor = new Color(getDisplay(), 57, 98, 149); + this.barInnerColor = new Color(getDisplay(), 219, 230, 243); + this.barBorderColor = new Color(getDisplay(), 101, 148, 207); + this.barGradientColorTopStart = new Color(getDisplay(), 175, 202, 237); + this.barGradientColorTopEnd = new Color(getDisplay(), 136, 177, 229); + this.barGradientColorMiddleStart = new Color(getDisplay(), 112, 161, 223); + + } + + /** + * @return the barBorderColor + */ + public Color getBarBorderColor() { + return this.barBorderColor; + } + + /** + * @param barBorderColor the barBorderColor to set + */ + public void setBarBorderColor(final Color barBorderColor) { + this.barBorderColor = barBorderColor; + } + + /** + * @return the barInnerColor + */ + public Color getBarInnerColor() { + return this.barInnerColor; + } + + /** + * @param barInnerColor the barInnerColor to set + */ + public void setBarInnerColor(final Color barInnerColor) { + this.barInnerColor = barInnerColor; + } + + /** + * @return the barTextColor + */ + public Color getBarTextColor() { + return this.barTextColor; + } + + /** + * @param barTextColor the barTextColor to set + */ + public void setBarTextColor(final Color barTextColor) { + this.barTextColor = barTextColor; + } + + /** + * @return the barGradientColorTopStart + */ + public Color getBarGradientColorTopStart() { + return this.barGradientColorTopStart; + } + + /** + * @param barGradientColorTopStart the barGradientColorTopStart to set + */ + public void setBarGradientColorTopStart(final Color barGradientColorTopStart) { + this.barGradientColorTopStart = barGradientColorTopStart; + } + + /** + * @return the barGradientColorTopEnd + */ + public Color getBarGradientColorTopEnd() { + return this.barGradientColorTopEnd; + } + + /** + * @param barGradientColorTopEnd the barGradientColorTopEnd to set + */ + public void setBarGradientColorTopEnd(final Color barGradientColorTopEnd) { + this.barGradientColorTopEnd = barGradientColorTopEnd; + } + + /** + * @return the barGradientColorMiddleStart + */ + public Color getBarGradientColorMiddleStart() { + return this.barGradientColorMiddleStart; + } + + /** + * @param barGradientColorMiddleStart the barGradientColorMiddleStart to set + */ + public void setBarGradientColorMiddleStart(final Color barGradientColorMiddleStart) { + this.barGradientColorMiddleStart = barGradientColorMiddleStart; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/horizontalSpinner/HorizontalSpinner.java b/org.tizen.common.externals/src/org/mihalis/opal/horizontalSpinner/HorizontalSpinner.java new file mode 100644 index 000000000..5362a36f0 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/horizontalSpinner/HorizontalSpinner.java @@ -0,0 +1,947 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Implementation + *******************************************************************************/ +package org.mihalis.opal.horizontalSpinner; + +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Text; +import org.mihalis.opal.utils.StringUtil; + +/** + * Instances of this class are selectable user interface objects that allow the user to enter and modify numeric values. + *

+ *

+ *
Styles:
+ *
READ_ONLY, FLAP
+ *
Events:
+ *
Selection, Modify
+ *
+ *

+ */ +public class HorizontalSpinner extends Composite { + private final List modifyListeners = new ArrayList(); + private final List selectionListeners = new ArrayList(); + + private Button leftButton; + private Button rightButton; + private Text text; + private int digits = 0; + private int increment = 1; + private int maximum = 0; + private int minimum = 255; + private int pageIncrement = 10; + private int storedValue = 0; + + private final char decimalFormatSeparator; + + /** + * Constructs a new instance of this class given its parent and a style value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class SWT which is applicable to instances of this class, or must be built by bitwise OR'ing together (that is, using the int "|" operator) two or more of those SWT style constants. The class description lists the style constants that are applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ * + * @see SWT#READ_ONLY + * @see SWT#FLAT + */ + public HorizontalSpinner(final Composite parent, final int style) { + super(parent, style); + + final GridLayout gd = new GridLayout(3, false); + gd.horizontalSpacing = gd.verticalSpacing = 0; + gd.marginWidth = gd.marginHeight = 0; + this.setLayout(gd); + + this.createContent(style); + this.addTextListeners(); + this.addButtonsListener(); + this.addModifyListeners(); + + this.decimalFormatSeparator = new DecimalFormatSymbols().getDecimalSeparator(); + } + + /** + * Create the content of the widget + * + * @param style style of the widget + */ + private void createContent(final int style) { + final boolean readOnly = (style & SWT.READ_ONLY) == SWT.READ_ONLY; + final boolean flat = (style & SWT.FLAT) == SWT.FLAT; + + final int buttonStyle = SWT.ARROW | (flat ? SWT.FLAT : SWT.NONE); + this.leftButton = new Button(this, buttonStyle | SWT.LEFT); + this.leftButton.setFont(this.getFont()); + this.leftButton.setBackground(this.getBackground()); + this.leftButton.setCursor(this.getCursor()); + this.leftButton.setEnabled(this.getEnabled()); + this.leftButton.setFont(this.getFont()); + this.leftButton.setForeground(this.getForeground()); + this.leftButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + this.text = new Text(this, readOnly ? SWT.READ_ONLY : SWT.NONE); + final GridData gd = new GridData(GridData.FILL, GridData.CENTER, true, false); + gd.minimumWidth = 40; + this.text.setLayoutData(gd); + + this.rightButton = new Button(this, buttonStyle | SWT.RIGHT); + this.rightButton.setFont(this.getFont()); + this.rightButton.setBackground(this.getBackground()); + this.rightButton.setCursor(this.getCursor()); + this.rightButton.setEnabled(this.getEnabled()); + this.rightButton.setFont(this.getFont()); + this.rightButton.setForeground(this.getForeground()); + this.rightButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + } + + /** + * Add the text listeners + */ + private void addTextListeners() { + this.text.addVerifyListener(new VerifyListener() { + + @Override + public void verifyText(final VerifyEvent e) { + if (e.character != 0 && !Character.isDigit(e.character) && e.keyCode != SWT.BS && e.keyCode != SWT.DEL) { + e.doit = false; + return; + } + + e.doit = HorizontalSpinner.this.verifyEntryAndStoreValue(e.text, e.keyCode); + + } + }); + + this.text.addKeyListener(new KeyAdapter() { + + /** + * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + @Override + public void keyReleased(final KeyEvent e) { + if (e.keyCode == SWT.ARROW_UP) { + HorizontalSpinner.this.increaseValue(HorizontalSpinner.this.increment); + } + if (e.keyCode == SWT.ARROW_DOWN) { + HorizontalSpinner.this.decreaseValue(HorizontalSpinner.this.increment); + } + if (e.keyCode == SWT.PAGE_UP) { + HorizontalSpinner.this.increaseValue(HorizontalSpinner.this.pageIncrement); + } + if (e.keyCode == SWT.PAGE_DOWN) { + HorizontalSpinner.this.decreaseValue(HorizontalSpinner.this.pageIncrement); + } + } + + }); + + this.text.addFocusListener(new org.eclipse.swt.events.FocusAdapter() { + + /** + * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent) + */ + @Override + public void focusLost(final org.eclipse.swt.events.FocusEvent e) { + if (HorizontalSpinner.this.text.getText().trim().equals("")) { + HorizontalSpinner.this.setSelection(HorizontalSpinner.this.storedValue); + } + } + + }); + + } + + /** + * Verify the entry and store the value in the field storedValue + * + * @param entry entry to check + * @param keyCode code of the typed key + * @return true if the entry if correct, false otherwise + */ + private boolean verifyEntryAndStoreValue(final String entry, final int keyCode) { + final String work; + if (keyCode == SWT.DEL) { + work = StringUtil.removeCharAt(this.text.getText(), this.text.getCaretPosition()); + } else if (keyCode == SWT.BS && this.text.getCaretPosition() == 0) { + work = StringUtil.removeCharAt(this.text.getText(), this.text.getCaretPosition() - 1); + } else if (keyCode == 0) { + work = entry; + } else { + work = StringUtil.insertString(this.text.getText(), entry, this.text.getCaretPosition()); + } + + try { + final double d = Double.parseDouble(work.replace(this.decimalFormatSeparator, '.')); + this.storedValue = (int) (d * Math.pow(10, this.getDigits())); + } catch (final NumberFormatException nfe) { + return false; + } + + for (final SelectionListener s : HorizontalSpinner.this.selectionListeners) { + s.widgetSelected(null); + } + + return true; + } + + /** + * Add the listener to the buttons + */ + private void addButtonsListener() { + this.leftButton.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + HorizontalSpinner.this.decreaseValue(HorizontalSpinner.this.increment); + } + }); + + this.rightButton.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + HorizontalSpinner.this.increaseValue(HorizontalSpinner.this.increment); + } + }); + + } + + /** + * Increase the value stored in this snippet + * + * @param value value to increase + */ + private void increaseValue(final int value) { + this.setSelection(this.getSelection() + value); + + } + + /** + * Decrease the value stored in this snippet + * + * @param value value to decrease + */ + private void decreaseValue(final int value) { + this.setSelection(this.getSelection() - value); + } + + /** + * Add the modify listeners + */ + private void addModifyListeners() { + this.text.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(final ModifyEvent e) { + for (final ModifyListener m : HorizontalSpinner.this.modifyListeners) { + m.modifyText(e); + } + + } + }); + + } + + /** + * Adds the listener to the collection of listeners who will be notified when the receiver's text is modified, by sending it one of the messages defined in the ModifyListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #removeModifyListener + * @see org.eclipse.swt.widgets.Spinner#addModifyListener(org.eclipse.swt.events.ModifyListener) + */ + + public void addModifyListener(final ModifyListener listener) { + this.checkWidget(); + this.modifyListeners.add(listener); + } + + /** + * Adds the listener to the collection of listeners who will be notified when the control is selected by the user, by sending it one of the messages defined in the SelectionListener interface. + *

+ * widgetSelected is not called for texts. widgetDefaultSelected is typically called when ENTER is pressed in a single-line text. + *

+ * + * @param listener the listener which should be notified when the control is selected by the user + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + this.checkWidget(); + this.selectionListeners.add(listener); + } + + /** + * Copies the selected text. + *

+ * The current selection is copied to the clipboard. + *

+ * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void copy() { + this.checkWidget(); + this.text.copy(); + } + + /** + * Cuts the selected text. + *

+ * The current selection is first copied to the clipboard and then deleted from the widget. + *

+ * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void cut() { + this.checkWidget(); + this.text.cut(); + } + + /** + * Returns the number of decimal places used by the receiver. + * + * @return the digits + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getDigits() { + this.checkWidget(); + return this.digits; + } + + /** + * Returns the amount that the receiver's value will be modified by when the up/down arrows are pressed. + * + * @return the increment + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getIncrement() { + this.checkWidget(); + return this.increment; + } + + /** + * Returns the maximum value which the receiver will allow. + * + * @return the maximum + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getMaximum() { + this.checkWidget(); + return this.maximum; + } + + /** + * Returns the minimum value which the receiver will allow. + * + * @return the minimum + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getMinimum() { + this.checkWidget(); + return this.minimum; + } + + /** + * Returns the amount that the receiver's position will be modified by when the page up/down keys are pressed. + * + * @return the page increment + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getPageIncrement() { + this.checkWidget(); + return this.pageIncrement; + } + + /** + * Returns the selection, which is the receiver's position. + * + * @return the selection + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getSelection() { + this.checkWidget(); + return this.storedValue; + + } + + /** + * Returns a string containing a copy of the contents of the receiver's text field, or an empty string if there are no contents. + * + * @return the receiver's text + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + */ + public String getText() { + this.checkWidget(); + return this.text.getText(); + } + + /** + * Returns the maximum number of characters that the receiver's text field is capable of holding. If this has not been changed by setTextLimit(), it will be the constant Spinner.LIMIT. + * + * @return the text limit + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #LIMIT + */ + public int getTextLimit() { + this.checkWidget(); + return this.text.getTextLimit(); + } + + /** + * Pastes text from clipboard. + *

+ * The selected text is deleted from the widget and new text inserted from the clipboard. + *

+ * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void paste() { + this.checkWidget(); + this.text.paste(); + } + + /** + * Removes the listener from the collection of listeners who will be notified when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(final ModifyListener listener) { + this.checkWidget(); + this.modifyListeners.remove(listener); + } + + /** + * Removes the listener from the collection of listeners who will be notified when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + this.checkWidget(); + this.selectionListeners.remove(listener); + } + + /** + * Sets the number of decimal places used by the receiver. + *

+ * The digit setting is used to allow for floating point values in the receiver. For example, to set the selection to a floating point value of 1.37 call setDigits() with a value of 2 and setSelection() with a value of 137. Similarly, if getDigits() has a value of 2 and getSelection() returns 137 this should be interpreted as 1.37. This applies to all numeric APIs. + *

+ * + * @param value the new digits (must be greater than or equal to zero) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the value is less than zero
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setDigits(final int value) { + this.checkWidget(); + this.digits = value; + this.convertSelection(); + } + + /** + * Sets the amount that the receiver's value will be modified by when the up/down arrows are pressed to the argument, which must be at least one. + * + * @param value the new increment (must be greater than zero) + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setIncrement(final int value) { + this.checkWidget(); + this.increment = value; + } + + /** + * Sets the maximum value that the receiver will allow. This new value will be ignored if it is less than the receiver's current minimum value. If the new maximum is applied then the receiver's selection value will be adjusted if necessary to fall within its new range. + * + * @param value the new maximum, which must be greater than or equal to the current minimum + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setMaximum(final int value) { + this.checkWidget(); + this.maximum = value; + } + + /** + * Sets the minimum value that the receiver will allow. This new value will be ignored if it is greater than the receiver's current maximum value. If the new minimum is applied then the receiver's selection value will be adjusted if necessary to fall within its new range. + * + * @param value the new minimum, which must be less than or equal to the current maximum + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setMinimum(final int value) { + this.checkWidget(); + this.minimum = value; + } + + /** + * Sets the amount that the receiver's position will be modified by when the page up/down keys are pressed to the argument, which must be at least one. + * + * @param value the page increment (must be greater than zero) + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setPageIncrement(final int value) { + this.checkWidget(); + this.pageIncrement = value; + } + + /** + * Sets the selection, which is the receiver's position, to the argument. If the argument is not within the range specified by minimum and maximum, it will be adjusted to fall within this range. + * + * @param value the new selection (must be zero or greater) + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setSelection(int selection) { + this.checkWidget(); + if (selection < this.minimum) { + selection = this.minimum; + } else if (selection > this.maximum) { + selection = this.maximum; + } + + this.storedValue = selection; + this.text.setText(this.convertSelection()); + this.text.selectAll(); + this.text.setFocus(); + + for (final SelectionListener s : HorizontalSpinner.this.selectionListeners) { + s.widgetSelected(null); + } + + } + + /** + * Convert the selection into a string + * + * @return the string representation of the selection + */ + private String convertSelection() { + if (this.getDigits() == 0) { + return String.valueOf(this.storedValue); + } + final String temp = String.valueOf(this.storedValue * Math.pow(10, -1 * this.getDigits())); + return temp.replace('.', this.decimalFormatSeparator); + } + + /** + * Sets the maximum number of characters that the receiver's text field is capable of holding to be the argument. + *

+ * To reset this value to the default, use setTextLimit(Spinner.LIMIT). Specifying a limit value larger than Spinner.LIMIT sets the receiver's limit to Spinner.LIMIT. + *

+ * + * @param limit new text limit + * + * @exception IllegalArgumentException
    + *
  • ERROR_CANNOT_BE_ZERO - if the limit is zero
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #LIMIT + */ + public void setTextLimit(final int limit) { + this.checkWidget(); + this.text.setTextLimit(limit); + } + + /** + * Sets the receiver's selection, minimum value, maximum value, digits, increment and page increment all at once. + *

+ * Note: This is similar to setting the values individually using the appropriate methods, but may be implemented in a more efficient fashion on some platforms. + *

+ * + * @param selection the new selection value + * @param minimum the new minimum value + * @param maximum the new maximum value + * @param digits the new digits value + * @param increment the new increment value + * @param pageIncrement the new pageIncrement value + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setValues(final int selection, final int minimum, final int maximum, final int digits, final int increment, final int pageIncrement) { + this.setMinimum(minimum); + this.setMaximum(maximum); + this.setDigits(digits); + this.setIncrement(increment); + this.setPageIncrement(pageIncrement); + this.setSelection(selection); + } + + /** + * Sets the receiver's drag detect state. If the argument is true, the receiver will detect drag gestures, otherwise these gestures will be ignored. + * + * @param dragDetect the new drag detect state + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public boolean setFocus() { + this.checkWidget(); + return this.text.setFocus(); + } + + /** + * Forces the receiver to have the keyboard focus, causing all keyboard events to be delivered to it. + * + * @return true if the control got focus, and false if it was unable to. + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #setFocus + */ + @Override + public boolean forceFocus() { + this.checkWidget(); + return this.text.forceFocus(); + } + + /** + * Sets the receiver's background color to the color specified by the argument, or to the default system color for the control if the argument is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. For example, on Windows the background of a Button cannot be changed. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setBackground(final Color color) { + super.setBackground(color); + this.leftButton.setBackground(color); + this.rightButton.setBackground(color); + this.text.setBackground(color); + } + + /** + * Sets the receiver's background image to the image specified by the argument, or to the default system color for the control if the argument is null. The background image is tiled to fill the available space. + *

+ * Note: This operation is a hint and may be overridden by the platform. For example, on Windows the background of a Button cannot be changed. + *

+ * + * @param image the new image (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
  • ERROR_INVALID_ARGUMENT - if the argument is not a bitmap
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setBackgroundImage(final Image image) { + super.setBackgroundImage(image); + this.leftButton.setBackgroundImage(image); + this.rightButton.setBackgroundImage(image); + this.text.setBackgroundImage(image); + + } + + /** + * Sets the receiver's cursor to the cursor specified by the argument, or to the default cursor for that kind of control if the argument is null. + *

+ * When the mouse pointer passes over a control its appearance is changed to match the control's cursor. + *

+ * + * @param cursor the new cursor (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setCursor(final Cursor cursor) { + super.setCursor(cursor); + this.leftButton.setCursor(cursor); + this.rightButton.setCursor(cursor); + this.text.setCursor(cursor); + + } + + /** + * Enables the receiver if the argument is true, and disables it otherwise. A disabled control is typically not selectable from the user interface and draws with an inactive or "grayed" look. + * + * @param enabled the new enabled state + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setEnabled(final boolean enabled) { + super.setEnabled(enabled); + this.leftButton.setEnabled(enabled); + this.rightButton.setEnabled(enabled); + this.text.setEnabled(enabled); + + } + + /** + * Sets the font that the receiver will use to paint textual information to the font specified by the argument, or to the default font for that kind of control if the argument is null. + * + * @param font the new font (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setFont(final Font font) { + super.setFont(font); + this.text.setFont(font); + } + + /** + * Sets the receiver's foreground color to the color specified by the argument, or to the default system color for the control if the argument is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setForeground(final Color color) { + super.setForeground(color); + this.leftButton.setForeground(color); + this.rightButton.setForeground(color); + this.text.setForeground(color); + + } + + /** + * Sets the receiver's pop up menu to the argument. All controls may optionally have a pop up menu that is displayed when the user requests one for the control. The sequence of key strokes, button presses and/or button releases that are used to request a pop up menu is platform specific. + *

+ * Note: Disposing of a control that has a pop up menu will dispose of the menu. To avoid this behavior, set the menu to null before the control is disposed. + *

+ * + * @param menu the new pop up menu + * + * @exception IllegalArgumentException
    + *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • + *
  • ERROR_INVALID_PARENT - if the menu is not in the same widget tree
  • + *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setMenu(final Menu menu) { + super.setMenu(menu); + this.leftButton.setMenu(menu); + this.rightButton.setMenu(menu); + this.text.setMenu(menu); + } + + /** + * Sets the receiver's tool tip text to the argument, which may be null indicating that the default tool tip for the control will be shown. For a control that has a default tool tip, such as the Tree control on Windows, setting the tool tip text to an empty string replaces the default, causing no tool tip text to be shown. + *

+ * The mnemonic indicator (character '&') is not displayed in a tool tip. To display a single '&' in the tool tip, the character '&' can be escaped by doubling it in the string. + *

+ * + * @param string the new tool tip text (or null) + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setToolTipText(final String tooltipText) { + super.setToolTipText(tooltipText); + this.leftButton.setToolTipText(tooltipText); + this.rightButton.setToolTipText(tooltipText); + this.text.setToolTipText(tooltipText); + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ISItem.java b/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ISItem.java new file mode 100644 index 000000000..fc9109905 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ISItem.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.imageSelector; + +import org.eclipse.swt.graphics.Point; +import org.mihalis.opal.OpalItem; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class represents items manipulated by the ImageSelector + * widget + */ +public class ISItem extends OpalItem implements Comparable { + + private double zPosition; + private Point upperLeftCorner; + private Point lowerRightCorner; + + /** + * Constructor + * + * @param fileName file name of the image that will be displayed + */ + public ISItem(final String fileName) { + setImage(SWTGraphicUtil.createImage(fileName)); + } + + /** + * Constructor + * + * @param title the title of the image + * @param fileName file name of the image that will be displayed + */ + public ISItem(final String title, final String fileName) { + setImage(SWTGraphicUtil.createImage(fileName)); + setText(title); + } + + /** + * @return the zPosition + */ + double getzPosition() { + return this.zPosition; + } + + /** + * @param zPosition the zPosition to set + */ + ISItem setzPosition(final double zPosition) { + this.zPosition = zPosition; + return this; + } + + /** + * @return the upperLeftCorner + */ + Point getUpperLeftCorner() { + return this.upperLeftCorner; + } + + /** + * @param x the upperLeftCorner.x to set + * @param y the upperLeftCorner.y to set + */ + void setUpperLeftCorner(final int x, final int y) { + this.upperLeftCorner = new Point(x, y); + } + + /** + * @return the lowerRightCorner + */ + Point getLowerRightCorner() { + return this.lowerRightCorner; + } + + /** + * @param x the lowerRightCorner.x to set + * @param y the lowerRightCorner.y to set + */ + void setLowerRightCorner(final int x, final int y) { + this.lowerRightCorner = new Point(x, y); + } + + void resetCornerToNull() { + this.upperLeftCorner = null; + this.lowerRightCorner = null; + + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ISItem [getText()=" + this.getText() + "]"; + } + + /** + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(final ISItem o) { + return new Double(Math.abs(this.zPosition)).compareTo(Math.abs(o.getzPosition())) * -1; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ImageSelector.java b/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ImageSelector.java new file mode 100755 index 000000000..2bab62d96 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ImageSelector.java @@ -0,0 +1,615 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + * Romain Guy - Original Swing Implementation (http://www.curious-creature.org/2005/07/09/a-music-shelf-in-java2d/) + *******************************************************************************/ +package org.mihalis.opal.imageSelector; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class are controls that allow the user to select images. + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
(none)
+ *
+ */ +public class ImageSelector extends Canvas { + private List items; + private List originalItems; + private Font font; + private static final int DEFAULT_WIDTH = 148; + private int maxItemWidth = DEFAULT_WIDTH; + private int index = -1; + private double sigma; + private double rho; + private double expMultiplier; + private double expMember; + private float spacing = 0.4f; + private Color gradientStart; + private Color gradientEnd; + private double animationStep = -1d; + private static final int TIMER_INTERVAL = 50; + private int pageIncrement = 5; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public ImageSelector(final Composite parent, final int style) { + super(parent, style | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED); + this.font = new Font(this.getDisplay(), "Lucida Sans", 24, SWT.NONE); + + this.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent e) { + SWTGraphicUtil.dispose(ImageSelector.this.font); + SWTGraphicUtil.dispose(ImageSelector.this.gradientStart); + SWTGraphicUtil.dispose(ImageSelector.this.gradientEnd); + } + + }); + + addPaintListener(new PaintListener() { + @Override + public void paintControl(final PaintEvent e) { + ImageSelector.this.paintControl(e); + } + + }); + + addKeyListener(); + addMouseListeners(); + + setSigma(0.5); + this.gradientStart = new Color(getDisplay(), 0, 0, 0); + this.gradientEnd = new Color(getDisplay(), 110, 110, 110); + } + + /** + * Set the sigma value for the gaussian curve + * + * @param sigma new sigma parameter + */ + public void setSigma(final double sigma) { + this.sigma = sigma; + this.rho = 1.0; + computeEquationParts(); + this.rho = computeModifierUnbounded(0.0); + computeEquationParts(); + redraw(); + } + + /** + * Computer both members of the equation + */ + private void computeEquationParts() { + this.expMultiplier = Math.sqrt(2.0 * Math.PI) / this.sigma / this.rho; + this.expMember = 4.0 * this.sigma * this.sigma; + } + + /** + * Compute the value of the modifier. The value is bounded between -1 and +1 + * + * @param x input value + * @return the value of the modifier between -1 and +1 + */ + private double computeModifierBounded(final double x) { + double result = computeModifierUnbounded(x); + if (result > 1.0) { + result = 1.0; + } else if (result < -1.0) { + result = -1.0; + } + return result; + } + + /** + * Compute the value of the modifier + * + * @param x input value + * @return the value of the function + */ + private double computeModifierUnbounded(final double x) { + return this.expMultiplier * Math.exp(-x * x / this.expMember); + } + + /** + * Draw the widget + * + * @param e the paintEvent + */ + private void paintControl(final PaintEvent e) { + + // Create the image to fill the canvas + final Image image = new Image(getDisplay(), getClientArea()); + + // Set up the offscreen gc + final GC gc = new GC(image); + + // Draw gradient + drawBackground(gc); + + // Draw the items + drawItems(gc); + + // Draw the title + if (this.animationStep < 0d) { + drawTitle(gc); + } + + // Draw the offscreen buffer to the screen + e.gc.drawImage(image, 0, 0); + + // Clean up + image.dispose(); + gc.dispose(); + + } + + /** + * Draw the background + * + * @param gc graphical context + */ + private void drawBackground(final GC gc) { + final Rectangle rect = getClientArea(); + + gc.setForeground(this.gradientStart); + gc.setBackground(this.gradientEnd); + gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height / 2, true); + + gc.setForeground(this.gradientEnd); + gc.setBackground(this.gradientStart); + gc.fillGradientRectangle(rect.x, rect.height / 2, rect.width, rect.height / 2, true); + } + + /** + * Draw the items + * + * @param gc graphical context + */ + private void drawItems(final GC gc) { + + if (this.animationStep < 0d) { + this.items.clear(); + this.items.addAll(this.originalItems); + for (int i = 0; i < this.items.size(); i++) { + final ISItem item = this.items.get(i); + item.setzPosition((i - this.index) * this.spacing); + } + + Collections.sort(this.items); + } + + for (final ISItem item : this.items) { + drawItem(gc, item); + } + } + + /** + * Draw a given item + * + * @param gc graphical context + * @param item item to draw + */ + private void drawItem(final GC gc, final ISItem item) { + + final int size = computeSize(item); + final int centerX = computeZPosition(item); + final int centerY = this.getClientArea().height / 2; + + if (size <= 0 || centerX < 0 || centerX > getBounds().width) { + item.resetCornerToNull(); + return; + } + + final int alpha = computeAlpha(item); + + final Image newImage = SWTGraphicUtil.createReflectedResizedImage(item.getImage(), size, size); + gc.setAlpha(alpha); + + final int x = centerX - newImage.getBounds().width / 2; + final int y = centerY - newImage.getBounds().height / 2; + + gc.drawImage(newImage, x, y); + + item.setUpperLeftCorner(x, y); + item.setLowerRightCorner(x + newImage.getBounds().width, (int) (y + newImage.getBounds().height / 1.5)); + + newImage.dispose(); + } + + /** + * Compute the z position for a given item + * + * @param item item + * @return the z position of the item + */ + private int computeZPosition(final ISItem item) { + final int totalWidth = this.getClientArea().width / 2; + final int centerX = this.getClientArea().width / 2; + return (int) (centerX + item.getzPosition() * totalWidth); + } + + /** + * Compute size for a given item + * + * @param item item + * @return the size of the item + */ + private int computeSize(final ISItem item) { + return (int) (computeModifierBounded(item.getzPosition()) * this.maxItemWidth); + } + + /** + * Compute the alpha value of a given item + * + * @param item item + * @return the alpha value of the item + */ + private int computeAlpha(final ISItem item) { + return (int) (255 - 150 * Math.abs(item.getzPosition())); + } + + /** + * Draw the title under the selected item + * + * @param gc graphical context + */ + private void drawTitle(final GC gc) { + final String title = this.originalItems.get(this.index).getText(); + if (title == null || title.trim().equals("")) { + return; + } + gc.setFont(getFont()); + final Point textSize = gc.stringExtent(title); + + gc.setAntialias(SWT.ON); + gc.setFont(getFont()); + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.setAlpha(255); + + final int centerX = this.getClientArea().width / 2; + final int centerY = (this.getClientArea().height + this.maxItemWidth) / 2; + + gc.drawString(title, centerX - textSize.x / 2, (centerY - textSize.y / 2), true); + + } + + /** + * Add the key listener + */ + private void addKeyListener() { + this.addKeyListener(new KeyAdapter() { + + /** + * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + @Override + public void keyReleased(final KeyEvent e) { + switch (e.keyCode) { + case SWT.ARROW_LEFT: + case SWT.ARROW_UP: + scrollAndAnimateBy(-1); + break; + case SWT.ARROW_RIGHT: + case SWT.ARROW_DOWN: + scrollAndAnimateBy(1); + break; + case SWT.HOME: + scrollBy(-1 * ImageSelector.this.index); + break; + case SWT.END: + scrollBy(ImageSelector.this.index); + break; + case SWT.PAGE_UP: + scrollBy(-1 * ImageSelector.this.pageIncrement); + break; + case SWT.PAGE_DOWN: + scrollBy(ImageSelector.this.pageIncrement); + break; + default: + break; + } + } + + }); + } + + /** + * Scroll the selected item + * + * @param increment increment value + */ + private void scrollBy(final int increment) { + this.index += increment; + if (this.index < 0) { + this.index = 0; + } + + if (this.index >= this.items.size()) { + this.index = this.items.size() - 1; + } + redraw(); + } + + /** + * Scroll the selected item with an animation + * + * @param increment increment value + */ + private void scrollAndAnimateBy(final int increment) { + if (this.index == 0 && increment < 0 || this.index == this.items.size() - 1 && increment > 0) { + return; + } + + final double step = Math.abs(increment) / (300d / TIMER_INTERVAL); + ImageSelector.this.animationStep = step; + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_WAIT)); + + getDisplay().syncExec(new Runnable() { + + @Override + public void run() { + + ImageSelector.this.items.clear(); + ImageSelector.this.items.addAll(ImageSelector.this.originalItems); + for (int i = 0; i < ImageSelector.this.items.size(); i++) { + final ISItem item = ImageSelector.this.items.get(i); + item.setzPosition((i - ImageSelector.this.index + ImageSelector.this.animationStep * (increment > 0 ? -1d : 1d)) * ImageSelector.this.spacing); + } + Collections.sort(ImageSelector.this.items); + if (!isDisposed()) { + redraw(); + } + + ImageSelector.this.animationStep += step; + if (ImageSelector.this.animationStep >= 1d) { + ImageSelector.this.animationStep = -1d; + ImageSelector.this.index += increment; + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); + } else { + if (!isDisposed()) { + getDisplay().timerExec(TIMER_INTERVAL, this); + } + } + + } + }); + + } + + /** + * Add mouse listeners + */ + private void addMouseListeners() { + addMouseMoveListener(new MouseMoveListener() { + + @Override + public void mouseMove(final MouseEvent e) { + for (final ISItem item : ImageSelector.this.items) { + if (item.getUpperLeftCorner() != null && item.getLowerRightCorner() != null && e.x >= item.getUpperLeftCorner().x && e.x <= item.getLowerRightCorner().x && e.y >= item.getUpperLeftCorner().y && e.y <= item.getLowerRightCorner().y) { + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + return; + } + } + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); + } + }); + + addMouseListener(new MouseAdapter() { + + /** + * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void mouseUp(final MouseEvent e) { + for (final ISItem item : ImageSelector.this.items) { + if (item.getUpperLeftCorner() != null && item.getLowerRightCorner() != null && e.x >= item.getUpperLeftCorner().x && e.x <= item.getLowerRightCorner().x && e.y >= item.getUpperLeftCorner().y && e.y <= item.getLowerRightCorner().y) { + scrollAndAnimateBy(ImageSelector.this.originalItems.indexOf(item) - ImageSelector.this.index); + return; + } + } + } + }); + + addListener(SWT.MouseWheel, new Listener() { + + @Override + public void handleEvent(final Event event) { + scrollBy(-1 * event.count); + } + }); + + } + + /** + * @return the items displayed by this widget + */ + public List getItems() { + return this.originalItems; + } + + /** + * @param items the items that are displayed in this widget to set + */ + public void setItems(final List items) { + this.items = new ArrayList(items); + this.originalItems = items; + this.index = this.items.size() / 2; + redraw(); + } + + /** + * @return the font used for the title + */ + @Override + public Font getFont() { + return this.font; + } + + /** + * @param font the font used for the title to set + */ + @Override + public void setFont(final Font font) { + SWTGraphicUtil.dispose(this.font); + this.font = font; + redraw(); + } + + /** + * @return the index of the selected image + */ + public int getIndex() { + return this.index; + } + + /** + * @param index the index of the selected image to set + */ + public void setIndex(final int index) { + this.index = index; + redraw(); + } + + /** + * @return the maximum items width + */ + public int getMaxItemWidth() { + return this.maxItemWidth; + } + + /** + * @param maxItemWidth the the maximum items width to set + */ + public void setMaxItemWidth(final int maxItemWidth) { + this.maxItemWidth = maxItemWidth; + redraw(); + } + + /** + * @return the sigma value + */ + public double getSigma() { + return this.sigma; + } + + /** + * @return the spacing between 2 items + */ + public float getSpacing() { + return this.spacing; + } + + /** + * @param spacing the the spacing between 2 items to set + */ + public void setSpacing(final float spacing) { + this.spacing = spacing; + redraw(); + } + + /** + * @return the gradient start color + */ + public Color getGradientStart() { + return this.gradientStart; + } + + /** + * @param gradientStart the the gradient start color to set + */ + public void setGradientStart(final Color gradientStart) { + SWTGraphicUtil.dispose(this.gradientStart); + this.gradientStart = gradientStart; + redraw(); + } + + /** + * @return the the gradient end color + */ + public Color getGradientEnd() { + return this.gradientEnd; + } + + /** + * @param gradientEnd the the gradient end color to set + */ + public void setGradientEnd(final Color gradientEnd) { + SWTGraphicUtil.dispose(this.gradientEnd); + this.gradientEnd = gradientEnd; + redraw(); + } + + /** + * @return the page increment when the user uses PgUp and PgDown + */ + public int getPageIncrement() { + return this.pageIncrement; + } + + /** + * @param pageIncrement the page increment to set + */ + public void setPageIncrement(final int pageIncrement) { + this.pageIncrement = pageIncrement; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/infinitePanel/InfiniteProgressPanel.java b/org.tizen.common.externals/src/org/mihalis/opal/infinitePanel/InfiniteProgressPanel.java new file mode 100644 index 000000000..e7a62dea3 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/infinitePanel/InfiniteProgressPanel.java @@ -0,0 +1,604 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation, + * inspired by Romain Guy's work (http://www.curious-creature.org) + *******************************************************************************/ +package org.mihalis.opal.infinitePanel; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class are controls located on the top of a shell. They + * display a ticker that indicates to the user that a long task operation is + * running + */ +public class InfiniteProgressPanel { + + private static final String INFINITE_PANEL_KEY = "org.mihalis.opal.InfinitePanel.InfiniteProgressPanel"; + private static final int NUMBER_OF_STEPS = 10; + + private final Shell parent; + private Shell panel; + private String text; + private Font textFont; + private Color textColor; + private float fps; + private int barsCount; + private int lineWidth; + private int alpha; + private Color defaultColor; + private Color selectionColor; + private int currentPosition; + private Thread animatorThread; + private Canvas canvas; + private boolean fadeIn; + private boolean fadeOut; + private int fadeOutCounter; + + /** + * Constructs a new instance of this class given its parent. + * + * @param shell a shell that will be the parent of the new instance (cannot + * be null) + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the parent has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ */ + private InfiniteProgressPanel(final Shell shell) { + if (shell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (shell.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + this.parent = shell; + if (shell.getData(INFINITE_PANEL_KEY) != null) { + throw new IllegalArgumentException("This shell has already an infinite panel attached on it !"); + } + + this.text = null; + this.textFont = null; + this.barsCount = 14; + this.fps = 15.0f; + this.lineWidth = 16; + this.alpha = 200; + this.fadeIn = false; + this.fadeOut = false; + this.fadeOutCounter = 0; + shell.setData(INFINITE_PANEL_KEY, this); + + this.parent.addListener(SWT.Activate, new Listener() { + + @Override + public void handleEvent(final Event e) { + if (InfiniteProgressPanel.this.panel != null && // + !InfiniteProgressPanel.this.panel.isDisposed() && !InfiniteProgressPanel.this.panel.isVisible()) { + InfiniteProgressPanel.this.panel.setVisible(true); + InfiniteProgressPanel.this.panel.setActive(); + } + } + }); + } + + /** + * Starts the ticker + */ + public void start() { + if (this.parent.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + this.panel = new Shell(this.parent, SWT.APPLICATION_MODAL | SWT.NO_TRIM | SWT.ON_TOP); + this.panel.setLayout(new FillLayout()); + this.panel.setAlpha(0); + + this.panel.addListener(SWT.KeyUp, new Listener() { + + @Override + public void handleEvent(final Event event) { + event.doit = false; + } + }); + + if (this.defaultColor == null) { + this.defaultColor = new Color(this.parent.getDisplay(), 200, 200, 200); + } + + if (this.selectionColor == null) { + this.selectionColor = new Color(this.parent.getDisplay(), 0, 0, 0); + } + + this.parent.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent e) { + SWTGraphicUtil.dispose(InfiniteProgressPanel.this.defaultColor); + SWTGraphicUtil.dispose(InfiniteProgressPanel.this.selectionColor); + } + }); + + this.currentPosition = 0; + this.fadeIn = true; + this.fadeOut = false; + this.fadeOutCounter = 0; + + this.canvas = new Canvas(this.panel, SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED); + this.canvas.addPaintListener(new PaintListener() { + + @Override + public void paintControl(final PaintEvent e) { + InfiniteProgressPanel.this.paintCanvas(e); + } + }); + + this.panel.setBounds(this.panel.getDisplay().map(this.parent, null, this.parent.getClientArea())); + this.panel.open(); + + this.animatorThread = new Thread() { + + /** + * @see java.lang.Thread#run() + */ + @Override + public void run() { + while (!Thread.interrupted()) { + InfiniteProgressPanel.this.currentPosition = (InfiniteProgressPanel.this.currentPosition + 1) % InfiniteProgressPanel.this.barsCount; + if (InfiniteProgressPanel.this.fadeOut) { + InfiniteProgressPanel.this.fadeOutCounter++; + } + InfiniteProgressPanel.this.panel.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + InfiniteProgressPanel.this.canvas.redraw(); + } + }); + + try { + sleep(InfiniteProgressPanel.this.fadeOut ? 20 : (long) (1000 / InfiniteProgressPanel.this.fps)); + } catch (final InterruptedException e) { + break; + } + } + } + }; + this.animatorThread.start(); + + this.panel.addListener(SWT.Deactivate, new Listener() { + + @Override + public void handleEvent(final Event arg0) { + InfiniteProgressPanel.this.panel.setVisible(false); + } + }); + + } + + /** + * Paint the canvas that holds the ticker + * + * @param e + */ + private void paintCanvas(final PaintEvent e) { + // Paint the panel + final Rectangle clientArea = ((Canvas) e.widget).getClientArea(); + final GC gc = e.gc; + + this.handleFadeIn(); + this.handleFadeOut(); + this.drawBackground(clientArea, gc); + this.drawTicker(clientArea, gc); + this.drawText(clientArea, gc); + + } + + /** + * Handle the fade in effect of the panel + */ + private void handleFadeIn() { + if (this.fadeIn) { + if (this.currentPosition == NUMBER_OF_STEPS) { + this.fadeIn = false; + this.panel.setAlpha(this.alpha); + } else { + this.panel.setAlpha(this.currentPosition * this.alpha / NUMBER_OF_STEPS); + } + } + } + + /** + * Handle the fade out effect of the panel + */ + private void handleFadeOut() { + if (this.fadeOut) { + if (this.fadeOutCounter == NUMBER_OF_STEPS) { + if (this.animatorThread != null) { + this.animatorThread.interrupt(); + this.animatorThread = null; + } + if (!this.panel.isDisposed()) { + this.panel.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if (!InfiniteProgressPanel.this.panel.isDisposed()) { + InfiniteProgressPanel.this.panel.dispose(); + } + } + }); + } + } + this.panel.setAlpha(255 - this.fadeOutCounter * this.alpha / NUMBER_OF_STEPS); + } + } + + /** + * Draw the background of the panel + * + * @param gc GC on with the background is drawn + * @param clientArea client area of the canvas + */ + private void drawBackground(final Rectangle clientArea, final GC gc) { + // Draw the background + gc.setBackground(this.panel.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.fillRectangle(clientArea); + } + + /** + * Draw the ticker + * + * @param gc GC on with the ticker is drawn + * @param clientArea client area of the canvas + */ + private void drawTicker(final Rectangle clientArea, final GC gc) { + // Draw the ticker + final int centerX = clientArea.width / 2; + final int centerY = clientArea.height / 2; + final int maxRay = (int) (Math.min(clientArea.width, clientArea.height) * 0.6f) / 2; + final int minRay = (int) (maxRay * 0.5f); + + double angle = Math.PI / 2; + + gc.setLineCap(SWT.CAP_ROUND); + gc.setLineWidth(this.lineWidth); + gc.setAntialias(SWT.ON); + + for (int i = 0; i < this.barsCount; i++) { + if (i == this.currentPosition) { + gc.setForeground(this.selectionColor); + } else { + gc.setForeground(this.defaultColor); + } + gc.drawLine((int) (centerX + minRay * Math.cos(angle)), // + (int) (centerY - minRay * Math.sin(angle)), // + (int) (centerX + maxRay * Math.cos(angle)), // + (int) (centerY - maxRay * Math.sin(angle))); + angle -= 2 * Math.PI / this.barsCount; + } + } + + /** + * Draw the text over the ticker + * + * @param gc GC on with the text is drawn + * @param clientArea client area of the canvas + */ + private void drawText(final Rectangle clientArea, final GC gc) { + if (this.text == null || "".equals(this.text)) { + return; + } + + final Font font; + if (this.textFont == null) { + font = this.parent.getDisplay().getSystemFont(); + } else { + font = this.textFont; + } + + final Color color; + if (this.textColor == null) { + color = this.parent.getDisplay().getSystemColor(SWT.COLOR_BLACK); + } else { + color = this.textColor; + } + + gc.setForeground(color); + gc.setFont(font); + gc.setTextAntialias(SWT.ON); + final Point textSize = gc.textExtent(this.text, SWT.DRAW_TRANSPARENT); + final int textWidth = textSize.x; + final int textHeight = textSize.y; + + gc.drawString(this.text, (clientArea.width - textWidth) / 2, (clientArea.height - textHeight) / 2, true); + + } + + /** + * Stop the animation and dispose the panel + */ + public void stop() { + if (this.panel.isDisposed() || this.panel.getDisplay().isDisposed()) { + return; + } + this.fadeOut = true; + } + + /** + * Returns the infinite progress panel for the shell. If no infinite panel + * has been declared, returns null. + * + * @param shell the shell for which we are trying to get the associated + * progess panel + * @return the progress panel associated to shell, or null if there is no + * progress panel + */ + public static InfiniteProgressPanel getInfiniteProgressPanelFor(final Shell shell) { + if (shell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (shell.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + if (shell.getDisplay().isDisposed()) { + SWT.error(SWT.ERROR_DEVICE_DISPOSED); + } + + final InfiniteProgressPanel[] temp = new InfiniteProgressPanel[1]; + shell.getDisplay().syncExec(new Runnable() { + + @Override + public void run() { + final Object data = shell.getData(INFINITE_PANEL_KEY); + if (data != null && data instanceof InfiniteProgressPanel) { + temp[0] = (InfiniteProgressPanel) data; + } + } + }); + + if (temp[0] == null) { + return new InfiniteProgressPanel(shell); + } else { + return temp[0]; + } + } + + /** + * Check if a shell has an associated progress panel + * + * @param shell the shell + * @return true if the shell has an associated panel, + * false otherwise + */ + public static boolean hasInfiniteProgressPanel(final Shell shell) { + return getInfiniteProgressPanelFor(shell) != null; + } + + // ------------------------------------------------- Getters and Setters + + /** + * @return the alpha value of the panel + */ + public int getAlpha() { + return this.alpha; + } + + /** + * @param alpha the alpha value of the panel, between 0 and 255 + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setAlpha(final int alpha) { + if (alpha < 0 || alpha > 255) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.checkIfAnimationIsRunning(); + this.alpha = alpha; + } + + /** + * Check if the animation is running + */ + private void checkIfAnimationIsRunning() { + if (this.animatorThread != null) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, "Can not change this value when an animation is running"); + } + } + + /** + * @return the number of bars displayed in the ticker + */ + public int getBarsCount() { + return this.barsCount; + } + + /** + * @param barsCount the number of bars displayed in the ticker + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setBarsCount(final int barsCount) { + this.checkIfAnimationIsRunning(); + this.barsCount = barsCount; + } + + /** + * @return the default color for the ticker's bars + */ + public Color getDefaultColor() { + return this.defaultColor; + } + + /** + * @param defaultColor the new default color for the ticker's bars. Please + * notice that the previous color is disposed. + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setDefaultColor(final Color defaultColor) { + this.checkIfAnimationIsRunning(); + SWTGraphicUtil.dispose(this.defaultColor); + this.defaultColor = defaultColor; + } + + /** + * @return the number of frame per second for the animation + */ + public float getFps() { + return this.fps; + } + + /** + * @param fps the new frame per second value + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setFps(final float fps) { + this.checkIfAnimationIsRunning(); + this.fps = fps; + } + + /** + * @return the line width of the bars that compose the ticker + */ + public int getLineWidth() { + return this.lineWidth; + } + + /** + * @param lineWidth the line width of the bars that compose the ticker + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setLineWidth(final int lineWidth) { + this.checkIfAnimationIsRunning(); + this.lineWidth = lineWidth; + } + + /** + * @return the selection color of the ticker's bars + */ + public Color getSelectionColor() { + return this.selectionColor; + } + + /** + * @param selectionColor the new selection color for the ticker's bars. + * Please notice that the previous color is disposed. + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setSelectionColor(final Color selectionColor) { + this.checkIfAnimationIsRunning(); + SWTGraphicUtil.dispose(this.selectionColor); + this.selectionColor = selectionColor; + } + + /** + * @return the displayed text + */ + public String getText() { + return this.text; + } + + /** + * @param text set the text to display + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setText(final String text) { + this.checkIfAnimationIsRunning(); + this.text = text; + } + + /** + * @return the text color + */ + public Color getTextColor() { + return this.textColor; + } + + /** + * @param textColor the text color. Please notice that the previous color is + * disposed. + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setTextColor(final Color textColor) { + this.checkIfAnimationIsRunning(); + SWTGraphicUtil.dispose(this.textColor); + this.textColor = textColor; + } + + /** + * @return the text font + */ + public Font getTextFont() { + return this.textFont; + } + + /** + * @param textFont the new text font. Please notice that the previous font + * set is disposed. + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_ARGUMENT - if the animation is running
  • + *
+ */ + public void setTextFont(final Font textFont) { + this.checkIfAnimationIsRunning(); + if (this.textFont != null && !this.textFont.isDisposed()) { + this.textFont.dispose(); + } + this.textFont = textFont; + + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DLItem.java b/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DLItem.java new file mode 100644 index 000000000..953226f21 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DLItem.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.mihalis.opal.itemSelector; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.mihalis.opal.OpalItem; + +/** + * Instances of this class represents items manipulated by this DualList widget + */ +public class DLItem extends OpalItem { + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + */ + public DLItem(final String text) { + this.setText(text); + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + */ + public DLItem(final String text, final Image image) { + this.setText(text); + this.setImage(image); + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + * @param font the font displayed in the DualList widget for this item + * @param foregroundColor the foreground color displayed in the DualList + * widget for this item + */ + public DLItem(final String text, final Image image, final Font font, final Color foregroundColor) { + this.setText(text); + this.setImage(image); + this.setFont(font); + this.setForeground(foregroundColor); + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + * @param foregroundColor the foreground color displayed in the DualList + * widget for this item + * @param backgroundColor the background color displayed in the DualList + * widget for this item + */ + public DLItem(final String text, final Image image, final Color foregroundColor, final Color backgroundColor) { + this.setText(text); + this.setImage(image); + this.setForeground(foregroundColor); + this.setBackground(backgroundColor); + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + * @param font the font displayed in the DualList widget for this item + */ + public DLItem(final String text, final Image image, final Font font) { + this.setText(text); + this.setImage(image); + this.setFont(font); + } + + /** + * @see org.mihalis.opal.OpalItem#getHeight() + */ + @Override + public int getHeight() { + throw new UnsupportedOperationException("DLItem does not support this method"); + } + + /** + * @see org.mihalis.opal.OpalItem#setHeight(int) + */ + @Override + public void setHeight(final int height) { + throw new UnsupportedOperationException("DLItem does not support this method"); + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DualList.java b/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DualList.java new file mode 100644 index 000000000..8b6b90296 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DualList.java @@ -0,0 +1,1265 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.mihalis.opal.itemSelector; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.mihalis.opal.utils.SWTGraphicUtil; +import org.mihalis.opal.utils.SimpleSelectionAdapter; + +/** + * Instances of this class are controls that allow the user to select multiple + * elements. + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
Selection
+ *
+ */ + +public class DualList extends Composite { + + private final List items; + private final List selection; + + private final Table itemsTable; + private final Table selectionTable; + + private List eventTable; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public DualList(final Composite parent, final int style) { + super(parent, style); + this.items = new ArrayList(); + this.selection = new ArrayList(); + + this.setLayout(new GridLayout(4, false)); + this.itemsTable = this.createTable(); + this.itemsTable.addMouseListener(new MouseAdapter() { + + /** + * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void mouseDoubleClick(final MouseEvent event) { + DualList.this.selectItem(); + } + + }); + final Button buttonSelectAll = this.createButton("double_right.png", true, GridData.END); + buttonSelectAll.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.selectAll(); + } + }); + + this.selectionTable = this.createTable(); + this.selectionTable.addMouseListener(new MouseAdapter() { + + /** + * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + @Override + public void mouseDoubleClick(final MouseEvent event) { + DualList.this.deselectItem(); + } + + }); + + final Button buttonMoveFirst = this.createButton("double_up.png", true, GridData.END); + buttonMoveFirst.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.moveSelectionToFirstPosition(); + } + }); + + final Button buttonSelect = this.createButton("arrow_right.png", false, GridData.CENTER); + buttonSelect.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.selectItem(); + } + }); + + final Button buttonMoveUp = this.createButton("arrow_up.png", false, GridData.CENTER); + buttonMoveUp.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.moveUpItem(); + } + }); + + final Button buttonDeselect = this.createButton("arrow_left.png", false, GridData.CENTER); + buttonDeselect.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.deselectItem(); + } + }); + + final Button buttonMoveDown = this.createButton("arrow_down.png", false, GridData.CENTER); + buttonMoveDown.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.moveDownItem(); + } + }); + + final Button buttonDeselectAll = this.createButton("double_left.png", false, GridData.BEGINNING); + buttonDeselectAll.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.deselectAll(); + } + }); + + final Button buttonMoveLast = this.createButton("double_down.png", true, GridData.BEGINNING); + buttonMoveLast.addSelectionListener(new SimpleSelectionAdapter() { + + @Override + public void handle(final SelectionEvent e) { + DualList.this.moveSelectionToLastPosition(); + } + }); + + } + + /** + * @return a table that will contain data + */ + private Table createTable() { + final Table table = new Table(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); + table.setLinesVisible(false); + table.setHeaderVisible(false); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 4); + gd.widthHint = 200; + table.setLayoutData(gd); + new TableColumn(table, SWT.CENTER); + new TableColumn(table, SWT.LEFT); + table.setData(-1); + return table; + } + + /** + * Create a button + * + * @param fileName file name of the icon + * @param verticalExpand if true, the button will take all the + * available space vertically + * @param alignment button alignment + * @return a new button + */ + private Button createButton(final String fileName, final boolean verticalExpand, final int alignment) { + final Button button = new Button(this, SWT.PUSH); + final Image image = new Image(this.getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/" + fileName)); + button.setImage(image); + button.setLayoutData(new GridData(GridData.CENTER, alignment, false, verticalExpand)); + button.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(final DisposeEvent e) { + SWTGraphicUtil.dispose(image); + } + }); + return button; + } + + /** + * Adds the argument to the end of the receiver's list. + * + * @param item the new item + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #add(DLItem,int) + */ + public void add(final DLItem item) { + this.checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + this.items.add(item); + } + + /** + * Adds the argument to the receiver's list at the given zero-relative + * index. + *

+ * Note: To add an item at the end of the list, use the result of calling + * getItemCount() as the index or use add(DLItem). + *

+ * + * @param item the new item + * @param index the index for the item + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_RANGE - if the index is not between 0 + * and the number of elements in the list (inclusive)
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #add(String) + */ + public void add(final DLItem item, final int index) { + this.checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (index <= 0 || index >= this.items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.items.add(index, item); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the user changes the receiver's selection, by sending it one of the + * messages defined in the SelectionListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + this.checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (this.eventTable == null) { + this.eventTable = new ArrayList(); + } + this.eventTable.add(listener); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + this.checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (this.eventTable == null) { + return; + } + this.eventTable.remove(listener); + } + + /** + * Deselects the item at the given zero-relative index in the receiver. If + * the item at the index was already deselected, it remains deselected. + * Indices that are out of range are ignored. + * + * @param index the index of the item to deselect + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselect(final int index) { + this.checkWidget(); + if (index <= 0 || index >= this.items.size()) { + return; + } + this.fireEvents(this.selection.remove(index)); + this.redrawTables(); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. + * If the item at the given zero-relative index in the receiver is selected, + * it is deselected. If the item at the index was not selected, it remains + * deselected. Indices that are out of range and duplicate indices are + * ignored. + * + * @param indices the array of indices for the items to deselect + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselect(final int[] indices) { + this.checkWidget(); + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final List toBeRemoved = new ArrayList(); + + for (final int index : indices) { + if (index <= 0 || index >= this.items.size()) { + continue; + } + toBeRemoved.add(this.selection.get(index)); + } + + for (final DLItem item : toBeRemoved) { + this.selection.remove(item); + } + toBeRemoved.clear(); + this.redrawTables(); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. + * If the item at the given zero-relative index in the receiver is selected, + * it is deselected. If the item at the index was not selected, it remains + * deselected. The range of the indices is inclusive. Indices that are out + * of range are ignored. + * + * @param start the start index of the items to deselect + * @param end the end index of the items to deselect + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_RANGE - if start is greater than end
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselect(final int start, final int end) { + this.checkWidget(); + if (start > end) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + final List toBeRemoved = new ArrayList(); + + for (int index = start; index <= end; index++) { + if (index <= 0 || index >= this.items.size()) { + continue; + } + toBeRemoved.add(this.selection.get(index)); + } + + for (final DLItem item : toBeRemoved) { + this.selection.remove(item); + } + toBeRemoved.clear(); + this.redrawTables(); + } + + /** + * Deselects all selected items in the receiver. + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselectAll() { + this.checkWidget(); + this.items.addAll(this.selection); + this.selection.clear(); + this.redrawTables(); + } + + /** + * Returns the item at the given, zero-relative index in the receiver. + * Throws an exception if the index is out of range. + * + * @param index the index of the item to return + * @return the item at the given index + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 + * and the number of elements in the list minus 1 (inclusive) + *
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + + public DLItem getItem(final int index) { + this.checkWidget(); + if (index <= 0 || index >= this.items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return this.items.get(index); + } + + /** + * Returns the number of items contained in the receiver. + * + * @return the number of items + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getItemCount() { + this.checkWidget(); + return this.items.size(); + } + + /** + * Returns a (possibly empty) array of DLItems which are the + * items in the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain + * its list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the items in the receiver's list + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public DLItem[] getItems() { + this.checkWidget(); + return this.items.toArray(new DLItem[this.items.size()]); + } + + /** + * Returns a (possibly empty) list of DLItems which are the + * items in the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain + * its list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the items in the receiver's list + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public List getItemsAsList() { + this.checkWidget(); + return new ArrayList(this.items); + } + + /** + * Returns an array of DLItems that are currently selected in + * the receiver. An empty array indicates that no items are selected. + *

+ * Note: This is not the actual structure used by the receiver to maintain + * its selection, so modifying the array will not affect the receiver. + *

+ * + * @return an array representing the selection + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public DLItem[] getSelection() { + this.checkWidget(); + return this.selection.toArray(new DLItem[this.items.size()]); + } + + /** + * Returns a list of DLItems that are currently selected in the + * receiver. An empty array indicates that no items are selected. + *

+ * Note: This is not the actual structure used by the receiver to maintain + * its selection, so modifying the array will not affect the receiver. + *

+ * + * @return an array representing the selection + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public List getSelectionAsList() { + this.checkWidget(); + return new ArrayList(this.selection); + } + + /** + * Returns the number of selected items contained in the receiver. + * + * @return the number of selected items + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getSelectionCount() { + this.checkWidget(); + return this.selection.size(); + } + + /** + * Removes the item from the receiver at the given zero-relative index. + * + * @param index the index for the item + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 + * and the number of elements in the list minus 1 (inclusive) + *
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final int index) { + this.checkWidget(); + if (index <= 0 || index >= this.items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.items.remove(index); + this.redrawTables(); + } + + /** + * Removes the items from the receiver at the given zero-relative indices. + * + * @param indices the array of indices of the items + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 + * and the number of elements in the list minus 1 (inclusive) + *
  • + *
  • ERROR_NULL_ARGUMENT - if the indices array is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final int[] indices) { + this.checkWidget(); + for (final int index : indices) { + if (index <= 0 || index >= this.items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.items.remove(index); + } + this.redrawTables(); + } + + /** + * Removes the items from the receiver which are between the given + * zero-relative start and end indices (inclusive). + * + * @param start the start of the range + * @param end the end of the range + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_RANGE - if either the start or end are + * not between 0 and the number of elements in the list minus + * 1 (inclusive) or if start>end
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final int start, final int end) { + this.checkWidget(); + if (start > end) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + for (int index = start; index <= end; index++) { + if (index <= 0 || index >= this.items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.items.remove(index); + } + this.redrawTables(); + } + + /** + * Searches the receiver's list starting at the first item until an item is + * found that is equal to the argument, and removes that item from the list. + * + * @param item the item to remove + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item is not found in + * the list
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final DLItem item) { + this.checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (!this.items.contains(item)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.items.remove(item); + this.redrawTables(); + } + + /** + * Removes all of the items from the receiver. + *

+ * + * @exception SWTException

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • ERROR_THREAD_INVALID_ACCESS - if not + * called from the thread that created the receiver
  • + *
+ */ + public void removeAll() { + this.checkWidget(); + this.items.clear(); + this.redrawTables(); + } + + /** + * Selects the item at the given zero-relative index in the receiver's list. + * If the item at the index was already selected, it remains selected. + * Indices that are out of range are ignored. + * + * @param index the index of the item to select + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void select(final int index) { + this.checkWidget(); + if (index <= 0 || index >= this.items.size()) { + return; + } + this.selection.add(this.items.get(index)); + this.fireEvents(this.items.get(index)); + this.redrawTables(); + } + + /** + * Selects the items at the given zero-relative indices in the receiver. The + * current selection is not cleared before the new items are selected. + *

+ * If the item at a given index is not selected, it is selected. If the item + * at a given index was already selected, it remains selected. Indices that + * are out of range and duplicate indices are ignored. If the receiver is + * single-select and multiple indices are specified, then all indices are + * ignored. + * + * @param indices the array of indices for the items to select + * + * @exception IllegalArgumentException

    + *
  • ERROR_NULL_ARGUMENT - if the array of indices is null + *
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • ERROR_THREAD_INVALID_ACCESS - if not + * called from the thread that created the receiver
  • + *
+ */ + public void select(final int[] indices) { + this.checkWidget(); + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + for (final int index : indices) { + if (index <= 0 || index >= this.items.size()) { + continue; + } + this.selection.add(this.items.get(index)); + this.fireEvents(this.items.get(index)); + } + this.redrawTables(); + } + + /** + * Selects the items in the range specified by the given zero-relative + * indices in the receiver. The range of indices is inclusive. The current + * selection is not cleared before the new items are selected. + *

+ * If an item in the given range is not selected, it is selected. If an item + * in the given range was already selected, it remains selected. Indices + * that are out of range are ignored and no items will be selected if start + * is greater than end. If the receiver is single-select and there is more + * than one item in the given range, then all indices are ignored. + * + * @param start the start of the range + * @param end the end of the range + * + * @exception SWTException

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • ERROR_THREAD_INVALID_ACCESS - if not + * called from the thread that created the receiver
  • + *
+ * + * @see List#setSelection(int,int) + */ + public void select(final int start, final int end) { + this.checkWidget(); + if (start > end) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + for (int index = start; index <= end; index++) { + if (index <= 0 || index >= this.items.size()) { + continue; + } + this.selection.add(this.items.get(index)); + this.fireEvents(this.items.get(index)); + } + this.redrawTables(); + } + + /** + * Selects all of the items in the receiver. + *

+ * If the receiver is single-select, do nothing. + * + * @exception SWTException

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • ERROR_THREAD_INVALID_ACCESS - if not + * called from the thread that created the receiver
  • + *
+ */ + public void selectAll() { + this.checkWidget(); + this.selection.addAll(this.items); + for (final DLItem item : this.items) { + this.fireEvents(item); + } + this.items.clear(); + this.redrawTables(); + } + + /** + * @see org.eclipse.swt.widgets.Control#setBounds(int, int, int, int) + */ + @Override + public void setBounds(final int x, final int y, final int width, final int height) { + super.setBounds(x, y, width, height); + final boolean itemsContainImage = this.itemsContainImage(); + final Point itemsTableDefaultSize = this.itemsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); + final Point selectionTableDefaultSize = this.selectionTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); + + int itemsTableSize = this.itemsTable.getSize().x; + if (itemsTableDefaultSize.y > this.itemsTable.getSize().y) { + itemsTableSize -= this.itemsTable.getVerticalBar().getSize().x; + } + + int selectionTableSize = this.selectionTable.getSize().x; + if (selectionTableDefaultSize.y > this.selectionTable.getSize().y) { + selectionTableSize -= this.selectionTable.getVerticalBar().getSize().x; + } + + if (itemsContainImage) { + this.itemsTable.getColumn(0).pack(); + this.itemsTable.getColumn(1).setWidth(itemsTableSize - this.itemsTable.getColumn(0).getWidth()); + + this.selectionTable.getColumn(0).pack(); + this.selectionTable.getColumn(1).setWidth(selectionTableSize - this.selectionTable.getColumn(0).getWidth()); + + } else { + this.itemsTable.getColumn(0).setWidth(itemsTableSize); + this.selectionTable.getColumn(0).setWidth(selectionTableSize); + } + } + + /** + * @return true if any item contains an image + */ + private boolean itemsContainImage() { + for (final DLItem item : this.items) { + if (item.getImage() != null) { + return true; + } + } + + for (final DLItem item : this.selection) { + if (item.getImage() != null) { + return true; + } + } + + return false; + } + + /** + * Sets the item in the receiver's list at the given zero-relative index to + * the item argument. + * + * @param index the index for the item + * @param item the new item + * + * @exception IllegalArgumentException
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 + * and the number of elements in the list minus 1 (inclusive) + *
  • + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setItem(final int index, final DLItem item) { + this.checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (index <= 0 || index >= this.items.size()) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + this.items.set(index, item); + this.redrawTables(); + } + + /** + * Sets the receiver's items to be the given array of items. + * + * @param items the array of items + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the items array is null
  • + *
  • ERROR_INVALID_ARGUMENT - if an item in the items array + * is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setItems(final DLItem[] items) { + this.checkWidget(); + if (items == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final List temp = new ArrayList(); + for (final DLItem item : items) { + if (item == null) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + temp.add(item); + } + this.items.clear(); + this.items.addAll(temp); + this.redrawTables(); + } + + /** + * Sets the receiver's items to be the given list of items. + * + * @param items the list of items + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the items list is null
  • + *
  • ERROR_INVALID_ARGUMENT - if an item in the items list + * is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setItems(final List items) { + this.checkWidget(); + this.checkWidget(); + if (items == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final List temp = new ArrayList(); + for (final DLItem item : items) { + if (item == null) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + temp.add(item); + } + this.items.clear(); + this.items.addAll(temp); + this.redrawTables(); + } + + /** + * Redraws all tables that compose this widget + */ + private void redrawTables() { + this.setRedraw(false); + this.redrawTable(this.itemsTable, false); + this.redrawTable(this.selectionTable, true); + this.setRedraw(true); + this.setBounds(this.getBounds()); + } + + /** + * Redraw a given table + * + * @param table table to be redrawned + * @param isSelected if true, fill the table with the + * selection. Otherwise, fill the table with the unselected + * items. + */ + private void redrawTable(final Table table, final boolean isSelected) { + this.clean(table); + this.fillData(table, isSelected ? this.selection : this.items); + } + + /** + * Cleans the content of a table + * + * @param table table to be emptied + */ + private void clean(final Table table) { + if (table == null) { + return; + } + + for (final TableItem item : table.getItems()) { + item.dispose(); + } + } + + /** + * Fill a table with data + * + * @param table table to be filled + * @param listOfData list of data + */ + private void fillData(final Table table, final List listOfData) { + for (final DLItem item : listOfData) { + final TableItem tableItem = new TableItem(table, SWT.NONE); + tableItem.setData(item); + + if (item.getBackground() != null) { + tableItem.setBackground(item.getBackground()); + } + + if (item.getForeground() != null) { + tableItem.setForeground(item.getForeground()); + } + + if (item.getImage() != null) { + tableItem.setImage(0, item.getImage()); + } + + if (item.getFont() != null) { + tableItem.setFont(item.getFont()); + } + + tableItem.setText(1, item.getText()); + } + + } + + /** + * Move the selected item to the first position + */ + protected void moveSelectionToFirstPosition() { + if (this.selectionTable.getSelectionCount() == 0) { + return; + } + + int index = 0; + for (final TableItem tableItem : this.selectionTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + this.selection.remove(item); + this.selection.add(index++, item); + } + + this.redrawTables(); + this.selectionTable.select(0, index - 1); + this.selectionTable.forceFocus(); + } + + /** + * Select a given item + */ + protected void selectItem() { + if (this.itemsTable.getSelectionCount() == 0) { + return; + } + for (final TableItem tableItem : this.itemsTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + this.selection.add(item); + this.items.remove(item); + } + this.redrawTables(); + } + + /** + * Move the selected item up + */ + protected void moveUpItem() { + if (this.selectionTable.getSelectionCount() == 0) { + return; + } + + for (final int index : this.selectionTable.getSelectionIndices()) { + if (index == 0) { + this.selectionTable.forceFocus(); + return; + } + } + + final int[] newSelection = new int[this.selectionTable.getSelectionCount()]; + int newSelectionIndex = 0; + for (final TableItem tableItem : this.selectionTable.getSelection()) { + final int position = this.selection.indexOf(tableItem.getData()); + this.swap(position, position - 1); + newSelection[newSelectionIndex++] = position - 1; + } + + this.redrawTables(); + this.selectionTable.select(newSelection); + this.selectionTable.forceFocus(); + } + + /** + * Deselect a given item + */ + protected void deselectItem() { + if (this.selectionTable.getSelectionCount() == 0) { + return; + } + for (final TableItem tableItem : this.selectionTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + this.items.add(item); + this.selection.remove(item); + } + this.redrawTables(); + } + + /** + * Move the selected item down + */ + protected void moveDownItem() { + if (this.selectionTable.getSelectionCount() == 0) { + return; + } + + for (final int index : this.selectionTable.getSelectionIndices()) { + if (index == this.selectionTable.getItemCount() - 1) { + this.selectionTable.forceFocus(); + return; + } + } + + final int[] newSelection = new int[this.selectionTable.getSelectionCount()]; + int newSelectionIndex = 0; + for (final TableItem tableItem : this.selectionTable.getSelection()) { + final int position = this.selection.indexOf(tableItem.getData()); + this.swap(position, position + 1); + newSelection[newSelectionIndex++] = position + 1; + } + + this.redrawTables(); + this.selectionTable.select(newSelection); + this.selectionTable.forceFocus(); + + } + + /** + * Swap 2 items + * + * @param first position of the first item to swap + * @param second position of the second item to swap + */ + private void swap(final int first, final int second) { + final DLItem temp = this.selection.get(first); + this.selection.set(first, this.selection.get(second)); + this.selection.set(second, temp); + } + + /** + * Move the selected item to the last position + */ + protected void moveSelectionToLastPosition() { + if (this.selectionTable.getSelectionCount() == 0) { + return; + } + + final int numberOfSelectedElements = this.selectionTable.getSelectionCount(); + for (final TableItem tableItem : this.selectionTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + this.selection.remove(item); + this.selection.add(item); + } + + this.redrawTables(); + final int numberOfElements = this.selectionTable.getItemCount(); + this.selectionTable.select(numberOfElements - numberOfSelectedElements, numberOfElements - 1); + this.selectionTable.forceFocus(); + } + + /** + * Call all selection listeners + * + * @param item selected item + */ + private void fireEvents(final DLItem item) { + if (this.eventTable == null) { + return; + } + + final Event event = new Event(); + event.button = 1; + event.display = this.getDisplay(); + event.item = null; + event.widget = this; + event.data = item; + final SelectionEvent selectionEvent = new SelectionEvent(event); + + for (final SelectionListener listener : this.eventTable) { + listener.widgetSelected(selectionEvent); + } + + } +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/launcher/LLabel.java b/org.tizen.common.externals/src/org/mihalis/opal/launcher/LLabel.java new file mode 100644 index 000000000..d6aa5e577 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/launcher/LLabel.java @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.launcher; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instance of this class are a button with text, image and a nice animation + * effect + */ +class LLabel extends Canvas { + + private String text; + private Image image; + private Font font; + + private static final int GAP = 12; + private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER; + private static final int DEFAULT_MARGIN = 5; + private final int leftMargin = DEFAULT_MARGIN; + private final int topMargin = DEFAULT_MARGIN; + private final int rightMargin = DEFAULT_MARGIN; + private final int bottomMargin = DEFAULT_MARGIN; + private Point textSize; + + private static final int MAX_NUMBER_OF_STEPS = 10; + private int animationStep = 0; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + LLabel(final Composite parent, final int style) { + super(parent, style | SWT.BORDER | SWT.DOUBLE_BUFFERED); + + final Font original = super.getFont(); + + this.font = new Font(getDisplay(), original.getFontData()[0].getName(), 18, SWT.BOLD); + + addPaintListener(new PaintListener() { + @Override + public void paintControl(final PaintEvent event) { + onPaint(event); + } + }); + + addListener(SWT.Dispose, new Listener() { + @Override + public void handleEvent(final Event event) { + onDispose(event); + } + }); + } + + /** + * Draw the content of the LLabel + * + * @param event paintevent + */ + private void onPaint(final PaintEvent event) { + final Rectangle rect = getClientArea(); + if (rect.width == 0 || rect.height == 0) { + return; + } + + final Image bufferImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height)); + + final GC gc = new GC(bufferImage); + gc.setForeground(getForeground()); + gc.setBackground(getBackground()); + + gc.fillRectangle(rect); + + final Point extent = getTotalSize(this.image.getBounds().width, this.image.getBounds().height); + final int xImage = (rect.width - this.image.getBounds().width) / 2; + final int yImage = (rect.height - extent.y) / 2; + gc.drawImage(this.image, xImage, yImage); + + gc.setFont(this.font); + final int xText = (rect.width - this.textSize.x) / 2; + final int yText = yImage + this.image.getBounds().height + GAP - this.textSize.y / 2; + gc.drawString(this.text, xText, yText); + + if (this.animationStep != 0) { + final float zoom = 1f + this.animationStep * (Math.max(extent.x, extent.y) - Math.max(this.image.getBounds().width, this.image.getBounds().height)) / MAX_NUMBER_OF_STEPS / 100f; + + final int newSizeX = (int) (this.image.getBounds().width * zoom); + final int newSizeY = (int) (this.image.getBounds().height * zoom); + + gc.setAntialias(SWT.ON); + gc.setInterpolation(SWT.HIGH); + + gc.setAlpha(255 - 255 / MAX_NUMBER_OF_STEPS * this.animationStep); + + final Point extentZoomedImage = getTotalSize(newSizeX, newSizeY); + final int xZoomedImage = (rect.width - newSizeX) / 2; + final int yZoomedImage = (rect.height - extentZoomedImage.y) / 2; + gc.drawImage(this.image, 0, 0, this.image.getBounds().width, this.image.getBounds().height, xZoomedImage, yZoomedImage, (int) (this.image.getBounds().width * zoom), (int) (this.image.getBounds().height * zoom)); + + } + + gc.dispose(); + + event.gc.drawImage(bufferImage, 0, 0); + + bufferImage.dispose(); + + } + + /** + * Dispose elements when the widget is disposed + * + * @param event dispose event + */ + private void onDispose(final Event event) { + SWTGraphicUtil.dispose(this.image); + SWTGraphicUtil.dispose(this.font); + this.text = null; + this.image = null; + } + + /** + * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + checkWidget(); + final Point e = getTotalSize(this.image.getBounds().width, this.image.getBounds().height); + if (wHint == SWT.DEFAULT) { + e.x += this.leftMargin + this.rightMargin; + } else { + e.x = wHint; + } + if (hHint == SWT.DEFAULT) { + e.y += this.topMargin + this.bottomMargin; + } else { + e.y = hHint; + } + return e; + } + + /** + * Compute the size of the content (image + text + gap) + * + * @param imgWidth image width + * @param imgHeight image height + * @return the size of the content + */ + private Point getTotalSize(final int imgWidth, final int imgHeight) { + final Point size = new Point(0, 0); + + int textWidth = 0; + int textHeight = 0; + + if (this.textSize == null) { + final GC gc = new GC(this); + gc.setFont(this.font); + + this.textSize = gc.textExtent(this.text, DRAW_FLAGS); + gc.dispose(); + + } + textWidth = this.textSize.x; + textHeight = this.textSize.y; + + size.x = Math.max(imgWidth, textWidth); + size.y = imgHeight + GAP + textHeight; + + return size; + } + + /** + * @return the text + */ + String getText() { + return this.text; + } + + /** + * @param text the text to set + */ + void setText(final String text) { + this.text = text; + } + + /** + * @return the image + */ + Image getImage() { + return this.image; + } + + /** + * @param image the image to set + */ + void setImage(final Image image) { + this.image = image; + } + + /** + * @return the font + */ + @Override + public Font getFont() { + return this.font; + } + + /** + * @param font the font to set + */ + @Override + public void setFont(final Font font) { + SWTGraphicUtil.dispose(font); + this.font = font; + } + + /** + * Increment the steps of the animation + * + * @return true if animation keeps running, false otherwise + */ + boolean incrementAnimation() { + this.animationStep++; + final boolean stopAnimation = this.animationStep > MAX_NUMBER_OF_STEPS; + + if (stopAnimation) { + this.animationStep = 0; + } + if (!isDisposed()) { + redraw(); + } + return !stopAnimation; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/launcher/Launcher.java b/org.tizen.common.externals/src/org/mihalis/opal/launcher/Launcher.java new file mode 100755 index 000000000..42bf7b1f8 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/launcher/Launcher.java @@ -0,0 +1,428 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.launcher; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class are a launcher composed of buttons. When one clicks + * on the button, an animation is started and a selection event is fired + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
Selection
+ *
+ */ +public class Launcher extends Composite { + + private final List items; + private final List selectionListeners; + private boolean needRedraw; + private int selection = -1; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public Launcher(final Composite parent, final int style) { + super(parent, style | SWT.BORDER); + this.items = new ArrayList(); + this.selectionListeners = new ArrayList(); + this.needRedraw = true; + setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + this.addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(final Event event) { + drawLauncher(); + } + }); + + this.addListener(SWT.KeyUp, new Listener() { + + @Override + public void handleEvent(final Event event) { + OnKeyPressed(event); + } + }); + + } + + /** + * Draw the launcher + */ + private void drawLauncher() { + if (!this.needRedraw) { + return; + } + + disposePreviousContent(); + createButtons(); + pack(); + + this.needRedraw = false; + } + + /** + * Dispose the content before a redraw + */ + private void disposePreviousContent() { + for (final Control c : this.getChildren()) { + c.dispose(); + } + } + + /** + * Create the buttons that will compose the launcher + */ + private void createButtons() { + final GridLayout gridLayout = new GridLayout(this.items.size() / 2, true); + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; + this.setLayout(gridLayout); + for (final LauncherItem item : this.items) { + final LLabel label = new LLabel(this, SWT.CENTER); + label.setText(item.title); + label.setImage(SWTGraphicUtil.createImage(item.image)); + label.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false); + gd.widthHint = 192; + gd.heightHint = 220; + label.setLayoutData(gd); + item.label = label; + + label.addListener(SWT.KeyUp, new Listener() { + + @Override + public void handleEvent(final Event event) { + OnKeyPressed(event); + } + }); + + label.addListener(SWT.MouseUp, new Listener() { + + @Override + public void handleEvent(final Event event) { + OnClick(event); + } + }); + + label.addListener(SWT.MouseDoubleClick, new Listener() { + + @Override + public void handleEvent(final Event event) { + OnDoubleClick(event); + } + }); + + } + } + + /** + * Code executed when a key is pressed + * + * @param event Event + */ + private void OnKeyPressed(final Event event) { + switch (event.keyCode) { + case SWT.ARROW_LEFT: + if (this.selection == -1) { + this.selection = 0; + changeColor(this.selection, true); + return; + } + + if (this.selection % 2 == 1) { + changeColor(this.selection, false); + this.selection--; + changeColor(this.selection, true); + } + break; + case SWT.ARROW_UP: + if (this.selection == -1) { + this.selection = 0; + changeColor(this.selection, true); + return; + } + if (this.selection >= 2) { + changeColor(this.selection, false); + this.selection -= 2; + changeColor(this.selection, true); + } + break; + case SWT.ARROW_RIGHT: + if (this.selection == -1) { + this.selection = 0; + changeColor(this.selection, true); + return; + } + if (this.selection % 2 == 0) { + changeColor(this.selection, false); + this.selection++; + changeColor(this.selection, true); + } + break; + case SWT.ARROW_DOWN: + if (this.selection == -1) { + this.selection = 0; + changeColor(this.selection, true); + return; + } + if (this.selection <= this.items.size() - 2) { + changeColor(this.selection, false); + this.selection += 2; + changeColor(this.selection, true); + } + break; + case SWT.HOME: + changeColor(this.selection, false); + this.selection = 0; + changeColor(this.selection, true); + break; + case SWT.END: + changeColor(this.selection, false); + this.selection = this.items.size() - 1; + changeColor(this.selection, true); + break; + default: + break; + } + + } + + /** + * Code executed when one clicks on the button + * + * @param event Event + */ + private void OnClick(final Event event) { + for (int i = 0; i < this.items.size(); i++) { + final LauncherItem item = this.items.get(i); + if (item.label != null && item.label.equals(event.widget)) { + if (this.selection != i) { + changeColor(this.selection, false); + this.selection = i; + changeColor(this.selection, true); + } + return; + } + } + } + + /** + * Change the background color of a given button + * + * @param index index of the button + * @param isSelected if true, the background is the light + * shadow. Otherwise, the background color is white + */ + private void changeColor(final int index, final boolean isSelected) { + if (index != -1 && this.items.get(index).label != null) { + this.items.get(index).label.setBackground(isSelected ? getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW) : getDisplay().getSystemColor(SWT.COLOR_WHITE)); + } + } + + /** + * Code executed when one double-clicks on a button + * + * @param event Event + */ + private void OnDoubleClick(final Event event) { + for (int i = 0; i < this.items.size(); i++) { + final LauncherItem item = this.items.get(i); + if (item.label != null && item.label.equals(event.widget)) { + if (this.selection != i) { + changeColor(this.selection, false); + this.selection = i; + changeColor(this.selection, true); + } + startAnimation(i, event); + return; + } + } + } + + /** + * Start the animation for a given button + * + * @param index index of the selected button + * @param event event (propagated to the selection listeners) + */ + private void startAnimation(final int index, final Event event) { + final LLabel label = this.items.get(index).label; + getDisplay().timerExec(0, new Runnable() { + + @Override + public void run() { + if (label.incrementAnimation()) { + getDisplay().timerExec(20, this); + } else { + fireSelectionListeners(event); + } + } + }); + + } + + /** + * Fire the selection listeners + * + * @param originalEvent mouse event + * @return true if the selection could be changed, + * false otherwise + */ + private boolean fireSelectionListeners(final Event originalEvent) { + for (final SelectionListener listener : this.selectionListeners) { + final Event event = new Event(); + + event.button = originalEvent.button; + event.display = this.getDisplay(); + event.item = null; + event.widget = this; + event.data = null; + event.time = originalEvent.time; + event.x = originalEvent.x; + event.y = originalEvent.y; + + final SelectionEvent selEvent = new SelectionEvent(event); + listener.widgetSelected(selEvent); + if (!selEvent.doit) { + return false; + } + } + return true; + } + + /** + * Add an item to the launcher + * + * @param title text associated to this item + * @param image image associated to this item + */ + public void addItem(final String title, final String image) { + checkWidget(); + this.items.add(new LauncherItem(title, image)); + this.needRedraw = true; + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the control is selected by the user, by sending it one of the + * messages defined in the SelectionListener interface. + *

+ * widgetSelected is called when the control is selected by the + * user. widgetDefaultSelected is not called. + *

+ * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + this.selectionListeners.add(listener); + + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + this.selectionListeners.remove(listener); + } + + /** + * Return the selected button + * + * @return the index of the selected button + * + * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public int getSelection() { + checkWidget(); + return this.selection; + } +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/launcher/LauncherItem.java b/org.tizen.common.externals/src/org/mihalis/opal/launcher/LauncherItem.java new file mode 100644 index 000000000..bb5dc13db --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/launcher/LauncherItem.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.mihalis.opal.launcher; + +/** + * Instances of this class are POJO to store information handled by the Launcher + * widget I could have used a inner class but I prefer this solution :) + */ +class LauncherItem { + String title; + String image; + LLabel label; + + /** + * Constructor + * + * @param title text associated to the item + * @param image image associated to the item + */ + LauncherItem(final String title, final String image) { + this.title = title; + this.image = image; + } +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialog.java b/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialog.java new file mode 100644 index 000000000..b811971ab --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialog.java @@ -0,0 +1,511 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.mihalis.opal.login; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.mihalis.opal.opalDialog.Dialog; +import org.mihalis.opal.utils.ResourceManager; +import org.mihalis.opal.utils.SWTGraphicUtil; + +/** + * Instances of this class are Login Dialog box, which is composed of + *

+ *

+ *
A login
+ *
A password
+ *
An image
+ *
(optional)
+ *
A description
+ *
(optional)
+ *
A checkbox "remember the password"
+ *
(optional)
+ *
+ *

+ */ +public class LoginDialog { + private Image image; + private String description; + private String login; + private String password; + private List autorizedLogin; + private boolean displayRememberPassword; + private boolean rememberPassword; + private LoginDialogVerifier verifier; + + private Shell shell; + private boolean returnedValue; + private Button buttonOk; + + /** + * Constructor + */ + public LoginDialog() { + this.displayRememberPassword = true; + } + + /** + * Open the Login box + * + * @return true if the authentication is OK, false + * if the user pressed on cancel. + */ + public boolean open() { + if (this.verifier == null) { + throw new IllegalArgumentException("Please set a verifier before opening the dialog box"); + } + + buildDialog(); + openShell(); + + return this.returnedValue; + } + + /** + * Build the dialog box + */ + private void buildDialog() { + buildShell(); + buildImage(); + buildDescription(); + buildLogin(); + buildPassword(); + if (this.displayRememberPassword) { + buildRememberPassword(); + } + buildButtons(); + } + + /** + * Build the shell + */ + private void buildShell() { + this.shell = new Shell(SWT.SYSTEM_MODAL | SWT.TITLE | SWT.BORDER); + this.shell.setText(ResourceManager.getLabel(ResourceManager.LOGIN)); + this.shell.setLayout(new GridLayout(4, false)); + } + + /** + * Build the image on top of the login box. If no image has been set, create + * a default image + */ + private void buildImage() { + final Canvas canvas = new Canvas(this.shell, SWT.DOUBLE_BUFFERED); + final GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, false, 4, 1); + gridData.widthHint = 400; + gridData.heightHint = 60; + canvas.setLayoutData(gridData); + canvas.addPaintListener(new PaintListener() { + + @Override + public void paintControl(final PaintEvent e) { + e.gc.drawImage(LoginDialog.this.image == null ? createDefaultImage(e.width, e.height) : LoginDialog.this.image, 0, 0); + } + }); + + } + + /** + * Create a default image. It is a port of the image used by the Login Box + * in the project SwingX + * + * @param w width + * @param h height + * @return a default image (blue wave) + */ + private Image createDefaultImage(final int w, final int h) { + final Display display = Display.getCurrent(); + final Color backgroundColor = new Color(display, 49, 121, 242); + final Color gradientColor1 = new Color(display, 155, 185, 245); + final Color gradientColor2 = new Color(display, 53, 123, 242); + + final Image img = new Image(display, w, h); + final GC gc = new GC(img); + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + gc.setBackground(backgroundColor); + gc.fillRectangle(0, 0, w, h); + + final Path curveShape = new Path(display); + curveShape.moveTo(0, h * .6f); + curveShape.cubicTo(w * .167f, h * 1.2f, w * .667f, h * -.5f, w, h * .75f); + curveShape.lineTo(w, h); + curveShape.lineTo(0, h); + curveShape.lineTo(0, h * .8f); + curveShape.close(); + + final Pattern pattern = new Pattern(display, 0, 0, 1, h * 1.2f, gradientColor1, gradientColor2); + gc.setBackgroundPattern(pattern); + gc.fillPath(curveShape); + + final Font font = new Font(display, "Arial Bold", 30, SWT.NONE); + gc.setFont(font); + gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); + final Point textSize = gc.stringExtent(ResourceManager.getLabel(ResourceManager.LOGIN)); + gc.drawString(ResourceManager.getLabel(ResourceManager.LOGIN), (int) (w * .05f), (h - textSize.y) / 2, true); + + font.dispose(); + curveShape.dispose(); + pattern.dispose(); + backgroundColor.dispose(); + gradientColor1.dispose(); + gradientColor2.dispose(); + gc.dispose(); + return img; + } + + /** + * Build the description part of the box + */ + private void buildDescription() { + final Label label = new Label(this.shell, SWT.NONE); + final GridData gridData = new GridData(GridData.FILL, GridData.BEGINNING, true, false, 4, 1); + gridData.verticalIndent = 5; + gridData.horizontalIndent = 5; + label.setLayoutData(gridData); + final Font bold = SWTGraphicUtil.buildFontFrom(label, SWT.BOLD); + label.setFont(bold); + label.addListener(SWT.Dispose, new Listener() { + + @Override + public void handleEvent(final Event event) { + SWTGraphicUtil.dispose(bold); + } + }); + + if (this.description == null || this.description.trim().equals("")) { + label.setText(" "); + } else { + label.setText(this.description); + } + } + + /** + * Build the login part of the box + */ + private void buildLogin() { + final Label label = new Label(this.shell, SWT.NONE); + final GridData gridData = new GridData(GridData.END, GridData.END, false, false, 1, 1); + gridData.horizontalIndent = 35; + gridData.verticalIndent = 15; + label.setLayoutData(gridData); + label.setText(ResourceManager.getLabel(ResourceManager.NAME)); + + if (this.autorizedLogin != null && !this.autorizedLogin.isEmpty()) { + // Combo + final Combo combo = new Combo(this.shell, SWT.BORDER | SWT.READ_ONLY); + + combo.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1)); + for (final String loginToAdd : this.autorizedLogin) { + combo.add(loginToAdd); + } + combo.setText(this.login == null ? "" : this.login); + combo.setFocus(); + combo.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(final ModifyEvent e) { + LoginDialog.this.login = combo.getText(); + changeButtonOkState(); + } + }); + } else { + // Text + final Text text = new Text(this.shell, SWT.BORDER); + text.setText(this.login == null ? "" : this.login); + text.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1)); + text.setFocus(); + text.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(final ModifyEvent e) { + LoginDialog.this.login = text.getText(); + changeButtonOkState(); + } + }); + } + + } + + /** + * Build the password part of the box + */ + private void buildPassword() { + final Label label = new Label(this.shell, SWT.NONE); + final GridData gridData = new GridData(GridData.END, GridData.CENTER, false, false, 1, 1); + gridData.horizontalIndent = 35; + label.setLayoutData(gridData); + label.setText(ResourceManager.getLabel(ResourceManager.PASSWORD)); + + final Text text = new Text(this.shell, SWT.PASSWORD | SWT.BORDER); + text.setText(this.password == null ? "" : this.password); + text.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); + text.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(final ModifyEvent e) { + LoginDialog.this.password = text.getText(); + changeButtonOkState(); + } + }); + + } + + /** + * Enable/Disable the button when the login and the password is empty (or + * not) + */ + private void changeButtonOkState() { + final boolean loginEntered = this.login != null && !this.login.trim().equals(""); + final boolean passwordEntered = this.password != null && !this.password.trim().equals(""); + this.buttonOk.setEnabled(loginEntered && passwordEntered); + + } + + /** + * Build the "remember password" part of the box + */ + private void buildRememberPassword() { + final Button checkbox = new Button(this.shell, SWT.CHECK); + final GridData gridData = new GridData(GridData.BEGINNING, GridData.CENTER, true, false, 4, 1); + gridData.horizontalIndent = 35; + checkbox.setLayoutData(gridData); + checkbox.setText(ResourceManager.getLabel(ResourceManager.REMEMBER_PASSWORD)); + checkbox.setSelection(this.rememberPassword); + + } + + /** + * Build the buttons + */ + private void buildButtons() { + this.buttonOk = new Button(this.shell, SWT.PUSH); + final GridData gdOk = new GridData(GridData.END, GridData.CENTER, true, false, 3, 1); + gdOk.verticalIndent = 60; + gdOk.minimumWidth = 80; + this.buttonOk.setLayoutData(gdOk); + this.buttonOk.setText(ResourceManager.getLabel(ResourceManager.OK)); + this.buttonOk.setEnabled(false); + + this.buttonOk.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent selectionEvent) { + try { + LoginDialog.this.verifier.authenticate(LoginDialog.this.login, LoginDialog.this.password); + LoginDialog.this.returnedValue = true; + LoginDialog.this.shell.dispose(); + } catch (final Exception e) { + Dialog.error(ResourceManager.getLabel(ResourceManager.LOGIN_FAILED), e.getMessage()); + for (final Control control : LoginDialog.this.shell.getChildren()) { + if (control instanceof Text || control instanceof Combo) { + control.setFocus(); + break; + } + } + + } + } + + }); + + final Button buttonCancel = new Button(this.shell, SWT.PUSH); + final GridData gdCancel = new GridData(GridData.FILL, GridData.CENTER, false, false); + gdCancel.widthHint = 80; + gdCancel.verticalIndent = 60; + buttonCancel.setLayoutData(gdCancel); + buttonCancel.setText(ResourceManager.getLabel(ResourceManager.CANCEL)); + buttonCancel.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + LoginDialog.this.returnedValue = false; + LoginDialog.this.shell.dispose(); + } + + }); + + } + + /** + * Open the shell + */ + private void openShell() { + this.shell.setDefaultButton(this.buttonOk); + this.shell.pack(); + this.shell.open(); + SWTGraphicUtil.centerShell(this.shell); + + while (!this.shell.isDisposed()) { + if (!this.shell.getDisplay().readAndDispatch()) { + this.shell.getDisplay().sleep(); + } + } + } + + // ------------- Getters & Setters + /** + * @return the image + */ + public Image getImage() { + return this.image; + } + + /** + * @return the description + */ + public String getDescription() { + return this.description; + } + + /** + * @return the login + */ + public String getLogin() { + return this.login == null ? null : this.login.trim(); + } + + /** + * @return the password + */ + public String getPassword() { + return this.password == null ? null : this.password.trim(); + } + + /** + * @return the list of autorized logins + */ + public List getAutorizedLogin() { + return this.autorizedLogin; + } + + /** + * @return true if the checkbox "remember the password" is + * displayed, false otherwise + */ + public boolean isDisplayRememberPassword() { + return this.displayRememberPassword; + } + + /** + * @return true if the checkbox "remember the password" is + * checked, false otherwise + */ + public boolean isRememberPassword() { + return this.rememberPassword; + } + + /** + * @return the verifier associated to this box + */ + public LoginDialogVerifier getVerifier() { + return this.verifier; + } + + /** + * @param image the image to set + */ + public void setImage(final Image image) { + this.image = image; + } + + /** + * @param description the description to set + */ + public void setDescription(final String description) { + this.description = description; + } + + /** + * @param login the login to set + */ + public void setLogin(final String login) { + this.login = login; + } + + /** + * @param password the password to set + */ + public void setPassword(final String password) { + this.password = password; + } + + /** + * @param autorizedLogin the list of autorized logins to set + */ + public void setAutorizedLogin(final List autorizedLogin) { + this.autorizedLogin = autorizedLogin; + } + + /** + * @param autorizedLogin the list of autorized logins to set + */ + public void setAutorizedLogin(final String... autorizedLogin) { + this.autorizedLogin = Arrays.asList(autorizedLogin); + } + + /** + * @param displayRememberPassword if true, the checkbox + * "remember the password" is displayed + */ + public void setDisplayRememberPassword(final boolean displayRememberPassword) { + this.displayRememberPassword = displayRememberPassword; + } + + /** + * @param rememberPassword if true, the checkbox + * "remember the password" is selected + */ + public void setRememberPassword(final boolean rememberPassword) { + this.rememberPassword = rememberPassword; + } + + /** + * @param verifier the verifier to set + */ + public void setVerifier(final LoginDialogVerifier verifier) { + this.verifier = verifier; + } + +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialogVerifier.java b/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialogVerifier.java new file mode 100644 index 000000000..14ec22cb8 --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialogVerifier.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.mihalis.opal.login; + +/** + * This interface describes a verifier for the LoginDialogWidget + */ +public interface LoginDialogVerifier { + /** + * Check if the couple login/password is correct + * + * @param login login entered by the user + * @param password password entered by the user + * @throws Exception if the couple login/password is wrong. The description + * of the exception contains the error message that is gonna be + * displayed. For instance, an implementation can throw the + * exception * + * new Exception("Unable to connect to the LDAP Server") + */ + void authenticate(String login, String password) throws Exception; +} diff --git a/org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoice.java b/org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoice.java new file mode 100755 index 000000000..3a5cb0e6b --- /dev/null +++ b/org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoice.java @@ -0,0 +1,1195 @@ +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Laurent CARON (laurent.caron@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.mihalis.opal.multiChoice; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.mihalis.opal.utils.SimpleSelectionAdapter; + +/** + * The MultiChoice class represents a selectable user interface object that + * combines a read-only text-field and a set of checkboxes. + * + *

+ * Note that although this class is a subclass of Composite, it + * does not make sense to add children to it, or set a layout on it. + *

+ *
+ *
Styles: + *
NONE
+ *
Events: + *
Selection
+ *
+ * + * @param Class of objects represented by this widget + */ +public class MultiChoice extends Composite { + + private Label text; + private Button arrow; + private Shell popup; + private Listener listener, filter; + private int numberOfColumns = 2; + private List elements; + private Set selection; + private List