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

com.codename1.components.FloatingActionButton Maven / Gradle / Ivy

There is a newer version: 7.0.161
Show newest version
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores
 * CA 94065 USA or visit www.oracle.com if you need additional information or
 * have any questions.
 */
package com.codename1.components;

import com.codename1.ui.Button;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import com.codename1.ui.Dialog;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
import com.codename1.ui.animations.CommonTransitions;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.FlowLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.plaf.RoundBorder;
import com.codename1.ui.plaf.Style;
import java.util.ArrayList;
import java.util.List;

/**
 * 

Floating action buttons are a material design element used to promote a special action in a Form. * They are represented as a floating circle with a flat icon floating above the UI typically in the bottom right * area.

* *

* Simple use cases include just the button as a standalone: *

* *

* The button can also nest sub actions *

* * Floating Button * * @author Chen */ public class FloatingActionButton extends Button { /** * The default icon size for the fab icon in millimeters * @return the fabDefaultSize */ public static float getIconDefaultSize() { return fabDefaultSize; } /** * The default icon size for the fab icon in millimeters * @param aFabDefaultSize the fabDefaultSize to set */ public static void setIconDefaultSize(float aFabDefaultSize) { fabDefaultSize = aFabDefaultSize; } /** * The FloatingActionButton tries to size/pad itself automatically but * this means that manual padding is ignored. Setting this to false * disables that behavior * @return the autoSizing */ public static boolean isAutoSizing() { return autoSizing; } /** * The FloatingActionButton tries to size/pad itself automatically but * this means that manual padding is ignored. Setting this to false * disables that behavior * @param aAutoSizing the autoSizing to set */ public static void setAutoSizing(boolean aAutoSizing) { autoSizing = aAutoSizing; } private List subMenu; /** * The UIID of the sub action texts can be overriden. It defaults to {@code FloatingActionText} */ private String floatingActionTextUIID = "FloatingActionText"; private String text; private int shadowOpacity = 100; private Dialog current; private boolean rectangle; private boolean isBadge; /** * The FloatingActionButton tries to size/pad itself automatically but * this means that manual padding is ignored. Setting this to false * disables that behavior */ private static boolean autoSizing = true; /** * The default icon size for the fab */ private static float fabDefaultSize = 3.8f; private float sizeMm = fabDefaultSize; /** * Constructor * * @param icon one of the FontImage.MATERIAL_* constants * @param text the text of the sub FloatingActionButton * @param size the size in millimeters */ protected FloatingActionButton(char icon, String text, float size) { this(icon, text, "FloatingActionButton", size); } /** * Constructor * * @param icon one of the FontImage.MATERIAL_* constants * @param text the text of the sub FloatingActionButton * @param uiid the uiid of the FAB * @param size the size in millimeters */ protected FloatingActionButton(char icon, String text, String uiid, float size) { FontImage image = FontImage.createMaterial(icon, uiid, size); setGap(0); image.setBgTransparency(0); sizeMm = size; setIcon(image); setText(""); this.text = text; setUIID(uiid); Style all = getAllStyles(); all.setAlignment(CENTER); updateBorder(); } /** * Overriden to update the icon * {@inheritDoc} */ @Override public void setUIID(String id) { super.setUIID(id); FontImage i = (FontImage)getIcon(); if(i != null) { Style all = getAllStyles(); all.setAlignment(CENTER); updateBorder(); FontImage image = FontImage.createMaterial(i.getText().charAt(0), id, sizeMm); image.setBgTransparency(0); setIcon(image); } } /** * This constructor is used by text badges */ private FloatingActionButton(String text) { super.setText(text); rectangle = true; shadowOpacity = 0; setUIID("Badge"); updateBorder(); isBadge = true; } private void updateBorder() { getUnselectedStyle().setBorder(RoundBorder.create(). color(getUnselectedStyle().getBgColor()). shadowOpacity(shadowOpacity).rectangle(rectangle)); getSelectedStyle().setBorder(RoundBorder.create(). color(getSelectedStyle().getBgColor()). shadowOpacity(shadowOpacity).rectangle(rectangle)); getPressedStyle().setBorder(RoundBorder.create(). color(getPressedStyle().getBgColor()). shadowOpacity(shadowOpacity).rectangle(rectangle)); } /** * We override this method to track style changes to the background color and map them to the border * * {@inheritDoc} */ @Override public void styleChanged(String propertyName, Style source) { if(propertyName.equals(Style.BG_COLOR)) { updateBorder(); } if(getIcon() instanceof FontImage && propertyName.equals(Style.FG_COLOR)) { FontImage i = (FontImage)getIcon(); FontImage image = FontImage.createMaterial(i.getText().charAt(0), "FloatingActionButton", sizeMm); image.setBgTransparency(0); setIcon(image); } } /** * Creates a text badge * @param text the text of the badge * @return a badge component */ public static FloatingActionButton createBadge(String text) { return new FloatingActionButton(text); } /** * a factory method to create a FloatingActionButton. * * @param icon one of the FontImage.MATERIAL_* constants * @return a FloatingActionButton instance */ public static FloatingActionButton createFAB(char icon) { return new FloatingActionButton(icon, null, fabDefaultSize); } /** * a factory method to create a FloatingActionButton. * * @param icon one of the FontImage.MATERIAL_* constants * @param uiid the uiid for the fab * @return a FloatingActionButton instance */ public static FloatingActionButton createFAB(char icon, String uiid) { return new FloatingActionButton(icon, null, uiid, fabDefaultSize); } /** * Adds a sub FAB to the FloatingActionButton instance. Once pressed all its * sub FAB's are displayed. * * @param icon one of the FontImage.MATERIAL_* constants * @param text the text of the sub FloatingActionButton * * @return a FloatingActionButton instance for the sub FAB added */ public FloatingActionButton createSubFAB(char icon, String text) { FloatingActionButton sub = new FloatingActionButton(icon, text, 2.8f); if (subMenu == null) { subMenu = new ArrayList(); } subMenu.add(sub); return sub; } @Override protected Dimension calcPreferredSize() { if(autoSizing && getIcon() != null) { return new Dimension(getIcon().getWidth() * 11 / 4, getIcon().getHeight() * 11 / 4); } return super.calcPreferredSize(); } /** * This is a utility method to bind the FAB to a given Container, it will return a new container to add or will * use the layered pane if the container is a content pane. * * @param cnt the Container to add the FAB to * @return a new Container that contains the cnt and the FAB on top or null in the case of a content pane */ public Container bindFabToContainer(Component cnt) { return bindFabToContainer(cnt, Component.RIGHT, Component.BOTTOM); } /** * This is a utility method to bind the FAB to a given Container, it will return a new container to add or will * use the layered pane if the container is a content pane. * * @param cnt the Container to add the FAB to * @param orientation one of Component.RIGHT/LEFT/CENTER * @param valign one of Component.TOP/BOTTOM/CENTER * * @return a new Container that contains the cnt and the FAB on top or null in the case of a content pane */ public Container bindFabToContainer(Component cnt, int orientation, int valign) { FlowLayout flow = new FlowLayout(orientation); flow.setValign(valign); Form f = cnt.getComponentForm(); if(f != null && (f.getContentPane() == cnt || f == cnt)) { // special case for content pane installs the button directly on the content pane Container layers = f.getLayeredPane(getClass(), true); layers.setLayout(flow); layers.add(this); return null; } Container conUpper = new Container(flow); conUpper.add(this); return LayeredLayout.encloseIn(cnt, conUpper); } /** * Removes the floating action button from its parent */ public void unbind() { Container cnt = getParent(); remove(); if(cnt != null) { cnt.remove(); } } @Override public void setText(String text) { if(isBadge) { super.setText(text); } this.text = text; } @Override protected void fireActionEvent(int x, int y) { Form current = Display.getInstance().getCurrent(); if(current instanceof Dialog) { ((Dialog)current).dispose(); } super.fireActionEvent(x, y); } @Override public void released(int x, int y) { super.released(x, y); if (current != null) { current.dispose(); current = null; } //if this fab has sub fab's display them if (subMenu != null) { final Container con = createPopupContent(subMenu); Dialog d = new Dialog(); d.setDialogUIID("Container"); d.getContentPane().setUIID("Container"); d.setLayout(new BorderLayout()); d.add(BorderLayout.CENTER, con); for (FloatingActionButton next : subMenu) { next.current = d; } d.setTransitionInAnimator(CommonTransitions.createEmpty()); d.setTransitionOutAnimator(CommonTransitions.createEmpty()); for(Component c : con) { c.setVisible(false); } Form f = getComponentForm(); int oldTint = f.getTintColor(); f.setTintColor(0); d.setBlurBackgroundRadius(-1); d.addShowListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { for(Component c : con) { c.setY(con.getHeight()); c.setVisible(true); } con.animateLayout(200); } }); showPopupDialog(d); f.setTintColor(oldTint); for (FloatingActionButton next : subMenu) { next.remove(); } con.removeAll(); } } /** * Creates the popup content container to display on the dialog. * * @param fabs List of sub FloatingActionButton * @return a Container that contains all fabs */ protected Container createPopupContent(List fabs) { Container con = new Container(new BoxLayout(BoxLayout.Y_AXIS)); for (final FloatingActionButton next : subMenu) { next.setPreferredW(getWidth()); Container c = new Container(new BorderLayout()); Button txt = new Button(next.text); txt.setUIID(floatingActionTextUIID); c.add(BorderLayout.CENTER, FlowLayout.encloseRight(txt)); c.add(BorderLayout.EAST, next); con.add(c); txt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { next.pressed(); next.released(); } }); } return con; } /** * Shows the popup Dialog with the sub FABs. * * @param dialog the Dialog with all sub FAB's Components */ protected void showPopupDialog(Dialog dialog) { dialog.setPopupDirectionBiasPortrait(Boolean.TRUE); dialog.showPopupDialog(this); } /** * @return the floatingActionTextUIID */ public String getFloatingActionTextUIID() { return floatingActionTextUIID; } /** * @param floatingActionTextUIID the floatingActionTextUIID to set */ public void setFloatingActionTextUIID(String floatingActionTextUIID) { this.floatingActionTextUIID = floatingActionTextUIID; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy