All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.graphenee.vaadin.component.InlineTextEditor Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2016, 2018 Farrukh Ijaz
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package io.graphenee.vaadin.component;

import com.vaadin.data.Property;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Label;
import com.vaadin.ui.RichTextArea;
import com.vaadin.ui.themes.ValoTheme;

@SuppressWarnings("serial")
public class InlineTextEditor extends CustomComponent {

	/*
	 * This Property contains the String type value to be edited. The same
	 * object is passed as content source for the label in read-only mode as
	 * well as the data source for the RichTextArea in edit mode. From there on
	 * synchronization between the two is automatic.
	 */
	private final Property property = new ObjectProperty<>("Enter text here...");
	private final Component editor;
	private final Component readOnly;

	public InlineTextEditor(final String initialValue) {
		setWidth(100.0f, Unit.PERCENTAGE);
		addStyleName("inline-text-editor");

		editor = buildEditor();
		readOnly = buildReadOnly();

		if (initialValue != null) {
			property.setValue(initialValue);
		}

		setCompositionRoot(editor);
	}

	private Component buildReadOnly() {
		final Label text = new Label(property);
		text.setContentMode(ContentMode.HTML);

		Button editButton = new Button(FontAwesome.EDIT);
		editButton.addStyleName(ValoTheme.BUTTON_SMALL);
		editButton.addStyleName(ValoTheme.BUTTON_ICON_ONLY);
		editButton.addClickListener(new ClickListener() {
			@Override
			public void buttonClick(final ClickEvent event) {
				setCompositionRoot(editor);
			}
		});

		CssLayout result = new CssLayout(text, editButton);
		result.addStyleName("text-editor");
		result.setSizeFull();
		result.addLayoutClickListener(new LayoutClickListener() {
			@Override
			public void layoutClick(final LayoutClickEvent event) {
				if (event.getChildComponent() == text && event.isDoubleClick()) {
					setCompositionRoot(editor);
				}
			}
		});
		return result;
	}

	private Component buildEditor() {
		final RichTextArea rta = new RichTextArea(property);
		rta.setWidth(100.0f, Unit.PERCENTAGE);
		rta.addAttachListener(new AttachListener() {
			@Override
			public void attach(final AttachEvent event) {
				rta.focus();
				rta.selectAll();
			}
		});

		Button save = new Button("Save");
		save.setDescription("Edit");
		save.addStyleName(ValoTheme.BUTTON_PRIMARY);
		save.addStyleName(ValoTheme.BUTTON_SMALL);
		save.addClickListener(new ClickListener() {
			@Override
			public void buttonClick(final ClickEvent event) {
				setCompositionRoot(readOnly);
			}
		});

		CssLayout result = new CssLayout(rta, save);
		result.addStyleName("edit");
		result.setSizeFull();
		return result;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy