001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ade.galleries.client.preview.ui;
029
030import org.opencms.ade.galleries.client.Messages;
031import org.opencms.ade.galleries.client.preview.CmsImageFormatHandler;
032import org.opencms.gwt.client.ui.CmsPushButton;
033import org.opencms.gwt.client.ui.CmsToggleButton;
034import org.opencms.gwt.client.ui.I_CmsButton;
035import org.opencms.gwt.client.ui.input.CmsLabel;
036import org.opencms.gwt.client.ui.input.CmsSelectBox;
037import org.opencms.gwt.client.ui.input.CmsTextBox;
038
039import com.google.gwt.core.client.GWT;
040import com.google.gwt.core.client.Scheduler;
041import com.google.gwt.core.client.Scheduler.ScheduledCommand;
042import com.google.gwt.event.dom.client.ClickEvent;
043import com.google.gwt.event.dom.client.KeyCodes;
044import com.google.gwt.event.dom.client.KeyPressEvent;
045import com.google.gwt.event.dom.client.KeyPressHandler;
046import com.google.gwt.event.logical.shared.ValueChangeEvent;
047import com.google.gwt.event.logical.shared.ValueChangeHandler;
048import com.google.gwt.uibinder.client.UiBinder;
049import com.google.gwt.uibinder.client.UiField;
050import com.google.gwt.uibinder.client.UiHandler;
051import com.google.gwt.user.client.ui.Composite;
052import com.google.gwt.user.client.ui.HTMLPanel;
053import com.google.gwt.user.client.ui.Widget;
054
055/**
056 * Image format form.<p>
057 *
058 * @since 8.0.0
059 */
060public class CmsImageFormatsForm extends Composite implements ValueChangeHandler<String>, KeyPressHandler {
061
062    /** GWT ui-binder. */
063    protected interface I_CmsImageFormatsFormUiBinder extends UiBinder<Widget, CmsImageFormatsForm> {
064        // nothing to do
065    }
066
067    /** The label width. */
068    private static final int LABEL_WIDTH = 80;
069
070    /** Text metrics key. */
071    private static final String TM_PREVIEW_TAB_IMAGEFORMATS = "ImageFormatsTab";
072
073    /** The ui-binder instance for this class. */
074    private static I_CmsImageFormatsFormUiBinder uiBinder = GWT.create(I_CmsImageFormatsFormUiBinder.class);
075    /** The cropping button. */
076    @UiField
077    protected CmsPushButton m_cropButton;
078
079    /** The height text box. */
080    @UiField
081    protected CmsTextBox m_heightBox;
082
083    /** The height label. */
084    @UiField
085    protected CmsLabel m_heightLabel;
086
087    /** The panel holding the content. */
088    @UiField
089    protected HTMLPanel m_panel;
090
091    /** The ratio lock button. */
092    @UiField
093    protected CmsToggleButton m_ratioLock;
094
095    /** The remove cropping button. */
096    @UiField
097    protected CmsPushButton m_removeCropButton;
098
099    /** The reset size button. */
100    @UiField
101    protected CmsPushButton m_resetSize;
102
103    /** The select box. */
104    @UiField
105    protected CmsSelectBox m_selectBox;
106
107    /** The select box label. */
108    @UiField
109    protected CmsLabel m_selectBoxLabel;
110
111    /** The width text box. */
112    @UiField
113    protected CmsTextBox m_widthBox;
114
115    /** The width label. */
116    @UiField
117    protected CmsLabel m_widthLabel;
118
119    /** The image format handler. */
120    private CmsImageFormatHandler m_formatHandler;
121
122    /** Flag to indicate if the formats form is enabled. */
123    private boolean m_formEnabled;
124
125    /**
126     * Constructor.<p>
127     *
128     * @param formatHandler the image format handler
129     */
130    public CmsImageFormatsForm(CmsImageFormatHandler formatHandler) {
131
132        initWidget(uiBinder.createAndBindUi(this));
133        // form is enabled by default
134        m_formEnabled = true;
135        m_formatHandler = formatHandler;
136        m_selectBoxLabel.setText(Messages.get().key(Messages.GUI_PREVIEW_LABEL_FORMAT_0));
137        m_selectBoxLabel.truncate(TM_PREVIEW_TAB_IMAGEFORMATS, LABEL_WIDTH);
138
139        // set localized values of the labels
140        m_cropButton.setText(Messages.get().key(Messages.GUI_PREVIEW_BUTTON_CROP_0));
141        m_cropButton.setImageClass(I_CmsButton.ICON_FONT + " " + I_CmsButton.CROP);
142
143        m_removeCropButton.setText(Messages.get().key(Messages.GUI_PREVIEW_BUTTON_REMOVECROP_0));
144        m_removeCropButton.setImageClass(I_CmsButton.ICON_FONT + " " + I_CmsButton.CROP_REMOVE);
145
146        m_widthLabel.setText(Messages.get().key(Messages.GUI_PREVIEW_LABEL_WIDTH_0));
147        m_widthLabel.truncate(TM_PREVIEW_TAB_IMAGEFORMATS, LABEL_WIDTH);
148
149        m_heightLabel.setText(Messages.get().key(Messages.GUI_PREVIEW_LABEL_HEIGHT_0));
150        m_heightLabel.truncate(TM_PREVIEW_TAB_IMAGEFORMATS, LABEL_WIDTH);
151
152        m_ratioLock.setImageClass(I_CmsButton.ICON_FONT + " " + I_CmsButton.LOCK_CLOSED);
153        m_ratioLock.setDownImageClass(I_CmsButton.ICON_FONT + " " + I_CmsButton.LOCK_OPEN);
154
155        m_resetSize.setImageClass(I_CmsButton.ICON_FONT + " " + I_CmsButton.RESET);
156        m_selectBox.addValueChangeHandler(this);
157        m_heightBox.addValueChangeHandler(this);
158        m_heightBox.addKeyPressHandler(this);
159        m_widthBox.addValueChangeHandler(this);
160        m_widthBox.addKeyPressHandler(this);
161
162        m_removeCropButton.setVisible(false);
163    }
164
165    /**
166     * Parses <code>String</code> to <code>int</code>. Return -1 for invalid input.<p>
167     *
168     * @param value the value to parse
169     *
170     * @return the int-value
171     */
172    private static native int parseInt(String value) /*-{
173                var ret = parseInt(value);
174                if (isNaN(ret)) {
175                        return -1;
176                }
177                return ret;
178    }-*/;
179
180    /**
181     * Adds a format select option.<p>
182     *
183     * @param value the option value
184     * @param label the option label
185     */
186    public void addFormatSelectOption(String value, String label) {
187
188        m_selectBox.addOption(value, label);
189    }
190
191    /**
192     * Returns the selected format value.<p>
193     *
194     * @return the selected format value
195     */
196    public String getFormatSelectValue() {
197
198        return m_selectBox.getFormValueAsString();
199    }
200
201    /**
202     * Returns the height input or -1 if input is empty or not valid.<p>
203     *
204     * @return the height input
205     */
206    public int getHeightInput() {
207
208        return parseInt(m_heightBox.getFormValueAsString());
209    }
210
211    /**
212     * Returns the width input or -1 if input is empty or not valid.<p>
213     *
214     * @return the width input
215     */
216    public int getWidthInput() {
217
218        return parseInt(m_widthBox.getFormValueAsString());
219    }
220
221    /**
222     * @see com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google.gwt.event.dom.client.KeyPressEvent)
223     */
224    public void onKeyPress(KeyPressEvent event) {
225
226        //preventing any input but numbers
227        char key = event.getCharCode();
228        int code = event.getNativeEvent().getKeyCode();
229        if (((key >= '0') && (key <= '9')) || (code == KeyCodes.KEY_BACKSPACE) || (code == KeyCodes.KEY_DELETE)) {
230            // the value of the input box will probably have changed, so fire an event after the input has been processed
231            final CmsTextBox source = (CmsTextBox)event.getSource();
232            Scheduler.get().scheduleDeferred(new ScheduledCommand() {
233
234                public void execute() {
235
236                    ValueChangeEvent.fire(source, source.getText());
237                }
238            });
239            return;
240        }
241        if ((code == KeyCodes.KEY_TAB)
242            || (code == KeyCodes.KEY_LEFT)
243            || (code == KeyCodes.KEY_RIGHT)
244            || (code == KeyCodes.KEY_ENTER)) {
245            return;
246        }
247        // prevent all others
248        event.stopPropagation();
249        event.preventDefault();
250    }
251
252    /**
253     * @see com.google.gwt.event.logical.shared.ValueChangeHandler#onValueChange(com.google.gwt.event.logical.shared.ValueChangeEvent)
254     */
255    public void onValueChange(ValueChangeEvent<String> event) {
256
257        Object source = event.getSource();
258        if (source == m_selectBox) {
259            m_formatHandler.onFormatChange(event.getValue());
260            return;
261        }
262        if (source == m_heightBox) {
263            m_formatHandler.onHeightChange(event.getValue());
264            return;
265        }
266        if (source == m_widthBox) {
267            m_formatHandler.onWidthChange(event.getValue());
268        }
269    }
270
271    /**
272     * Enables/disables buttons and input fields necessary if the image if cropped.<p>
273     *
274     * @param cropped <code>true</code> if the image is cropped
275     */
276    public void setCropped(boolean cropped) {
277
278        if (cropped) {
279            m_heightBox.setEnabled(false);
280            m_widthBox.setEnabled(false);
281            m_selectBox.setEnabled(false);
282            m_resetSize.disable(Messages.get().key(Messages.GUI_PREVIEW_BUTTON_DIS_CROPPED_0));
283            m_ratioLock.disable(Messages.get().key(Messages.GUI_PREVIEW_BUTTON_DIS_CROPPED_0));
284            m_cropButton.disable(Messages.get().key(Messages.GUI_PREVIEW_BUTTON_DIS_CROPPED_0));
285            if (m_formEnabled) {
286                m_removeCropButton.enable();
287            }
288            m_removeCropButton.setVisible(true);
289            return;
290        }
291        if (m_formEnabled) {
292            m_cropButton.enable();
293            m_heightBox.setEnabled(true);
294            m_widthBox.setEnabled(true);
295            m_selectBox.setEnabled(true);
296            m_resetSize.enable();
297            m_ratioLock.enable();
298        }
299        m_removeCropButton.setVisible(false);
300    }
301
302    /**
303     * Sets the format select value.<p>
304     *
305     * @param value the value
306     */
307    public void setFormatSelectValue(String value) {
308
309        m_selectBox.setFormValueAsString(value);
310    }
311
312    /**
313     * Sets the format form enabled.<p>
314     *
315     * @param enabled if <code>true</code> the form will be enabled
316     */
317    public void setFormEnabled(boolean enabled) {
318
319        m_formEnabled = enabled;
320        m_selectBox.setEnabled(enabled);
321        m_heightBox.setEnabled(enabled);
322        m_widthBox.setEnabled(enabled);
323        if (enabled) {
324            m_cropButton.enable();
325            m_removeCropButton.enable();
326        } else {
327            m_cropButton.disable(Messages.get().key(Messages.GUI_IMAGE_NO_FORMATS_AVAILABLE_0));
328            m_removeCropButton.disable(Messages.get().key(Messages.GUI_IMAGE_NO_FORMATS_AVAILABLE_0));
329        }
330    }
331
332    /**
333     * Sets the height input field.<p>
334     *
335     * @param height the value
336     */
337    public void setHeightInput(int height) {
338
339        m_heightBox.setFormValueAsString(String.valueOf(height));
340    }
341
342    /**
343     * Enables the height input field.<p>
344     *
345     * @param enabled <code>true</code> to enable the input field
346     */
347    public void setHeightInputEnabled(boolean enabled) {
348
349        m_heightBox.setEnabled(enabled);
350    }
351
352    /**
353     * Sets the state of the ratio lock button.<p>
354     *
355     * @param down if <code>true</code> button will be set down / lock open
356     * @param enabled if <code>true</code> button will be enabled
357     * @param disableMessage message to show for disabled button
358     */
359    public void setRatioButton(boolean down, boolean enabled, String disableMessage) {
360
361        m_ratioLock.setDown(down);
362        if (enabled) {
363            m_ratioLock.enable();
364        } else {
365            m_ratioLock.disable(disableMessage);
366        }
367    }
368
369    /**
370     * Sets the width input field.<p>
371     *
372     * @param width the value
373     */
374    public void setWidthInput(int width) {
375
376        m_widthBox.setFormValueAsString(String.valueOf(width));
377    }
378
379    /**
380     * Enables the width input field.<p>
381     *
382     * @param enabled <code>true</code> to enable the input field
383     */
384    public void setWidthInputEnabled(boolean enabled) {
385
386        m_widthBox.setEnabled(enabled);
387    }
388
389    /**
390     * Opens the cropping dialog on crop button click.<p>
391     *
392     * @param event the click event
393     */
394    @UiHandler("m_cropButton")
395    protected void openCropping(ClickEvent event) {
396
397        m_formatHandler.openCropping();
398    }
399
400    /**
401     * Removes the cropping on button click.<p>
402     *
403     * @param event the click event
404     */
405    @UiHandler("m_removeCropButton")
406    protected void removeCropping(ClickEvent event) {
407
408        m_formatHandler.onRemoveCropping();
409    }
410
411    /**
412     * Resets the size on button click.<p>
413     *
414     * @param event the click event
415     */
416    @UiHandler("m_resetSize")
417    protected void resetSize(ClickEvent event) {
418
419        m_formatHandler.onResetSize();
420    }
421
422    /**
423     * Toggle the ratio lock on button click.<p>
424     *
425     * @param event the click event
426     */
427    @UiHandler("m_ratioLock")
428    protected void toggleRatioLock(ClickEvent event) {
429
430        m_formatHandler.onLockRatio(!m_ratioLock.isDown());
431    }
432}