├── vaadin-sliderpanel ├── src │ └── main │ │ ├── resources │ │ └── org │ │ │ └── vaadin │ │ │ └── sliderpanel │ │ │ ├── public │ │ │ └── sliderpanel │ │ │ │ └── .gitkeep │ │ │ ├── sliderpanel.scss │ │ │ ├── WidgetSet.gwt.xml │ │ │ └── components │ │ │ └── _sliderpanel.scss │ │ └── java │ │ └── org │ │ └── vaadin │ │ └── sliderpanel │ │ ├── client │ │ ├── SliderPanelServerRpc.java │ │ ├── ToggleListener.java │ │ ├── SliderPanelClientRpc.java │ │ ├── SliderTabPosition.java │ │ ├── SliderMode.java │ │ ├── SliderPanelState.java │ │ ├── SliderPanelConnector.java │ │ └── VSliderPanel.java │ │ ├── SliderPanelStyles.java │ │ ├── SliderPanelBuilder.java │ │ └── SliderPanel.java ├── assembly │ ├── MANIFEST.MF │ └── assembly.xml └── pom.xml ├── assets ├── showcase.gif ├── screenshot-demo.jpg ├── sliderpanel-layouting.png ├── sliderpanel-wrong-sample.png ├── sliderpanel-layouting-variant.png ├── icon.svg ├── sliderpanel-wrong-sample.json ├── sliderpanel-layouting-variant.json └── sliderpanel-layouting.json ├── vaadin-sliderpanel-demo ├── src │ └── main │ │ ├── resources │ │ ├── application.properties │ │ └── org │ │ │ └── vaadin │ │ │ └── sliderpanel │ │ │ └── demo │ │ │ ├── WidgetSet.gwt.xml │ │ │ └── demo.scss │ │ └── java │ │ └── org │ │ └── vaadin │ │ └── sliderpanel │ │ └── demo │ │ ├── Application.java │ │ ├── data │ │ ├── Inhabitants.java │ │ └── DummyDataGen.java │ │ └── DemoUI.java ├── org │ └── vaadin │ │ └── sliderpanel │ │ ├── sliderpanel.scss │ │ └── components │ │ └── _sliderpanel.scss ├── Dockerfile └── pom.xml ├── LICENSE ├── .gitignore ├── pom.xml └── README.md /vaadin-sliderpanel/src/main/resources/org/vaadin/sliderpanel/public/sliderpanel/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/showcase.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melistik/vaadin-sliderpanel/HEAD/assets/showcase.gif -------------------------------------------------------------------------------- /assets/screenshot-demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melistik/vaadin-sliderpanel/HEAD/assets/screenshot-demo.jpg -------------------------------------------------------------------------------- /assets/sliderpanel-layouting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melistik/vaadin-sliderpanel/HEAD/assets/sliderpanel-layouting.png -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | build.version=@project.version@ 2 | build.timestamp=@timestamp@ -------------------------------------------------------------------------------- /assets/sliderpanel-wrong-sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melistik/vaadin-sliderpanel/HEAD/assets/sliderpanel-wrong-sample.png -------------------------------------------------------------------------------- /assets/sliderpanel-layouting-variant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melistik/vaadin-sliderpanel/HEAD/assets/sliderpanel-layouting-variant.png -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/org/vaadin/sliderpanel/sliderpanel.scss: -------------------------------------------------------------------------------- 1 | $tab-long-size-v: 260; 2 | $tab-short-size-v: 40; 3 | $tab-caption-size-v: 210; 4 | 5 | @import "components/sliderpanel"; 6 | 7 | @include sliderpanel; 8 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/resources/org/vaadin/sliderpanel/sliderpanel.scss: -------------------------------------------------------------------------------- 1 | $tab-long-size-v: 260; 2 | $tab-short-size-v: 40; 3 | $tab-caption-size-v: 210; 4 | 5 | @import "components/sliderpanel"; 6 | 7 | @include sliderpanel; 8 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD target/*-SNAPSHOT.jar app.jar 4 | RUN bash -c 'touch /app.jar' 5 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 6 | 7 | EXPOSE 8080 8 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/assembly/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Vaadin-Package-Version: 1 3 | Vaadin-Addon: ${Vaadin-Addon} 4 | Vaadin-License-Title: ${Vaadin-License-Title} 5 | Implementation-Vendor: ${Implementation-Vendor} 6 | Implementation-Title: ${Implementation-Title} 7 | Implementation-Version: ${Implementation-Version} 8 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/src/main/resources/org/vaadin/sliderpanel/demo/WidgetSet.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/SliderPanelServerRpc.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | import com.vaadin.shared.communication.ServerRpc; 4 | 5 | /** 6 | * is been called from GWT connector 7 | * 8 | * @author Marten Prieß (http://www.non-rocket-science.com) 9 | * @version 1.0 10 | */ 11 | public interface SliderPanelServerRpc extends ServerRpc { 12 | 13 | void clicked(boolean visible); 14 | } 15 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/ToggleListener.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | /** 4 | * listener for panel interactions 5 | * 6 | * @author Marten Prieß (http://www.non-rocket-science.com) 7 | * @version 2.0 8 | */ 9 | public interface ToggleListener { 10 | 11 | /** 12 | * get fired on each click on the tab caption 13 | * 14 | * @param expand true means content is visible now 15 | */ 16 | void onToggle(boolean expand); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/src/main/java/org/vaadin/sliderpanel/demo/Application.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.demo; 2 | 3 | import com.vaadin.spring.annotation.EnableVaadin; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @EnableVaadin 9 | public class Application { 10 | 11 | public static void main(String[] args) throws Exception { 12 | SpringApplication.run((Application.class), args); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/SliderPanelClientRpc.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | import com.vaadin.shared.communication.ClientRpc; 4 | 5 | /** 6 | * is been called from ServerComponent 7 | * 8 | * @author Marten Prieß (http://www.non-rocket-science.com) 9 | * @version 1.0 10 | */ 11 | public interface SliderPanelClientRpc extends ClientRpc { 12 | 13 | void setExpand(boolean expand, boolean animated); 14 | 15 | void scheduleExpand(boolean expand, boolean animated, int delayMillis); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/SliderTabPosition.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | /** 4 | * holds different tab positions 5 | * 6 | * @author Marten Prieß (http://www.non-rocket-science.com) 7 | * @version 1.0 8 | */ 9 | public enum SliderTabPosition { 10 | 11 | /** 12 | * Mode: BOTTOM/TOP = LEFT
13 | * Mode: LEFT/RIGHT = TOP 14 | */ 15 | BEGINNING, 16 | /** 17 | * Middle of the slider 18 | */ 19 | MIDDLE, 20 | /** 21 | * Mode: BOTTOM/TOP = RIGHT
22 | * Mode: LEFT/RIGHT = BOTTOM 23 | */ 24 | END; 25 | } 26 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/SliderMode.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | /** 4 | * Presentation mode of the sliders 5 | * 6 | * @author Marten Prieß (http://www.non-rocket-science.com) 7 | * @version 1.0 8 | */ 9 | public enum SliderMode { 10 | 11 | /** 12 | * slides from top to bottom 13 | */ 14 | TOP(false), 15 | /** 16 | * slides from right to left 17 | */ 18 | RIGHT(true), 19 | /** 20 | * slides from bottom to top 21 | */ 22 | BOTTOM(false), 23 | /** 24 | * slides from left to right 25 | */ 26 | LEFT(true); 27 | 28 | private boolean vertical; 29 | 30 | SliderMode(final boolean vertical) { 31 | this.vertical = vertical; 32 | } 33 | 34 | /** 35 | * layout is vertical 36 | * 37 | * @return is vertical 38 | */ 39 | public boolean isVertical() { 40 | return this.vertical; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/SliderPanelState.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | import com.vaadin.shared.ui.AbstractSingleComponentContainerState; 4 | 5 | /** 6 | * Transfer states to GWT connector 7 | * 8 | * @author Marten Prieß (http://www.non-rocket-science.com) 9 | * @version 1.0 10 | */ 11 | public class SliderPanelState extends AbstractSingleComponentContainerState { 12 | 13 | private static final long serialVersionUID = -8569926476346984749L; 14 | 15 | public int tabSize = 40; 16 | public int animationDuration = 500; 17 | public boolean expand = false; 18 | public SliderMode mode = null; 19 | public SliderTabPosition tabPosition = SliderTabPosition.BEGINNING; 20 | 21 | public boolean flowInContent = false; 22 | public int pixel = -1; 23 | public boolean autoCollapseSlider = false; 24 | public int zIndex = 9990; 25 | public boolean enableToggle = true; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Marten Prieß 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/src/main/resources/org/vaadin/sliderpanel/demo/demo.scss: -------------------------------------------------------------------------------- 1 | 2 | $tab-long-size-v: 460; 3 | $tab-short-size-v: 80; 4 | $tab-caption-size-v: 390; 5 | 6 | /* relative to org/vaadin/sliderpanel */ 7 | @import "../components/sliderpanel"; 8 | .my-sliderpanel { 9 | @include sliderpanel; 10 | 11 | .v-sliderpanel-wrapper { 12 | .v-sliderpanel-tab { 13 | .v-sliderpanel-caption { 14 | font-size: 30px; 15 | line-height: $tab-short-size-v - 6px; 16 | } 17 | 18 | .v-sliderpanel-icon { 19 | height: 44px; 20 | width: 44px; 21 | line-height: 44px; 22 | font-size: 32px; 23 | } 24 | } 25 | } 26 | } 27 | 28 | /* demo-styling */ 29 | .v-verticallayout { 30 | &.sp-gray { 31 | background: #808080; 32 | color: #fff; 33 | 34 | h3 { 35 | color: #fff !important; 36 | } 37 | } 38 | &.black-bg { 39 | background: #000; 40 | color: #fff; 41 | 42 | h3 { 43 | color: #fff !important; 44 | } 45 | 46 | .version { 47 | text-align: right; 48 | font-style: italic; 49 | } 50 | } 51 | 52 | &.main > .v-expand > .v-slot:nth-child(1) { 53 | height: 0; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### vaadin 2 | **/VAADIN/widgetsets 3 | *.launch 4 | 5 | ### idea template 6 | .idea/ 7 | *.iml 8 | 9 | ### scss 10 | *.css.map 11 | .sass-cache 12 | **/scss/*.css 13 | sass 14 | *.css 15 | 16 | # Created by .ignore support plugin (hsz.mobi) 17 | ### Eclipse template 18 | *.pydevproject 19 | .metadata 20 | .gradle 21 | bin/ 22 | tmp/ 23 | *.tmp 24 | *.bak 25 | *.swp 26 | *~.nib 27 | local.properties 28 | .settings/ 29 | .loadpath 30 | 31 | # Eclipse Core 32 | .project 33 | 34 | # External tool builders 35 | .externalToolBuilders/ 36 | 37 | # Locally stored "Eclipse launch configurations" 38 | *.launch 39 | 40 | # CDT-specific 41 | .cproject 42 | 43 | # JDT-specific (Eclipse Java Development Tools) 44 | .classpath 45 | 46 | # PDT-specific 47 | .buildpath 48 | 49 | # sbteclipse plugin 50 | .target 51 | 52 | # TeXlipse plugin 53 | .texlipse 54 | 55 | 56 | ### Java template 57 | *.class 58 | target/ 59 | 60 | # Mobile Tools for Java (J2ME) 61 | .mtj.tmp/ 62 | 63 | # Package Files # 64 | *.jar 65 | *.war 66 | *.ear 67 | 68 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 69 | hs_err_pid* 70 | /vaadin-sliderpanel-demo/src/main/resources/org/vaadin/sliderpanel/components/_sliderpanel.scss 71 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/SliderPanelStyles.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel; 2 | 3 | /** 4 | * Holds preconfigured style names that can be used to change color of sliderPanel 5 | * 6 | * @author Marten Prieß (http://www.non-rocket-science.com) 7 | * @version 1.1 8 | */ 9 | public final class SliderPanelStyles { 10 | 11 | /** 12 | * default open/close button color white 13 | */ 14 | public static final String ICON_WHITE = "whiteico"; 15 | /** 16 | * set the icon-color to black of the open/close button 17 | */ 18 | public static final String ICON_BLACK = "blackico"; 19 | 20 | /** 21 | * default style gray background with white text-color 22 | */ 23 | public static final String COLOR_GRAY = "sp-gray"; 24 | /** 25 | * white background with black text and icon 26 | */ 27 | public static final String COLOR_WHITE = "sp-white"; 28 | /** 29 | * valo blue background with white text-color 30 | */ 31 | public static final String COLOR_BLUE = "sp-blue"; 32 | /** 33 | * lite green with white text-color 34 | */ 35 | public static final String COLOR_GREEN = "sp-green"; 36 | /** 37 | * lite red with white text-color 38 | */ 39 | public static final String COLOR_RED = "sp-red"; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/resources/org/vaadin/sliderpanel/WidgetSet.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/assembly/assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | addon 7 | 8 | 10 | 11 | 12 | zip 13 | 14 | 15 | 16 | false 17 | 18 | 19 | 20 | .. 21 | 22 | LICENSE.txt 23 | README.md 24 | 25 | 26 | 27 | target 28 | 29 | 30 | *.jar 31 | *.pdf 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | assembly/MANIFEST.MF 40 | META-INF 41 | true 42 | 43 | 44 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/src/main/java/org/vaadin/sliderpanel/demo/data/Inhabitants.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.demo.data; 2 | 3 | import java.util.Date; 4 | 5 | 6 | public class Inhabitants { 7 | 8 | public enum Gender { 9 | FEMALE, 10 | MALE; 11 | } 12 | 13 | private long id; 14 | private Gender gender; 15 | private String name; 16 | private double bodySize; 17 | private Date birthday; 18 | private boolean onFacebook; 19 | 20 | public Inhabitants() { 21 | 22 | } 23 | 24 | public Inhabitants(final long id, final Gender gender) { 25 | super(); 26 | this.id = id; 27 | this.gender = gender; 28 | } 29 | 30 | public long getId() { 31 | return this.id; 32 | } 33 | 34 | public void setId(final long id) { 35 | this.id = id; 36 | } 37 | 38 | public Gender getGender() { 39 | return this.gender; 40 | } 41 | 42 | public void setGender(final Gender gender) { 43 | this.gender = gender; 44 | } 45 | 46 | public String getName() { 47 | return this.name; 48 | } 49 | 50 | public void setName(final String name) { 51 | this.name = name; 52 | } 53 | 54 | public double getBodySize() { 55 | return this.bodySize; 56 | } 57 | 58 | public void setBodySize(final double bodySize) { 59 | this.bodySize = bodySize; 60 | } 61 | 62 | public Date getBirthday() { 63 | return this.birthday; 64 | } 65 | 66 | public void setBirthday(final Date birthday) { 67 | this.birthday = birthday; 68 | } 69 | 70 | public boolean isOnFacebook() { 71 | return this.onFacebook; 72 | } 73 | 74 | public void setOnFacebook(final boolean onFacebook) { 75 | this.onFacebook = onFacebook; 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return "Inhabitants [id=" + this.id + ", name=" + this.name + "]"; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /assets/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 11 | 12 | 13 | 16 | 17 | 21 | 25 | 26 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/src/main/java/org/vaadin/sliderpanel/demo/data/DummyDataGen.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.demo.data; 2 | 3 | import org.apache.commons.lang.time.DateUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | public final class DummyDataGen { 11 | 12 | public static final List genInhabitants(final int quantity) { 13 | List result = new ArrayList(); 14 | 15 | for (long x = 1; x <= quantity; x++) { 16 | result.add(genInhabitant(x)); 17 | } 18 | 19 | return result; 20 | } 21 | 22 | public static final Inhabitants genInhabitant(final long id) { 23 | Inhabitants inh = new Inhabitants(id, Math.random() > 0.5 ? Inhabitants.Gender.FEMALE : Inhabitants.Gender.MALE); 24 | if (inh.getGender() 25 | .equals(Inhabitants.Gender.MALE)) { 26 | inh.setName(randomOfList(MALES)); 27 | } else { 28 | inh.setName(randomOfList(FEMALES)); 29 | } 30 | inh.setBirthday(new Date(new Date().getTime() - ((long) (Math.random() * 10000) % (365 * 90)) * DateUtils.MILLIS_PER_DAY)); 31 | inh.setBodySize(1.6 + (Math.random() * (Math.random() > 0.5 ? -1 : +1))); 32 | inh.setOnFacebook(Math.random() > 0.5); 33 | return inh; 34 | } 35 | 36 | private final static String randomOfList(final List list) { 37 | return list.get((int) (Math.random() * 10000) % (list.size() - 1)); 38 | } 39 | 40 | public static List FEMALES = Arrays.asList("AMELIA", "OLIVIA", "JESSICA", "EMILY", "LILY", "AVA", "MIA", "ISLA", "SOPHIE", "ISABELLA", "EVIE", 41 | "RUBY", "POPPY", "GRACE", "SOPHIA", "CHLOE", "ISABELLE", "ELLA", "FREYA", "CHARLOTTE", "SCARLETT", "DAISY", "LOLA", "EVA", "HOLLY", "MILLIE", 42 | "LUCY", "PHOEBE", "LAYLA", "MAISIE", "SIENNA", "ALICE", "LILLY", "FLORENCE", "ELLIE", "ERIN", "IMOGEN", "ELIZABETH", "MOLLY", "SUMMER", "MEGAN", 43 | "HANNAH", "SOFIA", "ABIGAIL", "JASMINE", "LEXI", "MATILDA", "ROSIE", "LACEY", "EMMA", "AMELIE", "GRACIE", "MAYA", "HOLLIE", "GEORGIA", "EMILIA", 44 | "EVELYN", "BELLA", "BROOKE", "AMBER", "ELIZA", "AMY", "ELEANOR", "LEAH", "ESME", "KATIE", "HARRIET", "ANNA", "WILLOW", "ELSIE", "ZARA", "ANNABELLE", 45 | "BETHANY", "FAITH", "MADISON", "ISABEL", "MARTHA", "ROSE", "JULIA", "PAIGE", "MARYAM", "MADDISON", "HEIDI", "MOLLIE", "NIAMH", "SKYE", "AISHA", 46 | "IVY", "DARCEY", "FRANCESCA", "ZOE", "KEIRA", "TILLY", "MARIA", "SARAH", "LYDIA", "CAITLIN", "ISOBEL", "SARA", "VIOLET"); 47 | 48 | public static List MALES = Arrays.asList("OLIVER", "JACK", "CHARLIE", "JACOB", "THOMAS", "ALFIE", "RILEY", "WILLIAM", "JAMES", "JOSHUA", "GEORGE", 49 | "ETHAN", "NOAH", "SAMUEL", "DANIEL", "OSCAR", "MAX", "MUHAMMAD", "LEO", "TYLER", "JOSEPH", "ARCHIE", "HENRY", "LUCAS", "MOHAMMED", "ALEXANDER", 50 | "DYLAN", "LOGAN", "ISAAC", "MASON", "BENJAMIN", "JAKE", "FINLEY", "HARRISON", "EDWARD", "JAYDEN", "FREDDIE", "ADAM", "ZACHARY", "SEBASTIAN", "RYAN", 51 | "LEWIS", "THEO", "LUKE", "HARLEY", "MATTHEW", "HARVEY", "TOBY", "LIAM", "CALLUM", "ARTHUR", "MICHAEL", "JENSON", "TOMMY", "NATHAN", "BOBBY", 52 | "CONNOR", "DAVID", "MOHAMMAD", "LUCA", "CHARLES", "KAI", "JAMIE", "ALEX", "BLAKE", "FRANKIE", "REUBEN", "AARON", "DEXTER", "JUDE", "LEON", "OLLIE", 53 | "STANLEY", "ELLIOT", "GABRIEL", "CAMERON", "OWEN", "LOUIE", "AIDEN", "LOUIS", "ELIJAH", "FINLAY", "RHYS", "CALEB", "EVAN", "FREDERICK", "HUGO", 54 | "KIAN", "SONNY", "SETH", "KAYDEN", "TAYLOR", "KYLE", "ELLIOTT", "ROBERT", "THEODORE", "BAILEY", "RORY", "ELLIS"); 55 | } 56 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/SliderPanelConnector.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | import com.vaadin.client.ComponentConnector; 4 | import com.vaadin.client.ConnectorHierarchyChangeEvent; 5 | import com.vaadin.client.communication.RpcProxy; 6 | import com.vaadin.client.communication.StateChangeEvent; 7 | import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; 8 | import com.vaadin.client.ui.SimpleManagedLayout; 9 | import com.vaadin.shared.ui.ComponentStateUtil; 10 | import com.vaadin.shared.ui.Connect; 11 | import org.vaadin.sliderpanel.SliderPanel; 12 | 13 | /** 14 | * connects SliderPanel with GWT VSliderPanel 15 | * 16 | * @author Marten Prieß (http://www.non-rocket-science.com) 17 | * @version 1.0 18 | */ 19 | @Connect(SliderPanel.class) 20 | public class SliderPanelConnector extends AbstractSingleComponentContainerConnector implements SimpleManagedLayout { 21 | 22 | SliderPanelServerRpc rpc = RpcProxy.create(SliderPanelServerRpc.class, this); 23 | 24 | public SliderPanelConnector() { 25 | super(); 26 | 27 | getWidget().setToggleListener(expanded -> SliderPanelConnector.this.rpc.clicked(expanded)); 28 | 29 | registerRpc(SliderPanelClientRpc.class, new SliderPanelClientRpc() { 30 | 31 | @Override 32 | public void setExpand(final boolean expand, final boolean animated) { 33 | getWidget().setExpand(expand, animated); 34 | } 35 | 36 | @Override 37 | public void scheduleExpand(final boolean expand, final boolean animated, final int delayMillis) { 38 | getWidget().scheduleExpand(expand, animated, delayMillis); 39 | } 40 | }); 41 | 42 | } 43 | 44 | @Override 45 | public SliderPanelState getState() { 46 | return (SliderPanelState) super.getState(); 47 | } 48 | 49 | @Override 50 | public VSliderPanel getWidget() { 51 | return (VSliderPanel) super.getWidget(); 52 | } 53 | 54 | @Override 55 | public void updateCaption(final ComponentConnector connector) { 56 | } 57 | 58 | @Override 59 | public void onConnectorHierarchyChange(final ConnectorHierarchyChangeEvent event) { 60 | getWidget().setWidget(getContentWidget()); 61 | } 62 | 63 | @Override 64 | public void onStateChanged(final StateChangeEvent stateChangeEvent) { 65 | super.onStateChanged(stateChangeEvent); 66 | 67 | getWidget().configure(getState().mode, getState().flowInContent, getState().tabPosition, getState().pixel); 68 | 69 | if (stateChangeEvent.hasPropertyChanged("animationDuration")) { 70 | getWidget().setAnimationDuration(getState().animationDuration); 71 | } 72 | if (stateChangeEvent.hasPropertyChanged("caption")) { 73 | getWidget().setCaption(getState().caption, false); 74 | } 75 | if (stateChangeEvent.hasPropertyChanged("pixel")) { 76 | getWidget().setFixedContentSize(getState().pixel); 77 | } 78 | if (stateChangeEvent.hasPropertyChanged("autoCollapseSlider")) { 79 | getWidget().setAutoCollapseSlider(getState().autoCollapseSlider); 80 | } 81 | if (stateChangeEvent.hasPropertyChanged("zIndex")) { 82 | getWidget().setZIndex(getState().zIndex); 83 | } 84 | if (stateChangeEvent.hasPropertyChanged("enabled") || 85 | stateChangeEvent.hasPropertyChanged("enableToggle")) { 86 | getWidget().setEnabled(getState().enabled && getState().enableToggle); 87 | } 88 | 89 | if (ComponentStateUtil.hasStyles(getState())) { 90 | String extraStyles = ""; 91 | for (String style : getState().styles) { 92 | extraStyles += " " + style; 93 | } 94 | getWidget().setStyles(extraStyles); 95 | } 96 | } 97 | 98 | @Override 99 | public boolean delegateCaptionHandling() { 100 | return false; 101 | } 102 | 103 | @Override 104 | public void layout() { 105 | // in case onStateChanged is not fired before 106 | getWidget().configure(getState().mode, getState().flowInContent, getState().tabPosition, getState().pixel); 107 | getWidget().initialize(getState().expand, getState().tabSize); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /assets/sliderpanel-wrong-sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "mockup":{ 3 | "controls":{ 4 | "control":[ 5 | { 6 | "ID":"6", 7 | "h":"600", 8 | "measuredH":"400", 9 | "measuredW":"450", 10 | "properties":{ 11 | "text":"Sliderpanel\nhttp://localhost:8080/vaadin-sliderpanel" 12 | }, 13 | "typeID":"BrowserWindow", 14 | "w":"800", 15 | "x":"138", 16 | "y":"101", 17 | "zOrder":"0" 18 | }, 19 | { 20 | "ID":"7", 21 | "h":"495", 22 | "measuredH":"70", 23 | "measuredW":"100", 24 | "properties":{ 25 | "backgroundAlpha":"0.75", 26 | "borderColor":"5865130", 27 | "borderStyle":"square", 28 | "color":"10470904" 29 | }, 30 | "typeID":"Canvas", 31 | "w":"783", 32 | "x":"146", 33 | "y":"198", 34 | "zOrder":"1" 35 | }, 36 | { 37 | "ID":"8", 38 | "measuredH":"21", 39 | "measuredW":"102", 40 | "properties":{ 41 | "color":"2848996", 42 | "text":"Horizontal Layout" 43 | }, 44 | "typeID":"Label", 45 | "w":"166", 46 | "x":"146", 47 | "y":"177", 48 | "zOrder":"2" 49 | }, 50 | { 51 | "ID":"9", 52 | "h":"451", 53 | "measuredH":"70", 54 | "measuredW":"100", 55 | "properties":{ 56 | "color":"13421772" 57 | }, 58 | "typeID":"Canvas", 59 | "w":"31", 60 | "x":"157", 61 | "y":"221", 62 | "zOrder":"3" 63 | }, 64 | { 65 | "ID":"10", 66 | "h":"451", 67 | "measuredH":"70", 68 | "measuredW":"100", 69 | "properties":{ 70 | "backgroundAlpha":"0.5", 71 | "borderColor":"13421772", 72 | "borderStyle":"roundedDotted", 73 | "color":"16777215" 74 | }, 75 | "typeID":"Canvas", 76 | "w":"727", 77 | "x":"195", 78 | "y":"221", 79 | "zOrder":"4" 80 | }, 81 | { 82 | "ID":"11", 83 | "measuredH":"43", 84 | "measuredW":"267", 85 | "properties":{ 86 | "color":"16777215", 87 | "text":"middle content" 88 | }, 89 | "typeID":"Title", 90 | "w":"435", 91 | "x":"353", 92 | "y":"415", 93 | "zOrder":"5" 94 | }, 95 | { 96 | "ID":"12", 97 | "measuredH":"109", 98 | "measuredW":"21", 99 | "properties":{ 100 | "text":"SliderMode.RIGHT", 101 | "textOrientation":"down" 102 | }, 103 | "typeID":"Label", 104 | "x":"163", 105 | "y":"382", 106 | "zOrder":"6" 107 | }, 108 | { 109 | "ID":"13", 110 | "measuredH":"32", 111 | "measuredW":"32", 112 | "properties":{ 113 | "icon":{ 114 | "ID":"arrow-circle-down", 115 | "name":"Arrow Circle Down", 116 | "size":"medium" 117 | }, 118 | "rotation":"270" 119 | }, 120 | "typeID":"Icon", 121 | "x":"157", 122 | "y":"237", 123 | "zOrder":"7" 124 | }, 125 | { 126 | "ID":"14", 127 | "h":"451", 128 | "measuredH":"70", 129 | "measuredW":"100", 130 | "properties":{ 131 | "color":"13421772" 132 | }, 133 | "typeID":"Canvas", 134 | "w":"119", 135 | "x":"38", 136 | "y":"221", 137 | "zOrder":"8" 138 | }, 139 | { 140 | "ID":"15", 141 | "measuredH":"21", 142 | "measuredW":"82", 143 | "properties":{ 144 | "text":"SliderContent", 145 | "textOrientation":"right" 146 | }, 147 | "typeID":"Label", 148 | "x":"56", 149 | "y":"230", 150 | "zOrder":"9" 151 | } 152 | ] 153 | }, 154 | "measuredH":"701", 155 | "measuredW":"938", 156 | "mockupH":"600", 157 | "mockupW":"900", 158 | "version":"1.0" 159 | } 160 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.vaadin.addons 6 | vaadin-sliderpanel-root 7 | pom 8 | 2.2.2-SNAPSHOT 9 | 10 | 11 | vaadin-sliderpanel 12 | vaadin-sliderpanel-demo 13 | 14 | 15 | 16 | 17 | Marten Prieß 18 | info@non-rocket-science.com 19 | Non-Rocket-Science.com 20 | http://www.non-rocket-science.com 21 | 22 | 23 | 24 | 25 | 26 | The MIT License (MIT) 27 | http://opensource.org/licenses/MIT 28 | 29 | 30 | 31 | 32 | 8.0.0 33 | 1.8 34 | 1.8 35 | UTF-8 36 | false 37 | 38 | 39 | ${project.version} 40 | SliderPanel 41 | Marten Prieß 42 | The MIT License (MIT) 43 | ${project.artifactId}-${project.version}.jar 44 | 45 | 46 | 47 | 48 | org.apache.maven.scm 49 | maven-scm-api 50 | 1.9.5 51 | 52 | 53 | org.apache.maven.scm 54 | maven-scm-provider-gitexe 55 | 1.9.5 56 | 57 | 58 | 59 | 60 | scm:git:git@github.com:melistik/vaadin-sliderpanel.git 61 | scm:git:git@github.com:melistik/vaadin-sliderpanel.git 62 | https://github.com/melistik/vaadin-sliderpanel.git 63 | HEAD 64 | 65 | 66 | 67 | 68 | vaadin-addons 69 | http://maven.vaadin.com/vaadin-addons 70 | 71 | 72 | vaadin-snapshots 73 | http://oss.sonatype.org/content/repositories/vaadin-snapshots/ 74 | 75 | false 76 | 77 | 78 | true 79 | 80 | 81 | 82 | 83 | 84 | 85 | vaadin-snapshots 86 | http://oss.sonatype.org/content/repositories/vaadin-snapshots/ 87 | 88 | false 89 | 90 | 91 | true 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | org.apache.maven.plugins 101 | maven-compiler-plugin 102 | 3.6.1 103 | 104 | ${project.encoding} 105 | ${project.source.version} 106 | ${project.target.version} 107 | 108 | 109 | 110 | 111 | org.apache.maven.plugins 112 | maven-release-plugin 113 | 2.5.3 114 | 115 | 116 | 117 | 118 | org.apache.maven.plugins 119 | maven-javadoc-plugin 120 | 2.10.4 121 | 122 | 123 | attach-javadocs 124 | 125 | jar 126 | 127 | 128 | -Xdoclint:none 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /assets/sliderpanel-layouting-variant.json: -------------------------------------------------------------------------------- 1 | { 2 | "mockup":{ 3 | "controls":{ 4 | "control":[ 5 | { 6 | "ID":"6", 7 | "h":"600", 8 | "measuredH":"400", 9 | "measuredW":"450", 10 | "properties":{ 11 | "text":"Sliderpanel\nhttp://localhost:8080/vaadin-sliderpanel" 12 | }, 13 | "typeID":"BrowserWindow", 14 | "w":"800", 15 | "x":"138", 16 | "y":"101", 17 | "zOrder":"0" 18 | }, 19 | { 20 | "ID":"7", 21 | "h":"495", 22 | "measuredH":"70", 23 | "measuredW":"100", 24 | "properties":{ 25 | "backgroundAlpha":"0.75", 26 | "borderColor":"5865130", 27 | "borderStyle":"square", 28 | "color":"10470904" 29 | }, 30 | "typeID":"Canvas", 31 | "w":"783", 32 | "x":"146", 33 | "y":"198", 34 | "zOrder":"1" 35 | }, 36 | { 37 | "ID":"8", 38 | "measuredH":"21", 39 | "measuredW":"102", 40 | "properties":{ 41 | "color":"2848996", 42 | "text":"Horizontal Layout" 43 | }, 44 | "typeID":"Label", 45 | "w":"166", 46 | "x":"146", 47 | "y":"177", 48 | "zOrder":"2" 49 | }, 50 | { 51 | "ID":"9", 52 | "h":"451", 53 | "measuredH":"70", 54 | "measuredW":"100", 55 | "properties":{ 56 | "color":"13421772" 57 | }, 58 | "typeID":"Canvas", 59 | "w":"31", 60 | "x":"325", 61 | "y":"220", 62 | "zOrder":"3" 63 | }, 64 | { 65 | "ID":"10", 66 | "h":"451", 67 | "measuredH":"70", 68 | "measuredW":"100", 69 | "properties":{ 70 | "backgroundAlpha":"0.5", 71 | "borderColor":"13421772", 72 | "borderStyle":"roundedDotted", 73 | "color":"16777215" 74 | }, 75 | "typeID":"Canvas", 76 | "w":"565", 77 | "x":"357", 78 | "y":"221", 79 | "zOrder":"4" 80 | }, 81 | { 82 | "ID":"11", 83 | "measuredH":"43", 84 | "measuredW":"267", 85 | "properties":{ 86 | "color":"16777215", 87 | "text":"middle content" 88 | }, 89 | "typeID":"Title", 90 | "w":"435", 91 | "x":"422", 92 | "y":"415", 93 | "zOrder":"5" 94 | }, 95 | { 96 | "ID":"16", 97 | "measuredH":"101", 98 | "measuredW":"21", 99 | "properties":{ 100 | "text":"SliderMode.LEFT", 101 | "textOrientation":"up" 102 | }, 103 | "typeID":"Label", 104 | "x":"332", 105 | "y":"385", 106 | "zOrder":"6" 107 | }, 108 | { 109 | "ID":"17", 110 | "measuredH":"32", 111 | "measuredW":"32", 112 | "properties":{ 113 | "icon":{ 114 | "ID":"arrow-circle-down", 115 | "name":"Arrow Circle Down", 116 | "size":"medium" 117 | }, 118 | "rotation":"90" 119 | }, 120 | "typeID":"Icon", 121 | "x":"325", 122 | "y":"611", 123 | "zOrder":"7" 124 | }, 125 | { 126 | "ID":"18", 127 | "h":"453", 128 | "measuredH":"70", 129 | "measuredW":"100", 130 | "properties":{ 131 | "color":"13421772" 132 | }, 133 | "typeID":"Canvas", 134 | "w":"162", 135 | "x":"154", 136 | "y":"218", 137 | "zOrder":"8" 138 | }, 139 | { 140 | "ID":"19", 141 | "measuredH":"21", 142 | "measuredW":"130", 143 | "properties":{ 144 | "text":"Main fixed Filter Panel", 145 | "textOrientation":"right" 146 | }, 147 | "typeID":"Label", 148 | "x":"161", 149 | "y":"230", 150 | "zOrder":"9" 151 | }, 152 | { 153 | "ID":"20", 154 | "measuredH":"23", 155 | "measuredW":"79", 156 | "typeID":"TextInput", 157 | "x":"228", 158 | "y":"259", 159 | "zOrder":"10" 160 | }, 161 | { 162 | "ID":"21", 163 | "measuredH":"21", 164 | "measuredW":"40", 165 | "properties":{ 166 | "text":"search" 167 | }, 168 | "typeID":"Label", 169 | "x":"161", 170 | "y":"260", 171 | "zOrder":"11" 172 | }, 173 | { 174 | "ID":"22", 175 | "measuredH":"24", 176 | "measuredW":"60", 177 | "typeID":"Button", 178 | "x":"247", 179 | "y":"635", 180 | "zOrder":"12" 181 | } 182 | ] 183 | }, 184 | "measuredH":"701", 185 | "measuredW":"938", 186 | "mockupH":"600", 187 | "mockupW":"800", 188 | "version":"1.0" 189 | } 190 | } -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/SliderPanelBuilder.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel; 2 | 3 | import com.vaadin.ui.Component; 4 | import org.vaadin.sliderpanel.client.SliderMode; 5 | import org.vaadin.sliderpanel.client.SliderTabPosition; 6 | import org.vaadin.sliderpanel.client.VSliderPanel; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Vaadin SliderPanelBuilder 13 | * 14 | * @author Marten Prieß (http://www.non-rocket-science.com) 15 | * @version 1.2 16 | */ 17 | public class SliderPanelBuilder { 18 | 19 | protected Component content; 20 | 21 | protected SliderMode mode = SliderMode.TOP; 22 | 23 | protected boolean expanded = false; 24 | 25 | protected boolean flowInContent = false; 26 | 27 | protected int tabSize = 40; 28 | 29 | protected List listeners = null; 30 | 31 | protected String caption = null; 32 | 33 | protected SliderTabPosition tabPosition = SliderTabPosition.BEGINNING; 34 | 35 | protected int animationDuration = 500; 36 | 37 | protected List styles = null; 38 | 39 | protected int pixel = -1; 40 | 41 | protected boolean autoCollapseSlider = false; 42 | 43 | protected int zIndex = 9990; 44 | 45 | 46 | /** 47 | * creates an builder instance that can be configured fluently 48 | * 49 | * @param content that is wrapped by the SliderPanel
50 | * typically it's a Vertical or HorizontalLayout 51 | */ 52 | public SliderPanelBuilder(final Component content) { 53 | this.content = content; 54 | } 55 | 56 | /** 57 | * creates an builder instance that can be configured fluently 58 | * 59 | * @param content that is wrapped by the SliderPanel
60 | * typically it's a Vertical or HorizontalLayout 61 | * @param caption of the slider navigation element 62 | */ 63 | public SliderPanelBuilder(final Component content, final String caption) { 64 | this.content = content; 65 | this.caption = caption; 66 | } 67 | 68 | /** 69 | * Which type of display you want to have 70 | * 71 | * @param mode default TOP 72 | * @return builder 73 | */ 74 | public SliderPanelBuilder mode(final SliderMode mode) { 75 | this.mode = mode; 76 | return this; 77 | } 78 | 79 | /** 80 | * Should the slider be expanded on intial paint
81 | * 82 | * @param expanded default false 83 | * @return builder 84 | */ 85 | public SliderPanelBuilder expanded(final boolean expanded) { 86 | this.expanded = expanded; 87 | return this; 88 | } 89 | 90 | /** 91 | * Should the navigator flow within the content of the other layouts below 92 | * 93 | * @param flowInContent default false 94 | * @return builder 95 | */ 96 | public SliderPanelBuilder flowInContent(final boolean flowInContent) { 97 | this.flowInContent = flowInContent; 98 | return this; 99 | } 100 | 101 | /** 102 | * allows to change the short width/height of the tab-caption
103 | * you need to change also your css when you change from default value
104 | * important need to get setted before first attach! 105 | * 106 | * @param tabSize default 40 107 | * @return builder 108 | */ 109 | public SliderPanelBuilder tabSize(final int tabSize) { 110 | this.tabSize = tabSize; 111 | return this; 112 | } 113 | 114 | /** 115 | * add the listener to the list of Listeners 116 | * 117 | * @param listener instance of {@link SliderPanel.SliderPanelToggleListener} 118 | * @return builder 119 | */ 120 | public SliderPanelBuilder listener(final SliderPanel.SliderPanelToggleListener listener) { 121 | if (this.listeners == null) { 122 | this.listeners = new ArrayList<>(); 123 | } 124 | this.listeners.add(listener); 125 | return this; 126 | } 127 | 128 | /** 129 | * set caption 130 | * 131 | * @param caption of the slider navigation element 132 | * @return builder 133 | */ 134 | public SliderPanelBuilder caption(final String caption) { 135 | this.caption = caption; 136 | return this; 137 | } 138 | 139 | /** 140 | * Which type of display you want to have
141 | * This controls the position of the navigation element within the {@link SliderPanel} total area 142 | * 143 | * @param tabPosition default BEGINNING 144 | * @return builder 145 | */ 146 | public SliderPanelBuilder tabPosition(final SliderTabPosition tabPosition) { 147 | this.tabPosition = tabPosition; 148 | return this; 149 | } 150 | 151 | /** 152 | * How long a collapse/expand should take in milliseconds 153 | * 154 | * @param animationDuration defaul 500 155 | * @return builder 156 | */ 157 | public SliderPanelBuilder animationDuration(final int animationDuration) { 158 | this.animationDuration = animationDuration; 159 | return this; 160 | } 161 | 162 | /** 163 | * add a style to the sliderPanel 164 | * 165 | * @param style style that should get add to each nodes of {@link VSliderPanel}
166 | * could get called multiple times 167 | * @return builder 168 | */ 169 | public SliderPanelBuilder style(final String... style) { 170 | if (this.styles == null) { 171 | this.styles = new ArrayList(); 172 | } 173 | if (style != null) { 174 | for (String s : style) { 175 | this.styles.add(s); 176 | } 177 | } 178 | return this; 179 | } 180 | 181 | /** 182 | * by default the {@link SliderPanel} calculates it's content width/height (depending on it's mode)
183 | * in some cases it's useful to programmatically set this value 184 | * 185 | * @param pixel width/height (depending on it's mode) 186 | * @return builder 187 | */ 188 | public SliderPanelBuilder fixedContentSize(final int pixel) { 189 | this.pixel = pixel; 190 | return this; 191 | } 192 | 193 | /** 194 | * by default the {@link SliderPanel} stays open when use clicks outside
195 | * when you enable autoCollapse the slider closes in mode of expand when user clicks somewhere else 196 | * 197 | * @param autoCollapseSlider enable auto collapse in expand state 198 | * @return builder 199 | */ 200 | public SliderPanelBuilder autoCollapseSlider(final boolean autoCollapseSlider) { 201 | this.autoCollapseSlider = autoCollapseSlider; 202 | return this; 203 | } 204 | 205 | /** 206 | * z-Index of navigator, content and wrapper
207 | * you can specify for multiple sliders which lays above another 208 | * 209 | * @param zIndex default 9990 210 | * @return 211 | */ 212 | public SliderPanelBuilder zIndex(int zIndex) { 213 | this.zIndex = zIndex; 214 | return this; 215 | } 216 | 217 | /** 218 | * generates the SliderPanel 219 | * 220 | * @return instance of configured {@link SliderPanel} 221 | */ 222 | public SliderPanel build() { 223 | return new SliderPanel(this); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/org/vaadin/sliderpanel/components/_sliderpanel.scss: -------------------------------------------------------------------------------- 1 | 2 | @mixin blackico { 3 | &.open { 4 | .v-sliderpanel-icon:before { 5 | content: "\f056"; 6 | color: black; 7 | } 8 | } 9 | 10 | &.closed { 11 | .v-sliderpanel-icon:before { 12 | content: "\f055"; 13 | color: black; 14 | } 15 | } 16 | } 17 | 18 | @mixin sliderpanel { 19 | /* --------- wrapper --------- */ 20 | .v-sliderpanel-wrapper { 21 | margin-left: auto; 22 | margin-right: auto; 23 | 24 | &.layout-horizontal { 25 | /* --------- horizontal handling --------- */ 26 | width: 100%; 27 | height: 0; 28 | position: relative; 29 | 30 | .v-sliderpanel-content { 31 | /* ------- content ------- */ 32 | width: 100%; 33 | } 34 | .v-sliderpanel-tab { 35 | /* ------- tab ------- */ 36 | border-radius: 0 0 10px 10px; 37 | height: $tab-short-size-v * 1px; 38 | width: $tab-long-size-v * 1px; 39 | 40 | &.tab-beginning { 41 | left: 4%; 42 | } 43 | &.tab-middle { 44 | left: 50%; 45 | margin-left: $tab-long-size-v * -0.5px; 46 | } 47 | &.tab-end { 48 | left: 96%; 49 | margin-left: $tab-long-size-v * -1px; 50 | } 51 | } 52 | .v-sliderpanel-navigator { 53 | height: $tab-short-size-v * 1px; 54 | width: 100%; 55 | } 56 | &.mode-bottom { 57 | .v-sliderpanel-tab { 58 | border-radius: 10px 10px 0 0; 59 | } 60 | .v-sliderpanel-navigator { 61 | position: absolute; 62 | } 63 | } 64 | } 65 | &.layout-vertical { 66 | /* --------- vertical handling --------- */ 67 | height: 100%; 68 | width: 0; 69 | position: relative; 70 | 71 | .v-sliderpanel-content { 72 | /* ------- content ------- */ 73 | height: 100%; 74 | } 75 | .v-sliderpanel-tab { 76 | /* ------- tab ------- */ 77 | border-radius: 0 0 10px 10px; 78 | height: $tab-short-size-v * 1px; 79 | width: $tab-long-size-v * 1px; 80 | position: absolute; 81 | 82 | &.tab-beginning { 83 | top: 4%; 84 | } 85 | &.tab-middle { 86 | top: 50%; 87 | margin-top: $tab-short-size-v * -0.5px; 88 | } 89 | &.tab-end { 90 | bottom: 4%; 91 | } 92 | } 93 | .v-sliderpanel-navigator { 94 | /* ------- navigation ------- */ 95 | position: absolute; 96 | height: 100%; 97 | width: $tab-short-size-v * 1px; 98 | } 99 | &.mode-right { 100 | margin-left: 0; 101 | .v-sliderpanel-tab { 102 | border-radius: 0 0 10px 10px; 103 | -moz-transform: rotate(90.0deg); 104 | -o-transform: rotate(90.0deg); 105 | -webkit-transform: rotate(90.0deg); 106 | transform: rotate(90.0deg); 107 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 108 | left: $tab-long-size-v * -0.5px + $tab-short-size-v * 0.5px; 109 | } 110 | .v-sliderpanel-navigator { 111 | left: 0; 112 | } 113 | .v-sliderpanel-content { 114 | float: right; 115 | left: $tab-short-size-v * 1px; 116 | } 117 | } 118 | &.mode-left { 119 | margin-right: 0; 120 | .v-sliderpanel-tab { 121 | -moz-transform: rotate(270.0deg); 122 | -o-transform: rotate(270.0deg); 123 | -webkit-transform: rotate(270.0deg); 124 | transform: rotate(270.0deg); 125 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); 126 | margin-top: $tab-long-size-v * 0.5px; 127 | margin-left: $tab-long-size-v * -0.5px + $tab-short-size-v * 0.5px; 128 | } 129 | .v-sliderpanel-content { 130 | left: $tab-short-size-v * -1px; 131 | } 132 | .v-sliderpanel-navigator { 133 | right: 0; 134 | } 135 | &.flow-in-content { 136 | .v-sliderpanel-content { 137 | // new slider doesn't need this 138 | left: 0; 139 | } 140 | } 141 | } 142 | } 143 | } 144 | 145 | /* --------- content --------- */ 146 | .v-sliderpanel-content { 147 | overflow: hidden; 148 | position: absolute; 149 | background: #808080; 150 | color: #fff; 151 | 152 | h1, .v-label-h1, h2, .v-label-h2, h3, .v-label-h3 { 153 | color: #fff; 154 | } 155 | .v-grid, .v-table { 156 | color: black; 157 | } 158 | } 159 | 160 | /* --------- navigator --------- */ 161 | .v-sliderpanel-navigator { 162 | position: relative; 163 | top: 0; 164 | pointer-events: none; 165 | } 166 | 167 | /* --------- tab action caption --------- */ 168 | .v-sliderpanel-tab { 169 | position: relative; 170 | line-height: 35px; 171 | color: #fff; 172 | font-size: 0.8em; 173 | cursor: pointer; 174 | background: #808080; 175 | pointer-events: all; 176 | 177 | &.open { 178 | .v-sliderpanel-icon:before { 179 | content: "\f056"; 180 | color: white; 181 | } 182 | } 183 | 184 | &.closed { 185 | .v-sliderpanel-icon:before { 186 | content: "\f055"; 187 | color: white; 188 | } 189 | } 190 | 191 | .v-sliderpanel-caption { 192 | padding: 3px 0 0 15px; 193 | width: $tab-caption-size-v * 1px; 194 | overflow: hidden; 195 | word-break: break-all; 196 | height: $tab-short-size-v - 6px; 197 | } 198 | } 199 | 200 | /* --------- icon --------- */ 201 | .v-sliderpanel-icon { 202 | height: 22px; 203 | width: 22px; 204 | position: absolute; 205 | top: 10px; 206 | right: 10px; 207 | 208 | font-family: FontAwesome; 209 | font-style: normal; 210 | font-weight: normal; 211 | -webkit-font-smoothing: antialiased; 212 | -moz-osx-font-smoothing: grayscale; 213 | display: inline-block; 214 | line-height: 22px; 215 | font-size: 16px; 216 | text-align: center; 217 | } 218 | 219 | /* --------- disabled --------- */ 220 | .v-disabled { 221 | .v-sliderpanel-icon, .v-sliderpanel-caption, .v-sliderpanel-tab { 222 | cursor: default; 223 | } 224 | .v-sliderpanel-caption { 225 | opacity: 0.5; 226 | } 227 | } 228 | 229 | /* --------- different colors --------- */ 230 | 231 | 232 | .v-sliderpanel-tab.blackico { 233 | @include blackico; 234 | } 235 | 236 | .sp-white { 237 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 238 | background: #fafafa; 239 | color: #000; 240 | h1, .v-label-h1, h2, .v-label-h2, h3, .v-label-h3 { 241 | color: #000; 242 | } 243 | } 244 | &.v-sliderpanel-tab { 245 | @include blackico; 246 | } 247 | 248 | .v-sliderpanel-content { 249 | -moz-box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2); 250 | -webkit-box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2); 251 | box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2); 252 | } 253 | 254 | &.layout-vertical { 255 | .v-sliderpanel-tab { 256 | -moz-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 257 | -webkit-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 258 | box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 259 | } 260 | } 261 | &.mode-top { 262 | .v-sliderpanel-tab { 263 | -moz-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 264 | -webkit-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 265 | box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 266 | } 267 | } 268 | &.mode-bottom { 269 | .v-sliderpanel-tab { 270 | -moz-box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.2); 271 | -webkit-box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.2); 272 | box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.2); 273 | } 274 | } 275 | } 276 | 277 | .sp-blue { 278 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 279 | background: #197de1; 280 | color: #fff; 281 | } 282 | } 283 | 284 | .sp-green { 285 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 286 | background: #3dbc1a; 287 | color: #fff; 288 | } 289 | } 290 | 291 | .sp-red { 292 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 293 | background: #ed473b; 294 | color: #fff; 295 | } 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/resources/org/vaadin/sliderpanel/components/_sliderpanel.scss: -------------------------------------------------------------------------------- 1 | 2 | @mixin blackico { 3 | &.open { 4 | .v-sliderpanel-icon:before { 5 | content: "\f056"; 6 | color: black; 7 | } 8 | } 9 | 10 | &.closed { 11 | .v-sliderpanel-icon:before { 12 | content: "\f055"; 13 | color: black; 14 | } 15 | } 16 | } 17 | 18 | @mixin sliderpanel { 19 | /* --------- wrapper --------- */ 20 | .v-sliderpanel-wrapper { 21 | margin-left: auto; 22 | margin-right: auto; 23 | 24 | &.layout-horizontal { 25 | /* --------- horizontal handling --------- */ 26 | width: 100%; 27 | height: 0; 28 | position: relative; 29 | 30 | .v-sliderpanel-content { 31 | /* ------- content ------- */ 32 | width: 100%; 33 | } 34 | .v-sliderpanel-tab { 35 | /* ------- tab ------- */ 36 | border-radius: 0 0 10px 10px; 37 | height: $tab-short-size-v * 1px; 38 | width: $tab-long-size-v * 1px; 39 | 40 | &.tab-beginning { 41 | left: 4%; 42 | } 43 | &.tab-middle { 44 | left: 50%; 45 | margin-left: $tab-long-size-v * -0.5px; 46 | } 47 | &.tab-end { 48 | left: 96%; 49 | margin-left: $tab-long-size-v * -1px; 50 | } 51 | } 52 | .v-sliderpanel-navigator { 53 | height: $tab-short-size-v * 1px; 54 | width: 100%; 55 | } 56 | &.mode-bottom { 57 | .v-sliderpanel-tab { 58 | border-radius: 10px 10px 0 0; 59 | } 60 | .v-sliderpanel-navigator { 61 | position: absolute; 62 | } 63 | } 64 | } 65 | &.layout-vertical { 66 | /* --------- vertical handling --------- */ 67 | height: 100%; 68 | width: 0; 69 | position: relative; 70 | 71 | .v-sliderpanel-content { 72 | /* ------- content ------- */ 73 | height: 100%; 74 | } 75 | .v-sliderpanel-tab { 76 | /* ------- tab ------- */ 77 | border-radius: 0 0 10px 10px; 78 | height: $tab-short-size-v * 1px; 79 | width: $tab-long-size-v * 1px; 80 | position: absolute; 81 | 82 | &.tab-beginning { 83 | top: 4%; 84 | } 85 | &.tab-middle { 86 | top: 50%; 87 | margin-top: $tab-short-size-v * -0.5px; 88 | } 89 | &.tab-end { 90 | bottom: 4%; 91 | } 92 | } 93 | .v-sliderpanel-navigator { 94 | /* ------- navigation ------- */ 95 | position: absolute; 96 | height: 100%; 97 | width: $tab-short-size-v * 1px; 98 | } 99 | &.mode-right { 100 | margin-left: 0; 101 | .v-sliderpanel-tab { 102 | border-radius: 0 0 10px 10px; 103 | -moz-transform: rotate(90.0deg); 104 | -o-transform: rotate(90.0deg); 105 | -webkit-transform: rotate(90.0deg); 106 | transform: rotate(90.0deg); 107 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 108 | left: $tab-long-size-v * -0.5px + $tab-short-size-v * 0.5px; 109 | } 110 | .v-sliderpanel-navigator { 111 | left: 0; 112 | } 113 | .v-sliderpanel-content { 114 | float: right; 115 | left: $tab-short-size-v * 1px; 116 | } 117 | } 118 | &.mode-left { 119 | margin-right: 0; 120 | .v-sliderpanel-tab { 121 | -moz-transform: rotate(270.0deg); 122 | -o-transform: rotate(270.0deg); 123 | -webkit-transform: rotate(270.0deg); 124 | transform: rotate(270.0deg); 125 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); 126 | margin-top: $tab-long-size-v * 0.5px; 127 | margin-left: $tab-long-size-v * -0.5px + $tab-short-size-v * 0.5px; 128 | } 129 | .v-sliderpanel-content { 130 | left: $tab-short-size-v * -1px; 131 | } 132 | .v-sliderpanel-navigator { 133 | right: 0; 134 | } 135 | &.flow-in-content { 136 | .v-sliderpanel-content { 137 | // new slider doesn't need this 138 | left: 0; 139 | } 140 | } 141 | } 142 | } 143 | } 144 | 145 | /* --------- content --------- */ 146 | .v-sliderpanel-content { 147 | overflow: hidden; 148 | position: absolute; 149 | background: #808080; 150 | color: #fff; 151 | 152 | h1, .v-label-h1, h2, .v-label-h2, h3, .v-label-h3 { 153 | color: #fff; 154 | } 155 | .v-grid, .v-table { 156 | color: black; 157 | } 158 | } 159 | 160 | /* --------- navigator --------- */ 161 | .v-sliderpanel-navigator { 162 | position: relative; 163 | top: 0; 164 | pointer-events: none; 165 | } 166 | 167 | /* --------- tab action caption --------- */ 168 | .v-sliderpanel-tab { 169 | position: relative; 170 | line-height: 35px; 171 | color: #fff; 172 | font-size: 0.8em; 173 | cursor: pointer; 174 | background: #808080; 175 | pointer-events: all; 176 | 177 | &.open { 178 | .v-sliderpanel-icon:before { 179 | content: "\f056"; 180 | color: white; 181 | } 182 | } 183 | 184 | &.closed { 185 | .v-sliderpanel-icon:before { 186 | content: "\f055"; 187 | color: white; 188 | } 189 | } 190 | 191 | .v-sliderpanel-caption { 192 | padding: 3px 0 0 15px; 193 | width: $tab-caption-size-v * 1px; 194 | overflow: hidden; 195 | word-break: break-all; 196 | height: $tab-short-size-v - 6px; 197 | } 198 | } 199 | 200 | /* --------- icon --------- */ 201 | .v-sliderpanel-icon { 202 | height: 22px; 203 | width: 22px; 204 | position: absolute; 205 | top: 10px; 206 | right: 10px; 207 | 208 | font-family: FontAwesome; 209 | font-style: normal; 210 | font-weight: normal; 211 | -webkit-font-smoothing: antialiased; 212 | -moz-osx-font-smoothing: grayscale; 213 | display: inline-block; 214 | line-height: 22px; 215 | font-size: 16px; 216 | text-align: center; 217 | } 218 | 219 | /* --------- disabled --------- */ 220 | .v-disabled { 221 | .v-sliderpanel-icon, .v-sliderpanel-caption, .v-sliderpanel-tab { 222 | cursor: default; 223 | } 224 | .v-sliderpanel-caption { 225 | opacity: 0.5; 226 | } 227 | } 228 | 229 | /* --------- different colors --------- */ 230 | 231 | 232 | .v-sliderpanel-tab.blackico { 233 | @include blackico; 234 | } 235 | 236 | .sp-white { 237 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 238 | background: #fafafa; 239 | color: #000; 240 | h1, .v-label-h1, h2, .v-label-h2, h3, .v-label-h3 { 241 | color: #000; 242 | } 243 | } 244 | &.v-sliderpanel-tab { 245 | @include blackico; 246 | } 247 | 248 | .v-sliderpanel-content { 249 | -moz-box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2); 250 | -webkit-box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2); 251 | box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2); 252 | } 253 | 254 | &.layout-vertical { 255 | .v-sliderpanel-tab { 256 | -moz-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 257 | -webkit-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 258 | box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 259 | } 260 | } 261 | &.mode-top { 262 | .v-sliderpanel-tab { 263 | -moz-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 264 | -webkit-box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 265 | box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2); 266 | } 267 | } 268 | &.mode-bottom { 269 | .v-sliderpanel-tab { 270 | -moz-box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.2); 271 | -webkit-box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.2); 272 | box-shadow: 0px -1px 1px 0px rgba(0, 0, 0, 0.2); 273 | } 274 | } 275 | } 276 | 277 | .sp-blue { 278 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 279 | background: #197de1; 280 | color: #fff; 281 | } 282 | } 283 | 284 | .sp-green { 285 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 286 | background: #3dbc1a; 287 | color: #fff; 288 | } 289 | } 290 | 291 | .sp-red { 292 | &.v-sliderpanel-content, &.v-sliderpanel-tab { 293 | background: #ed473b; 294 | color: #fff; 295 | } 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Vaadin Directory status](http://img.shields.io/vaadin-directory/status/sliderpanel.svg)](https://vaadin.com/directory/component/sliderpanel) 2 | [![Vaadin Directory version](http://img.shields.io/vaadin-directory/version/sliderpanel.svg)](https://vaadin.com/directory/component/sliderpanel) 3 | [![Vaadin Directory star](http://img.shields.io/vaadin-directory/star/sliderpanel.svg)](https://vaadin.com/directory/component/sliderpanel) 4 | 5 | Vaadin SliderPanel 6 | ============== 7 | 8 | Panel that is able to get collapsed and expand. The expand mode lays over the content... 9 | 10 | ![showcase](assets/showcase.gif) 11 | 12 | Main Features 13 | ======== 14 | 15 | * pur css design 16 | * nice collapse/expand animation 17 | * Listener for collapsed/expanded 18 | * schedule future collapse/expand on client side 19 | * customizable: 20 | * 4 different display modes 21 | * 3 different tab position 22 | * easy to change color and style by css 23 | * 5 pre designed colors (by *SliderPanelStyles*) 24 | * SliderNavigation element can flow within underlaying content or not 25 | * configure custom TabSize (need to change css as well!) 26 | * Vaadin compatibility 27 | * 1.x Vaadin 7 28 | * 2.x Vaadin 8 29 | 30 | 31 | Workflow 32 | ======== 33 | 34 | Add the dependency to your pom the GWT inherits will get automatically added by the maven-vaadin-plugin. 35 | 36 | ```xml 37 | 38 | org.vaadin.addons 39 | vaadin-sliderpanel 40 | ${vaadin-sliderpanel-version} 41 | 42 | ``` 43 | 44 | ```xml 45 | 46 | ``` 47 | 48 | You can recolor the panel by changing the css like: 49 | 50 | ```css 51 | .v-sliderpanel-wrapper .v-sliderpanel-content { 52 | background: #99CCFF; 53 | color: #000; 54 | } 55 | .v-sliderpanel-wrapper .v-sliderpanel-tab { 56 | background: #B1E7FF; 57 | color: #000; 58 | } 59 | ``` 60 | 61 | Version 1.1.x introduced some extra colors that you can use for example: 62 | 63 | ```java 64 | SliderPanel sliderPanel = new SliderPanel(dummyContent("White Slider", 3), false, SliderMode.TOP); 65 | firstTopSlider.setCaption("White Slider"); 66 | firstTopSlider.addStyleName(SliderPanelStyles.COLOR_WHITE); 67 | ``` 68 | 69 | The class **SliderPanelStyles** holds the style options. Further more you can place your custom StyleName in the same way... 70 | 71 | Version 1.2.x introduced a fluent builder to configure SliderPanel: 72 | 73 | ```java 74 | SliderPanel sliderPanel = new SliderPanelBuilder(dummyContent("White Slider", 3)) 75 | .caption("White Slider") 76 | .mode(SliderMode.TOP) 77 | .tabPosition(SliderTabPosition.MIDDLE) 78 | .style(SliderPanelStyles.COLOR_WHITE) 79 | .build(); 80 | ``` 81 | Version 1.4.x rearranged the sass styling in order to use mixins and allow to overwrite defaults. The Sample contains an example how you can configure your custom styling. Explanation see Styling. 82 | 83 | 84 | Version 2.x.x Compatible with Vaadin 8 85 | 86 | 87 | Details to the addon you can find on [Vaadin](https://vaadin.com/directory#addon/sliderpanel) 88 | 89 | Styling 90 | ======= 91 | ```java 92 | // add your stylesheet to UI 93 | // Specify your custom tabSize and add your custom-stylename 94 | new SliderPanelBuilder(dummyContent("Bottom Slider Heading", 5), "Bottom Custom-Style").mode(SliderMode.BOTTOM) 95 | .tabSize(80) 96 | .tabPosition(SliderTabPosition.END).style("my-sliderpanel").build() 97 | ``` 98 | 99 | ```scss 100 | $tab-long-size-v: 460; // specify the total length of the sliderpanel-navigator 101 | $tab-short-size-v: 80; // height of the navigator 102 | $tab-caption-size-v: 390; // width of caption within navigator 103 | 104 | /* relative to org/vaadin/sliderpanel */ 105 | @import "../components/sliderpanel"; 106 | .my-sliderpanel { 107 | @include sliderpanel; 108 | 109 | .v-sliderpanel-wrapper { 110 | .v-sliderpanel-tab { 111 | // increase font-size of caption 112 | .v-sliderpanel-caption { 113 | font-size: 30px; 114 | line-height: $tab-short-size-v - 6px; 115 | } 116 | // increase size of icon 117 | .v-sliderpanel-icon { 118 | height: 44px; 119 | width: 44px; 120 | line-height: 44px; 121 | font-size: 32px; 122 | } 123 | } 124 | } 125 | } 126 | ``` 127 | Finally you need to configure your pom to unpack the sliperpanel-components into your project and compile your scss file 128 | ```xml 129 | 130 | org.apache.maven.plugins 131 | maven-dependency-plugin 132 | 133 | 134 | unpack 135 | generate-sources 136 | 137 | unpack 138 | 139 | 140 | 141 | 142 | org.vaadin.addons 143 | vaadin-sliderpanel 144 | 2.0.0-SNAPSHOT 145 | jar 146 | **/sliderpanel/components/*.scss 147 | ${basedir}/src/main/resources 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | org.codehaus.mojo 157 | exec-maven-plugin 158 | 1.5.0 159 | 160 | 161 | stylesheet 162 | compile 163 | 164 | java 165 | 166 | 167 | true 168 | true 169 | 170 | com.vaadin 171 | vaadin-sass-compiler 172 | 173 | com.vaadin.sass.SassCompiler 174 | 175 | ${basedir}/src/main/resources/org/vaadin/sliderpanel/demo/demo.scss 176 | ${basedir}/src/main/resources/org/vaadin/sliderpanel/demo/demo.css 177 | 178 | 179 | 180 | 181 | 182 | 183 | com.vaadin 184 | vaadin-sass-compiler 185 | 0.9.13 186 | 187 | 188 | 189 | ``` 190 | 191 | Layouting 192 | ======== 193 | ![layout-mockup](assets/sliderpanel-layouting.png) 194 | It's important that you take care for the main layout. Use a combination of VerticalLayout and HorizontalLayout. The SliderPosition is only a hint for the component in which direction the slider should get expand. When you place for example as first component a SliderPanel with SliderMode.RIGHT to a HorizontalLayout and afterwards the middleContent with ExpandRatio(1) it will expand outside the visible browserarea. 195 | 196 | ```java 197 | protected void init(final VaadinRequest vaadinRequest) { 198 | final HorizontalLayout mainLayout = new HorizontalLayout(); 199 | mainLayout.setSizeFull(); 200 | 201 | SliderPanel rightSlider = new SliderPanel(new Label("

SliderContent

", ContentMode.HTML), SliderMode.RIGHT); 202 | rightSlider.setCaption("SliderCaption"); 203 | mainLayout.addComponent(rightSlider); 204 | 205 | VerticalLayout middleContent = new VerticalLayout(); 206 | middleContent.setSizeFull(); 207 | middleContent.addComponent(new Label("

MiddleContent

Lots of Content ...

", ContentMode.HTML)); 208 | 209 | mainLayout.addComponent(middleContent); 210 | mainLayout.setExpandRatio(middleContent, 1); 211 | setContent(mainLayout); 212 | } 213 | ``` 214 | ![wrong-sample](assets/sliderpanel-wrong-sample.png) 215 | 216 | The Layouting of the SliderPanel is not made absolute because of the possibility to use it also within the layout: 217 | 218 | ![layout-variant](assets/sliderpanel-layouting-variant.png) 219 | 220 | 221 | The MIT License (MIT) 222 | ------------------------- 223 | 224 | Copyright (c) 2017 rocketbase.io 225 | 226 | Permission is hereby granted, free of charge, to any person obtaining a copy 227 | of this software and associated documentation files (the "Software"), to deal 228 | in the Software without restriction, including without limitation the rights 229 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 230 | copies of the Software, and to permit persons to whom the Software is 231 | furnished to do so, subject to the following conditions: 232 | 233 | The above copyright notice and this permission notice shall be included in all 234 | copies or substantial portions of the Software. 235 | 236 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 237 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 238 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 239 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 240 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 241 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 242 | SOFTWARE. 243 | 244 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/SliderPanel.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel; 2 | 3 | import com.vaadin.shared.Registration; 4 | import com.vaadin.ui.AbstractSingleComponentContainer; 5 | import com.vaadin.ui.Component; 6 | import com.vaadin.util.ReflectTools; 7 | import org.vaadin.sliderpanel.client.*; 8 | 9 | import java.io.Serializable; 10 | import java.lang.reflect.Method; 11 | 12 | /** 13 | * Vaadin SliderPanel 14 | * 15 | * @author Marten Prieß (http://www.non-rocket-science.com) 16 | * @version 1.0 17 | */ 18 | public class SliderPanel extends AbstractSingleComponentContainer { 19 | 20 | 21 | private final SliderPanelServerRpc rpc = new SliderPanelServerRpc() { 22 | 23 | @Override 24 | public void clicked(final boolean visible) { 25 | getState().expand = visible; 26 | SliderPanel.this.fireEvent(new SliderPanelToggleEvent(SliderPanel.this, visible)); 27 | } 28 | }; 29 | 30 | /** 31 | * {@link SliderPanelBuilder} simplify the configuration of the {@link SliderPanel}
32 | * You can write your configuration with the fluent api
33 | * Hint: to construct {@link SliderPanel} use {@link SliderPanelBuilder#build()} 34 | * 35 | * @param builder instance of the builder. normally create instance via {@link SliderPanelBuilder#build()} 36 | */ 37 | public SliderPanel(final SliderPanelBuilder builder) { 38 | setContent(builder.content); 39 | if (builder.mode.isVertical()) { 40 | setHeight(100, Unit.PERCENTAGE); 41 | setWidth(builder.flowInContent ? 0 : builder.tabSize, Unit.PIXELS); 42 | } else { 43 | setWidth(100, Unit.PERCENTAGE); 44 | setHeight(builder.flowInContent ? 0 : builder.tabSize, Unit.PIXELS); 45 | } 46 | registerRpc(this.rpc); 47 | 48 | getState().pixel = builder.pixel; 49 | getState().expand = builder.expanded; 50 | getState().mode = builder.mode; 51 | getState().tabSize = builder.tabSize; 52 | getState().flowInContent = builder.flowInContent; 53 | getState().tabPosition = builder.tabPosition; 54 | getState().animationDuration = builder.animationDuration; 55 | getState().autoCollapseSlider = builder.autoCollapseSlider; 56 | getState().zIndex = builder.zIndex; 57 | 58 | if (builder.caption != null) { 59 | getState().caption = builder.caption; 60 | } 61 | if (builder.listeners != null) { 62 | builder.listeners.forEach(l -> { 63 | addToggleListener(l); 64 | }); 65 | } 66 | if (builder.styles != null) { 67 | for (String style : builder.styles) { 68 | addStyleName(style); 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * Caption of the tab escape HTML 75 | */ 76 | @Override 77 | public void setCaption(final String caption) { 78 | getState().caption = caption; 79 | } 80 | 81 | /** 82 | * controls the position of the tab-panel
83 | * 84 | * @param tabPosition by default BEGINNING 85 | */ 86 | public void setTabPosition(final SliderTabPosition tabPosition) { 87 | getState().tabPosition = tabPosition; 88 | } 89 | 90 | /** 91 | * explicitly map the custom state object to the server implementation 92 | * 93 | * @return current SliderPanelState 94 | */ 95 | @Override 96 | protected SliderPanelState getState() { 97 | return (SliderPanelState) super.getState(); 98 | } 99 | 100 | /** 101 | * @return duration in milliseconds 102 | */ 103 | public int getAnimationDuration() { 104 | return getState().animationDuration; 105 | } 106 | 107 | /** 108 | * set the animation duration
109 | * by default 500ms 110 | * 111 | * @param animationDuration in milliseconds 112 | */ 113 | public void setAnimationDuration(final int animationDuration) { 114 | getState().animationDuration = animationDuration; 115 | } 116 | 117 | /** 118 | * by default the {@link SliderPanel} calculates it's content width/height (depending on it's mode)
119 | * in some cases it's useful to programmatically set this value 120 | * 121 | * @param pixel width/height (depending on it's mode) 122 | */ 123 | public void setFixedContentSize(final int pixel) { 124 | getState().pixel = pixel; 125 | } 126 | 127 | /** 128 | * by default the {@link SliderPanel} stays open when use clicks outside
129 | * when you enable autoCollapse the slider closes in mode of expand when user clicks somewhere else 130 | * 131 | * @param autoCollapseSlider enable auto collapse in expand state 132 | */ 133 | public void setAutoCollapseSlider(boolean autoCollapseSlider) { 134 | getState().autoCollapseSlider = autoCollapseSlider; 135 | } 136 | 137 | /** 138 | * z-Index of navigator, content and wrapper
139 | * you can specify for multiple sliders which lays above another 140 | * 141 | * @param zIndex default 9990 142 | */ 143 | public void setZIndex(int zIndex) { 144 | getState().zIndex = zIndex; 145 | } 146 | 147 | /** 148 | * change to value when not already set 149 | * 150 | * @param value true means expand 151 | * @param animated should be animated or not 152 | */ 153 | public void setExpanded(final boolean value, final boolean animated) { 154 | getRpcProxy(SliderPanelClientRpc.class).setExpand(value, animated); 155 | } 156 | 157 | /** 158 | * returns the current state of {@link SliderPanel}
159 | * it look only on state - a possible queued change is not checked 160 | * 161 | * @return is expanded 162 | */ 163 | public boolean isExpanded() { 164 | return getState().expand; 165 | } 166 | 167 | /** 168 | * change from expand to collapsed... 169 | */ 170 | public void toogle() { 171 | getRpcProxy(SliderPanelClientRpc.class).setExpand(!getState().expand, true); 172 | } 173 | 174 | /** 175 | * collapse with animation
176 | * when not animation is wished use {@link #setExpanded(boolean, boolean)} 177 | */ 178 | public void collapse() { 179 | getRpcProxy(SliderPanelClientRpc.class).setExpand(false, true); 180 | } 181 | 182 | /** 183 | * expand with animation
184 | * when not animation is wished use {@link #setExpanded(boolean, boolean)} 185 | */ 186 | public void expand() { 187 | getRpcProxy(SliderPanelClientRpc.class).setExpand(true, true); 188 | } 189 | 190 | /** 191 | * schedule a state change of the slider on client site
192 | * a recall within the schedule will cancel the previous one 193 | * 194 | * @param value true means expand 195 | * @param animated should be animated or not 196 | * @param delayMillis millis in future the task will happen 197 | */ 198 | public void scheduleExpand(final boolean value, final boolean animated, final int delayMillis) { 199 | getRpcProxy(SliderPanelClientRpc.class).scheduleExpand(value, animated, delayMillis); 200 | } 201 | 202 | /** 203 | * schedule a change from expand to collapse vice versa in future. will trigger a timer on client site that will change the slider state 204 | *
205 | * a recall within the schedule will cancel the previous one 206 | * 207 | * @param delayMillis millis in future the task will happen 208 | */ 209 | public void scheduleToggle(final int delayMillis) { 210 | getRpcProxy(SliderPanelClientRpc.class).scheduleExpand(!getState().expand, true, delayMillis); 211 | } 212 | 213 | /** 214 | * schedule a collapse in future. will trigger a timer on client site that will collapse the slider
215 | * a recall within the schedule will cancel the previous one 216 | * 217 | * @param delayMillis millis in future the task will happen 218 | */ 219 | public void scheduleCollapse(final int delayMillis) { 220 | getRpcProxy(SliderPanelClientRpc.class).scheduleExpand(false, true, delayMillis); 221 | } 222 | 223 | /** 224 | * schedule an expand in future. will trigger a timer on client site that will expand the slider
225 | * a recall within the schedule will cancel the previous one 226 | * 227 | * @param delayMillis millis in future the task will happen 228 | */ 229 | public void scheduleExpand(final int delayMillis) { 230 | getRpcProxy(SliderPanelClientRpc.class).scheduleExpand(true, true, delayMillis); 231 | } 232 | 233 | 234 | public Registration addToggleListener(SliderPanelToggleListener listener) { 235 | return this.addListener(SliderPanelToggleEvent.class, listener, SliderPanelToggleListener.ELEMENT_TOGGLED_METHOD); 236 | } 237 | 238 | 239 | public interface SliderPanelToggleListener extends Serializable { 240 | 241 | Method ELEMENT_TOGGLED_METHOD = ReflectTools 242 | .findMethod(SliderPanel.SliderPanelToggleListener.class, "toggle", 243 | SliderPanel.SliderPanelToggleEvent.class); 244 | 245 | void toggle(SliderPanelToggleEvent event); 246 | } 247 | 248 | public static class SliderPanelToggleEvent extends Component.Event { 249 | 250 | private boolean expand; 251 | 252 | public SliderPanelToggleEvent(SliderPanel source, boolean expand) { 253 | super(source); 254 | this.expand = expand; 255 | } 256 | 257 | @Override 258 | public SliderPanel getSource() { 259 | return (SliderPanel) super.getSource(); 260 | } 261 | 262 | public boolean isExpand() { 263 | return expand; 264 | } 265 | } 266 | 267 | /** 268 | * allow to disable changing toggle
269 | * content is not disabled 270 | * 271 | * @param enabled by default enabled 272 | */ 273 | public void setEnabledToggle(boolean enabled) { 274 | getState().enableToggle = enabled; 275 | } 276 | 277 | public boolean isEnabledToggle() { 278 | return getState().enableToggle; 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/src/main/java/org/vaadin/sliderpanel/demo/DemoUI.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.demo; 2 | 3 | import com.vaadin.annotations.StyleSheet; 4 | import com.vaadin.annotations.Widgetset; 5 | import com.vaadin.server.Page; 6 | import com.vaadin.server.Page.BrowserWindowResizeEvent; 7 | import com.vaadin.server.Page.BrowserWindowResizeListener; 8 | import com.vaadin.server.VaadinRequest; 9 | import com.vaadin.shared.ui.ContentMode; 10 | import com.vaadin.spring.annotation.SpringUI; 11 | import com.vaadin.ui.*; 12 | import com.vaadin.ui.Button.ClickEvent; 13 | import com.vaadin.ui.Notification.Type; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.vaadin.sliderpanel.SliderPanel; 16 | import org.vaadin.sliderpanel.SliderPanelBuilder; 17 | import org.vaadin.sliderpanel.SliderPanelStyles; 18 | import org.vaadin.sliderpanel.client.SliderMode; 19 | import org.vaadin.sliderpanel.client.SliderTabPosition; 20 | import org.vaadin.sliderpanel.demo.data.DummyDataGen; 21 | import org.vaadin.sliderpanel.demo.data.Inhabitants; 22 | 23 | import java.util.Date; 24 | 25 | @SpringUI() 26 | @StyleSheet("demo.css") 27 | @Widgetset("org.vaadin.sliderpanel.demo.WidgetSet") 28 | public class DemoUI extends UI { 29 | 30 | private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet,consetetur sadipscing elitr, " 31 | + "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."; 32 | 33 | private SliderPanel secondTopSlider; 34 | 35 | 36 | @Value("${build.version}") 37 | private String buildVersion; 38 | 39 | @Override 40 | protected void init(final VaadinRequest vaadinRequest) { 41 | final VerticalLayout mainLayout = new VerticalLayout(); 42 | mainLayout.addStyleName("main"); 43 | mainLayout.setSizeFull(); 44 | mainLayout.setMargin(false); 45 | mainLayout.setSpacing(false); 46 | 47 | // top slider 48 | Grid grid = genGrid(); 49 | VerticalLayout topLeftSliderContent = new VerticalLayout(new Label("Grid works now!"), grid); 50 | topLeftSliderContent.addComponent(new DateField()); 51 | topLeftSliderContent.setMargin(true); 52 | topLeftSliderContent.setSpacing(true); 53 | topLeftSliderContent.setExpandRatio(grid, 1); 54 | 55 | final SliderPanel firstTopSlider = 56 | new SliderPanelBuilder(topLeftSliderContent, "First Top with Grid") 57 | .tabPosition(SliderTabPosition.END) 58 | .style(SliderPanelStyles.COLOR_WHITE) 59 | .flowInContent(true) 60 | .build(); 61 | 62 | secondTopSlider = 63 | new SliderPanelBuilder(dummyContent("Second Top Slider Heading", 1), "Second Top fixedContentSize (flowIn)") 64 | .tabPosition(SliderTabPosition.BEGINNING) 65 | .style(SliderPanelStyles.COLOR_GREEN) 66 | .flowInContent(true) 67 | .fixedContentSize(Page.getCurrent() 68 | .getBrowserWindowHeight() - 130) 69 | .build(); 70 | 71 | // Two top slider 72 | HorizontalLayout topTwoSliderLayout = new HorizontalLayout(); 73 | topTwoSliderLayout.setWidth(100, Unit.PERCENTAGE); 74 | topTwoSliderLayout.setHeight(0, Unit.PIXELS); 75 | topTwoSliderLayout.setMargin(false); 76 | topTwoSliderLayout.setSpacing(false); 77 | topTwoSliderLayout.addComponent(firstTopSlider); 78 | topTwoSliderLayout.setExpandRatio(firstTopSlider, 1); 79 | topTwoSliderLayout.addComponent(secondTopSlider); 80 | topTwoSliderLayout.setExpandRatio(secondTopSlider, 1); 81 | mainLayout.addComponent(topTwoSliderLayout); 82 | 83 | // center layout with left and right slider 84 | HorizontalLayout contentLayout = new HorizontalLayout(); 85 | contentLayout.setSpacing(false); 86 | contentLayout.setSizeFull(); 87 | 88 | // left slider shoudn't get displayed over this element 89 | VerticalLayout paddingLeftComp = new VerticalLayout(); 90 | paddingLeftComp.addStyleName(SliderPanelStyles.COLOR_GRAY); 91 | paddingLeftComp.setWidth("200px"); 92 | paddingLeftComp.setHeight("100%"); 93 | paddingLeftComp.setMargin(true); 94 | 95 | Label leftPaddingContent = new Label("

Left Padding

" 96 | + "

Wokring with Grid since version 1.4.2

" 97 | + "

compatible with Vaadin 8

", ContentMode.HTML); 98 | leftPaddingContent.setSizeFull(); 99 | paddingLeftComp.addComponentsAndExpand(leftPaddingContent); 100 | 101 | 102 | contentLayout.addComponent(paddingLeftComp); 103 | 104 | // left slider 105 | VerticalLayout leftDummyContent = dummyContent("Left Slider Heading", 3); 106 | leftDummyContent.setWidth(400, Unit.PIXELS); 107 | SliderPanel leftSlider = 108 | new SliderPanelBuilder(leftDummyContent, "Left slow Slider").mode(SliderMode.LEFT) 109 | .tabPosition(SliderTabPosition.BEGINNING) 110 | .animationDuration(2000) 111 | .zIndex(9980) 112 | .build(); 113 | contentLayout.addComponent(leftSlider); 114 | paddingLeftComp.addComponent(new Button("toggle Slider", e -> leftSlider.setEnabledToggle(!leftSlider.isEnabledToggle()))); 115 | paddingLeftComp.addComponent(new Button("toggle Enabled", e -> leftSlider.setEnabled(!leftSlider.isEnabled()))); 116 | 117 | // dummy middle content 118 | VerticalLayout contentLabel = dummyContent("Main Content", 4); 119 | contentLabel.setMargin(true); 120 | contentLabel.setSizeFull(); 121 | 122 | contentLabel.addComponent(new Button("schedule toggle first-top-slider", new Button.ClickListener() { 123 | 124 | @Override 125 | public void buttonClick(final ClickEvent event) { 126 | Notification.show("start schedule toggle on first-top-slider in 2 secs", Type.TRAY_NOTIFICATION); 127 | firstTopSlider.scheduleToggle(2000); 128 | } 129 | })); 130 | 131 | final Label listenerLabel = new Label("event-listener for right-slider", ContentMode.HTML); 132 | listenerLabel.setWidth(100, Unit.PERCENTAGE); 133 | listenerLabel.setHeight(45, Unit.PIXELS); 134 | contentLabel.addComponent(listenerLabel); 135 | 136 | contentLayout.addComponent(contentLabel); 137 | contentLayout.setComponentAlignment(contentLabel, Alignment.MIDDLE_CENTER); 138 | contentLayout.setExpandRatio(contentLabel, 1); 139 | 140 | // right slider 141 | VerticalLayout rightDummyContent = dummyContent("Right Slider Heading", 1); 142 | rightDummyContent.setWidth(400, Unit.PIXELS); 143 | 144 | ComboBox simpleCombo = new ComboBox("Combo"); 145 | simpleCombo.setItems(SliderMode.values()); 146 | rightDummyContent.addComponent(simpleCombo); 147 | rightDummyContent.addComponent(new Label("vaadin's combo creates an inner popup that is also get catched by autoCollapse detection")); 148 | rightDummyContent.addComponent(genGrid()); 149 | 150 | SliderPanel rightSlider = 151 | new SliderPanelBuilder(rightDummyContent, "Right Slider + Grid (autoCollapse)").mode(SliderMode.RIGHT) 152 | .tabPosition(SliderTabPosition.MIDDLE) 153 | .flowInContent(true) 154 | .autoCollapseSlider(true) 155 | .zIndex(9980) 156 | .style(SliderPanelStyles.COLOR_BLUE) 157 | .listener(e -> { 158 | listenerLabel.setValue( 159 | "event-listener for right-slider: " + (e.isExpand() ? "expand" : "collapsed") + " by: " 160 | + new Date().toString()); 161 | }) 162 | .build(); 163 | contentLayout.addComponent(rightSlider); 164 | 165 | // fit full screen 166 | mainLayout.addComponent(contentLayout); 167 | mainLayout.setExpandRatio(contentLayout, 1); 168 | 169 | // bottom slider 170 | // i've created a custom sliderpanel style within demo.scss with different labelwidth 171 | SliderPanel bottomSlider = 172 | new SliderPanelBuilder(dummyContent("Bottom Slider Heading", 5), "Bottom Custom-Style").mode(SliderMode.BOTTOM) 173 | .autoCollapseSlider(true) 174 | .flowInContent(true) 175 | .tabSize(80) 176 | .tabPosition(SliderTabPosition.END) 177 | .style("my-sliderpanel", SliderPanelStyles.COLOR_RED) 178 | .build(); 179 | mainLayout.addComponent(bottomSlider); 180 | 181 | HorizontalLayout wrapper = new HorizontalLayout(mainLayout, genInfo()); 182 | wrapper.setSizeFull(); 183 | wrapper.setExpandRatio(mainLayout, 1); 184 | wrapper.setSpacing(false); 185 | 186 | setContent(wrapper); 187 | 188 | Page.getCurrent() 189 | .setTitle("SliderPanel Sample"); 190 | Page.getCurrent() 191 | .addBrowserWindowResizeListener(new BrowserWindowResizeListener() { 192 | 193 | @Override 194 | public void browserWindowResized(BrowserWindowResizeEvent event) { 195 | secondTopSlider.setFixedContentSize(Page.getCurrent() 196 | .getBrowserWindowHeight() - 100); 197 | } 198 | }); 199 | } 200 | 201 | private Grid genGrid() { 202 | // init Grid 203 | final Grid grid = new Grid(Inhabitants.class); 204 | grid.setSizeFull(); 205 | 206 | // init Container 207 | grid.setItems(DummyDataGen.genInhabitants(100)); 208 | grid.setColumnOrder("id", "gender", "name", "bodySize", "birthday", "onFacebook"); 209 | 210 | return grid; 211 | } 212 | 213 | private Component genInfo() { 214 | VerticalLayout info = new VerticalLayout(); 215 | info.setMargin(true); 216 | info.setWidth("320px"); 217 | info.setHeight("100%"); 218 | info.addStyleName("black-bg"); 219 | 220 | Label details = new Label("

Vaadin SliderPanel

" 221 | + "

Developed by Marten Prieß
" 222 | + "www.rocketbase.io

" 223 | + "

Sample & Sourcecode:
github.com
" 224 | + "Vaadin Addon-Site:
vaadin.com

", ContentMode.HTML); 225 | details.setSizeFull(); 226 | info.addComponentsAndExpand(details); 227 | info.addComponent(new Label("

Version: " + buildVersion + "

", ContentMode.HTML)); 228 | 229 | return info; 230 | } 231 | 232 | private VerticalLayout dummyContent(final String title, final int length) { 233 | String text = ""; 234 | for (int x = 0; x <= length; x++) { 235 | text += LOREM_IPSUM + " "; 236 | } 237 | Label htmlDummy = new Label(String.format("

%s

%s", title, text.trim()), ContentMode.HTML); 238 | VerticalLayout component = new VerticalLayout(htmlDummy); 239 | component.setExpandRatio(htmlDummy, 1); 240 | component.addComponent(new Button(title, new Button.ClickListener() { 241 | @Override 242 | public void buttonClick(final ClickEvent event) { 243 | Notification.show("clicked: " + title, Type.HUMANIZED_MESSAGE); 244 | } 245 | })); 246 | component.setMargin(true); 247 | component.setSpacing(true); 248 | return component; 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /vaadin-sliderpanel/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | org.vaadin.addons 6 | vaadin-sliderpanel 7 | 2.2.2-SNAPSHOT 8 | jar 9 | 10 | SliderPanel 11 | SlidingPanel that allows to collapse and expand. Lays of rest of the content 12 | https://github.com/melistik/vaadin-sliderpanel 13 | 14 | 15 | 16 | Marten Prieß 17 | marten@rocketbase.io 18 | rocketbase.io software productions 19 | http://www.rocketbase.io 20 | 21 | 22 | 23 | 24 | 8.0.0 25 | 1.8 26 | 1.8 27 | UTF-8 28 | false 29 | 30 | 31 | ${project.version} 32 | SliderPanel 33 | Marten Prieß 34 | The MIT License (MIT) 35 | ${project.artifactId}-${project.version}.jar 36 | 37 | 38 | 39 | 40 | The MIT License (MIT) 41 | http://opensource.org/licenses/MIT 42 | 43 | 44 | 45 | 46 | 47 | com.vaadin 48 | vaadin-client 49 | ${vaadin.version} 50 | provided 51 | 52 | 53 | com.vaadin 54 | vaadin-client-compiler 55 | ${vaadin.version} 56 | provided 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | src/main/java 65 | 66 | 67 | src/main/resources 68 | 69 | 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-compiler-plugin 75 | 3.6.1 76 | 77 | ${project.encoding} 78 | ${project.source.version} 79 | ${project.target.version} 80 | 81 | 82 | 83 | 84 | org.codehaus.mojo 85 | exec-maven-plugin 86 | 1.5.0 87 | 88 | 89 | stylesheet 90 | compile 91 | 92 | java 93 | 94 | 95 | true 96 | true 97 | 98 | com.vaadin 99 | vaadin-sass-compiler 100 | 101 | com.vaadin.sass.SassCompiler 102 | 103 | ${basedir}/src/main/resources/org/vaadin/sliderpanel/sliderpanel.scss 104 | ${basedir}/src/main/resources/org/vaadin/sliderpanel/public/sliderpanel/sliderpanel.css 105 | 106 | 107 | 108 | 109 | 110 | 111 | com.vaadin 112 | vaadin-sass-compiler 113 | 0.9.13 114 | 115 | 116 | 117 | 118 | 119 | org.apache.felix 120 | maven-bundle-plugin 121 | 3.2.0 122 | true 123 | 124 | 125 | default-bundle 126 | process-classes 127 | 128 | manifest 129 | 130 | 131 | true 132 | 133 | * 134 | org.vaadin.sliderpanel.* 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | org.apache.maven.plugins 143 | maven-jar-plugin 144 | 3.0.2 145 | 146 | 147 | ${project.build.outputDirectory}/META-INF/MANIFEST.MF 148 | true 149 | 150 | true 151 | 152 | 153 | 154 | 1 155 | ${Vaadin-License-Title} 156 | org.vaadin.sliderpanel.WidgetSet 157 | 158 | 159 | 160 | 161 | 162 | 163 | org.apache.maven.plugins 164 | maven-source-plugin 165 | 3.0.1 166 | 167 | 168 | attach-sources 169 | 170 | jar 171 | 172 | 173 | 174 | 175 | 176 | 177 | org.apache.maven.plugins 178 | maven-assembly-plugin 179 | 3.0.0 180 | 181 | false 182 | 183 | assembly/assembly.xml 184 | 185 | 186 | 187 | 188 | 189 | single 190 | 191 | package 192 | 193 | 194 | 195 | 196 | 197 | 198 | org.apache.maven.plugins 199 | maven-javadoc-plugin 200 | 2.10.4 201 | 202 | 203 | attach-javadocs 204 | 205 | jar 206 | 207 | 208 | -Xdoclint:none 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 218 | 219 | org.eclipse.m2e 220 | lifecycle-mapping 221 | 1.0.0 222 | 223 | 224 | 225 | 226 | 227 | 228 | org.jasig.maven 229 | 230 | 231 | sass-maven-plugin 232 | 233 | 234 | [1.1.1,) 235 | 236 | 237 | 238 | update-stylesheets 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | org.codehaus.mojo 250 | 251 | 252 | exec-maven-plugin 253 | 254 | 255 | [1.4.0,) 256 | 257 | 258 | java 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | -------------------------------------------------------------------------------- /vaadin-sliderpanel-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | vaadin-sliderpanel-root 5 | org.vaadin.addons 6 | 2.2.2-SNAPSHOT 7 | 8 | 9 | 4.0.0 10 | vaadin-sliderpanel-demo 11 | 12 | 13 | 14 | Marten Prieß 15 | marten@rocketbase.io 16 | rocketbase.io software productions 17 | http://www.rocketbase.io 18 | 19 | 20 | 21 | 22 | 23 | org.vaadin.sliderpanel.demo.Application 24 | 1.5.1.RELEASE 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | com.vaadin 33 | vaadin-bom 34 | ${vaadin.version} 35 | pom 36 | import 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-dependencies 42 | ${spring.boot.version} 43 | pom 44 | import 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | com.vaadin 53 | vaadin-spring-boot-starter 54 | 2.0.0 55 | 56 | 57 | 58 | org.vaadin.addons 59 | vaadin-sliderpanel 60 | ${version} 61 | 62 | 63 | 64 | com.vaadin 65 | vaadin-client 66 | provided 67 | 68 | 69 | com.vaadin 70 | vaadin-client-compiler 71 | provided 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | ${basedir}/src/main/resources 80 | true 81 | 82 | **/application.yml 83 | **/application.properties 84 | 85 | 86 | 87 | ${basedir}/src/main/resources 88 | 89 | **/application.yml 90 | **/application.properties 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | org.apache.maven.plugins 99 | maven-compiler-plugin 100 | 3.0 101 | 102 | 1.8 103 | 1.8 104 | 105 | 106 | 107 | 108 | org.apache.maven.plugins 109 | maven-dependency-plugin 110 | 111 | 112 | unpack 113 | generate-sources 114 | 115 | unpack 116 | 117 | 118 | 119 | 120 | org.vaadin.addons 121 | vaadin-sliderpanel 122 | ${version} 123 | jar 124 | **/sliderpanel/components/*.scss 125 | ${basedir}/src/main/resources 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | org.codehaus.mojo 135 | exec-maven-plugin 136 | 1.5.0 137 | 138 | 139 | stylesheet 140 | compile 141 | 142 | java 143 | 144 | 145 | true 146 | true 147 | 148 | com.vaadin 149 | vaadin-sass-compiler 150 | 151 | com.vaadin.sass.SassCompiler 152 | 153 | ${basedir}/src/main/resources/org/vaadin/sliderpanel/demo/demo.scss 154 | ${basedir}/src/main/resources/org/vaadin/sliderpanel/demo/demo.css 155 | 156 | 157 | 158 | 159 | 160 | 161 | com.vaadin 162 | vaadin-sass-compiler 163 | 0.9.13 164 | 165 | 166 | 167 | 168 | 169 | com.vaadin 170 | vaadin-maven-plugin 171 | ${vaadin.version} 172 | 173 | -Xmx1g -Xss1024k 174 | ${project.build.outputDirectory}/VAADIN/widgetsets 175 | ${project.build.outputDirectory}/VAADIN/widgetsets 176 | true 177 | 178 | true 179 | ${project.build.directory}/gwtdirt 180 | false 181 | 182 | true 183 | 184 | ${project.build.directory}/gwt-deploy 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | clean 194 | resources 195 | update-widgetset 196 | compile 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | org.apache.maven.plugins 205 | maven-jar-plugin 206 | 207 | 208 | 209 | ${start-class} 210 | 211 | 212 | 213 | 214 | 215 | org.springframework.boot 216 | spring-boot-maven-plugin 217 | ${spring.boot.version} 218 | 219 | 220 | 221 | repackage 222 | 223 | 224 | 225 | 226 | ${start-class} 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 236 | 237 | 238 | org.eclipse.m2e 239 | lifecycle-mapping 240 | 1.0.0 241 | 242 | 243 | 244 | 245 | 246 | com.vaadin 247 | 248 | vaadin-maven-plugin 249 | 250 | [7.1.11,) 251 | 252 | resources 253 | update-widgetset 254 | compile 255 | compile-theme 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | org.apache.maven.plugins 266 | 267 | 268 | maven-dependency-plugin 269 | 270 | 271 | [2.8,) 272 | 273 | 274 | unpack 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | org.codehaus.mojo 285 | 286 | 287 | exec-maven-plugin 288 | 289 | 290 | [1.5.0,) 291 | 292 | 293 | java 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | -------------------------------------------------------------------------------- /assets/sliderpanel-layouting.json: -------------------------------------------------------------------------------- 1 | { 2 | "mockup":{ 3 | "controls":{ 4 | "control":[ 5 | { 6 | "ID":"0", 7 | "h":"600", 8 | "measuredH":"400", 9 | "measuredW":"450", 10 | "properties":{ 11 | "text":"Sliderpanel\nhttp://localhost:8080/vaadin-sliderpanel" 12 | }, 13 | "typeID":"BrowserWindow", 14 | "w":"800", 15 | "x":"98", 16 | "y":"61", 17 | "zOrder":"0" 18 | }, 19 | { 20 | "ID":"1", 21 | "h":"31", 22 | "measuredH":"70", 23 | "measuredW":"100", 24 | "properties":{ 25 | "color":"13421772" 26 | }, 27 | "typeID":"Canvas", 28 | "w":"785", 29 | "x":"105", 30 | "y":"141", 31 | "zOrder":"1" 32 | }, 33 | { 34 | "ID":"2", 35 | "h":"31", 36 | "measuredH":"70", 37 | "measuredW":"100", 38 | "properties":{ 39 | "color":"13421772" 40 | }, 41 | "typeID":"Canvas", 42 | "w":"785", 43 | "x":"105", 44 | "y":"619", 45 | "zOrder":"2" 46 | }, 47 | { 48 | "ID":"4", 49 | "measuredH":"21", 50 | "measuredW":"94", 51 | "properties":{ 52 | "text":"SliderMode.TOP" 53 | }, 54 | "typeID":"Label", 55 | "x":"451", 56 | "y":"146", 57 | "zOrder":"3" 58 | }, 59 | { 60 | "ID":"5", 61 | "measuredH":"21", 62 | "measuredW":"122", 63 | "properties":{ 64 | "text":"SliderMode.BOTTOM" 65 | }, 66 | "typeID":"Label", 67 | "x":"437", 68 | "y":"624", 69 | "zOrder":"4" 70 | }, 71 | { 72 | "ID":"6", 73 | "h":"435", 74 | "measuredH":"70", 75 | "measuredW":"100", 76 | "properties":{ 77 | "color":"13421772" 78 | }, 79 | "typeID":"Canvas", 80 | "w":"31", 81 | "x":"105", 82 | "y":"178", 83 | "zOrder":"5" 84 | }, 85 | { 86 | "ID":"7", 87 | "h":"435", 88 | "measuredH":"70", 89 | "measuredW":"100", 90 | "properties":{ 91 | "color":"13421772" 92 | }, 93 | "typeID":"Canvas", 94 | "w":"31", 95 | "x":"859", 96 | "y":"178", 97 | "zOrder":"6" 98 | }, 99 | { 100 | "ID":"8", 101 | "measuredH":"101", 102 | "measuredW":"21", 103 | "properties":{ 104 | "text":"SliderMode.LEFT", 105 | "textOrientation":"up" 106 | }, 107 | "typeID":"Label", 108 | "x":"112", 109 | "y":"345", 110 | "zOrder":"7" 111 | }, 112 | { 113 | "ID":"9", 114 | "measuredH":"109", 115 | "measuredW":"21", 116 | "properties":{ 117 | "text":"SliderMode.RIGHT", 118 | "textOrientation":"down" 119 | }, 120 | "typeID":"Label", 121 | "x":"861", 122 | "y":"341", 123 | "zOrder":"8" 124 | }, 125 | { 126 | "ID":"10", 127 | "measuredH":"32", 128 | "measuredW":"32", 129 | "properties":{ 130 | "icon":{ 131 | "ID":"arrow-circle-down", 132 | "name":"Arrow Circle Down", 133 | "size":"medium" 134 | } 135 | }, 136 | "typeID":"Icon", 137 | "x":"792", 138 | "y":"140", 139 | "zOrder":"9" 140 | }, 141 | { 142 | "ID":"11", 143 | "measuredH":"32", 144 | "measuredW":"32", 145 | "properties":{ 146 | "icon":{ 147 | "ID":"arrow-circle-down", 148 | "name":"Arrow Circle Down", 149 | "size":"medium" 150 | }, 151 | "rotation":"90" 152 | }, 153 | "typeID":"Icon", 154 | "x":"105", 155 | "y":"542", 156 | "zOrder":"10" 157 | }, 158 | { 159 | "ID":"12", 160 | "measuredH":"32", 161 | "measuredW":"32", 162 | "properties":{ 163 | "icon":{ 164 | "ID":"arrow-circle-down", 165 | "name":"Arrow Circle Down", 166 | "size":"medium" 167 | }, 168 | "rotation":"180" 169 | }, 170 | "typeID":"Icon", 171 | "x":"792", 172 | "y":"618", 173 | "zOrder":"11" 174 | }, 175 | { 176 | "ID":"13", 177 | "measuredH":"32", 178 | "measuredW":"32", 179 | "properties":{ 180 | "icon":{ 181 | "ID":"arrow-circle-down", 182 | "name":"Arrow Circle Down", 183 | "size":"medium" 184 | }, 185 | "rotation":"270" 186 | }, 187 | "typeID":"Icon", 188 | "x":"858", 189 | "y":"224", 190 | "zOrder":"12" 191 | }, 192 | { 193 | "ID":"14", 194 | "h":"349", 195 | "measuredH":"70", 196 | "measuredW":"100", 197 | "properties":{ 198 | "backgroundAlpha":"0.25", 199 | "borderColor":"13369344", 200 | "borderStyle":"square", 201 | "color":"15374745" 202 | }, 203 | "typeID":"Canvas", 204 | "w":"526", 205 | "x":"235", 206 | "y":"221", 207 | "zOrder":"13" 208 | }, 209 | { 210 | "ID":"15", 211 | "measuredH":"21", 212 | "measuredW":"88", 213 | "properties":{ 214 | "color":"13369344", 215 | "text":"Vertical Layout" 216 | }, 217 | "typeID":"Label", 218 | "x":"235", 219 | "y":"203", 220 | "zOrder":"14" 221 | }, 222 | { 223 | "ID":"16", 224 | "h":"33", 225 | "measuredH":"70", 226 | "measuredW":"100", 227 | "properties":{ 228 | "backgroundAlpha":"0.25", 229 | "borderColor":"13369344", 230 | "borderStyle":"square", 231 | "color":"15374745" 232 | }, 233 | "typeID":"Canvas", 234 | "w":"511", 235 | "x":"241", 236 | "y":"232", 237 | "zOrder":"15" 238 | }, 239 | { 240 | "ID":"17", 241 | "h":"246", 242 | "measuredH":"70", 243 | "measuredW":"100", 244 | "properties":{ 245 | "backgroundAlpha":"0.25", 246 | "borderColor":"13369344", 247 | "borderStyle":"square", 248 | "color":"15374745" 249 | }, 250 | "typeID":"Canvas", 251 | "w":"511", 252 | "x":"241", 253 | "y":"272", 254 | "zOrder":"16" 255 | }, 256 | { 257 | "ID":"18", 258 | "h":"33", 259 | "measuredH":"70", 260 | "measuredW":"100", 261 | "properties":{ 262 | "backgroundAlpha":"0.25", 263 | "borderColor":"13369344", 264 | "borderStyle":"square", 265 | "color":"15374745" 266 | }, 267 | "typeID":"Canvas", 268 | "w":"511", 269 | "x":"241", 270 | "y":"526", 271 | "zOrder":"17" 272 | }, 273 | { 274 | "ID":"19", 275 | "h":"23", 276 | "measuredH":"70", 277 | "measuredW":"100", 278 | "properties":{ 279 | "color":"13421772" 280 | }, 281 | "typeID":"Canvas", 282 | "w":"467", 283 | "x":"265", 284 | "y":"237", 285 | "zOrder":"18" 286 | }, 287 | { 288 | "ID":"20", 289 | "measuredH":"21", 290 | "measuredW":"94", 291 | "properties":{ 292 | "text":"SliderMode.TOP" 293 | }, 294 | "typeID":"Label", 295 | "x":"451", 296 | "y":"238", 297 | "zOrder":"19" 298 | }, 299 | { 300 | "ID":"21", 301 | "h":"77", 302 | "measuredH":"100", 303 | "measuredW":"150", 304 | "properties":{ 305 | "curvature":"-1", 306 | "direction":"bottom", 307 | "rightArrow":"false" 308 | }, 309 | "typeID":"Arrow", 310 | "w":"212", 311 | "x":"580", 312 | "y":"256", 313 | "zOrder":"30" 314 | }, 315 | { 316 | "ID":"22", 317 | "h":"46", 318 | "measuredH":"123", 319 | "measuredW":"109", 320 | "properties":{ 321 | "text":"setExpandRatio(1)" 322 | }, 323 | "typeID":"StickyNote", 324 | "w":"138", 325 | "x":"761", 326 | "y":"251", 327 | "zOrder":"20" 328 | }, 329 | { 330 | "ID":"23", 331 | "h":"25", 332 | "measuredH":"100", 333 | "measuredW":"150", 334 | "properties":{ 335 | "curvature":"-1", 336 | "direction":"bottom", 337 | "rightArrow":"false" 338 | }, 339 | "typeID":"Arrow", 340 | "w":"157", 341 | "x":"323", 342 | "y":"187", 343 | "zOrder":"22" 344 | }, 345 | { 346 | "ID":"24", 347 | "h":"46", 348 | "measuredH":"123", 349 | "measuredW":"109", 350 | "properties":{ 351 | "text":"setSizeFull()" 352 | }, 353 | "typeID":"StickyNote", 354 | "w":"138", 355 | "x":"461", 356 | "y":"176", 357 | "zOrder":"21" 358 | }, 359 | { 360 | "ID":"25", 361 | "h":"210", 362 | "measuredH":"70", 363 | "measuredW":"100", 364 | "properties":{ 365 | "backgroundAlpha":"0.75", 366 | "borderColor":"5865130", 367 | "borderStyle":"square", 368 | "color":"10470904" 369 | }, 370 | "typeID":"Canvas", 371 | "w":"481", 372 | "x":"258", 373 | "y":"298", 374 | "zOrder":"23" 375 | }, 376 | { 377 | "ID":"26", 378 | "measuredH":"21", 379 | "measuredW":"102", 380 | "properties":{ 381 | "color":"2848996", 382 | "text":"Horizontal Layout" 383 | }, 384 | "typeID":"Label", 385 | "x":"258", 386 | "y":"277", 387 | "zOrder":"24" 388 | }, 389 | { 390 | "ID":"27", 391 | "h":"191", 392 | "measuredH":"70", 393 | "measuredW":"100", 394 | "properties":{ 395 | "color":"13421772" 396 | }, 397 | "typeID":"Canvas", 398 | "w":"31", 399 | "x":"265", 400 | "y":"308", 401 | "zOrder":"25" 402 | }, 403 | { 404 | "ID":"28", 405 | "measuredH":"101", 406 | "measuredW":"21", 407 | "properties":{ 408 | "text":"SliderMode.LEFT", 409 | "textOrientation":"up" 410 | }, 411 | "typeID":"Label", 412 | "x":"271", 413 | "y":"353", 414 | "zOrder":"26" 415 | }, 416 | { 417 | "ID":"29", 418 | "h":"191", 419 | "measuredH":"70", 420 | "measuredW":"100", 421 | "properties":{ 422 | "color":"13421772" 423 | }, 424 | "typeID":"Canvas", 425 | "w":"31", 426 | "x":"701", 427 | "y":"308", 428 | "zOrder":"27" 429 | }, 430 | { 431 | "ID":"30", 432 | "measuredH":"109", 433 | "measuredW":"21", 434 | "properties":{ 435 | "text":"SliderMode.RIGHT", 436 | "textOrientation":"down" 437 | }, 438 | "typeID":"Label", 439 | "w":"21", 440 | "x":"704", 441 | "y":"349", 442 | "zOrder":"28" 443 | }, 444 | { 445 | "ID":"31", 446 | "h":"191", 447 | "measuredH":"70", 448 | "measuredW":"100", 449 | "properties":{ 450 | "backgroundAlpha":"0.5", 451 | "borderColor":"13421772", 452 | "borderStyle":"roundedDotted", 453 | "color":"16777215" 454 | }, 455 | "typeID":"Canvas", 456 | "w":"390", 457 | "x":"303", 458 | "y":"308", 459 | "zOrder":"29" 460 | }, 461 | { 462 | "ID":"32", 463 | "h":"37", 464 | "measuredH":"100", 465 | "measuredW":"150", 466 | "properties":{ 467 | "curvature":"-1", 468 | "direction":"bottom", 469 | "rightArrow":"false" 470 | }, 471 | "typeID":"Arrow", 472 | "w":"425", 473 | "x":"367", 474 | "y":"256", 475 | "zOrder":"31" 476 | }, 477 | { 478 | "ID":"33", 479 | "measuredH":"43", 480 | "measuredW":"267", 481 | "properties":{ 482 | "color":"16777215", 483 | "text":"middle content" 484 | }, 485 | "typeID":"Title", 486 | "x":"367", 487 | "y":"382", 488 | "zOrder":"32" 489 | }, 490 | { 491 | "ID":"34", 492 | "h":"23", 493 | "measuredH":"70", 494 | "measuredW":"100", 495 | "properties":{ 496 | "color":"13421772" 497 | }, 498 | "typeID":"Canvas", 499 | "w":"467", 500 | "x":"265", 501 | "y":"531", 502 | "zOrder":"33" 503 | }, 504 | { 505 | "ID":"35", 506 | "measuredH":"21", 507 | "measuredW":"122", 508 | "properties":{ 509 | "text":"SliderMode.BOTTOM" 510 | }, 511 | "typeID":"Label", 512 | "x":"437", 513 | "y":"532", 514 | "zOrder":"34" 515 | } 516 | ] 517 | }, 518 | "measuredH":"661", 519 | "measuredW":"899", 520 | "mockupH":"600", 521 | "mockupW":"801", 522 | "version":"1.0" 523 | } 524 | } -------------------------------------------------------------------------------- /vaadin-sliderpanel/src/main/java/org/vaadin/sliderpanel/client/VSliderPanel.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.sliderpanel.client; 2 | 3 | import org.vaadin.sliderpanel.SliderPanel; 4 | 5 | import com.google.gwt.animation.client.Animation; 6 | import com.google.gwt.dom.client.DivElement; 7 | import com.google.gwt.dom.client.Document; 8 | import com.google.gwt.dom.client.Element; 9 | import com.google.gwt.dom.client.EventTarget; 10 | import com.google.gwt.dom.client.NativeEvent; 11 | import com.google.gwt.dom.client.Style; 12 | import com.google.gwt.dom.client.Style.Display; 13 | import com.google.gwt.dom.client.Style.Position; 14 | import com.google.gwt.safehtml.shared.SafeHtmlUtils; 15 | import com.google.gwt.user.client.DOM; 16 | import com.google.gwt.user.client.Event; 17 | import com.google.gwt.user.client.Event.NativePreviewEvent; 18 | import com.google.gwt.user.client.Event.NativePreviewHandler; 19 | import com.google.gwt.user.client.Timer; 20 | import com.google.gwt.user.client.ui.SimplePanel; 21 | 22 | /** 23 | * the main gwt implementation of the {@link SliderPanel} 24 | * 25 | * @author Marten Prieß (http://www.non-rocket-science.com) 26 | * @version 1.0 27 | */ 28 | public class VSliderPanel extends SimplePanel implements NativePreviewHandler { 29 | 30 | public static final String CLASSNAME = "v-sliderpanel"; 31 | 32 | private String wrapperBaseClassName = "", tabBaseClassName = ""; 33 | 34 | private final DivElement wrapperNode, contentNode, navigationElem, captionNode, tabElem; 35 | 36 | private boolean initialized = false; 37 | 38 | private boolean expand = false; 39 | 40 | private boolean flowInContent = false; 41 | 42 | private int animationDuration; 43 | 44 | private Integer componentSize = null; 45 | 46 | private SliderMode mode = null; 47 | 48 | private final SliderTabPosition tabPosition = null; 49 | 50 | private int tabSize; 51 | 52 | private final SliderAnimation slideAnimation = new SliderAnimation(); 53 | 54 | private ToggleListener listener; 55 | 56 | private boolean autoCollapseSlider = false; 57 | 58 | private boolean enabled = true; 59 | 60 | public VSliderPanel() { 61 | super(); 62 | // main wrapper of the component 63 | this.wrapperNode = Document.get() 64 | .createDivElement(); 65 | this.wrapperNode.setClassName(VSliderPanel.CLASSNAME + "-wrapper"); 66 | getElement().appendChild(this.wrapperNode); 67 | 68 | // container that holds the content 69 | this.contentNode = Document.get() 70 | .createDivElement(); 71 | this.contentNode.setClassName(VSliderPanel.CLASSNAME + "-content"); 72 | this.contentNode.getStyle() 73 | .setDisplay(Display.BLOCK); 74 | this.wrapperNode.appendChild(this.contentNode); 75 | 76 | // wrapper for collapsed content line, tab with caption and icon 77 | this.navigationElem = Document.get() 78 | .createDivElement(); 79 | this.navigationElem.setClassName(VSliderPanel.CLASSNAME + "-navigator"); 80 | 81 | this.tabElem = Document.get() 82 | .createDivElement(); 83 | this.tabElem.setClassName(VSliderPanel.CLASSNAME + "-tab"); 84 | this.navigationElem.appendChild(this.tabElem); 85 | 86 | this.captionNode = Document.get() 87 | .createDivElement(); 88 | this.captionNode.setClassName(VSliderPanel.CLASSNAME + "-caption"); 89 | this.tabElem.appendChild(this.captionNode); 90 | 91 | DivElement toggleLabel = Document.get() 92 | .createDivElement(); 93 | toggleLabel.setClassName(VSliderPanel.CLASSNAME + "-icon"); 94 | this.tabElem.appendChild(toggleLabel); 95 | 96 | DOM.sinkEvents(this.tabElem, Event.ONCLICK); 97 | this.wrapperNode.appendChild(this.navigationElem); 98 | 99 | Event.addNativePreviewHandler(this); 100 | } 101 | 102 | private void setMode(final SliderMode sliderMode, final boolean flowInContent) { 103 | if (this.mode == null) { 104 | this.mode = sliderMode; 105 | this.flowInContent = flowInContent; 106 | this.wrapperNode.addClassName("mode-" + this.mode.name() 107 | .toLowerCase()); 108 | this.wrapperNode.addClassName("layout-" + (this.mode.isVertical() ? "vertical" : "horizontal")); 109 | 110 | if (flowInContent) { 111 | this.wrapperNode.addClassName("flow-in-content"); 112 | } 113 | 114 | this.wrapperBaseClassName = this.wrapperNode.getClassName(); 115 | 116 | if (this.mode.equals(SliderMode.BOTTOM) || this.mode.equals(SliderMode.LEFT)) { 117 | // rearrange order contentNode after navigationElem 118 | this.wrapperNode.removeChild(this.contentNode); 119 | this.wrapperNode.appendChild(this.contentNode); 120 | } 121 | } 122 | } 123 | 124 | private void setTabPosition(final SliderTabPosition tabPosition) { 125 | if (this.tabPosition != null) { 126 | this.tabElem.removeClassName("tab-" + tabPosition.name() 127 | .toLowerCase()); 128 | } 129 | this.tabElem.addClassName("tab-" + tabPosition.name() 130 | .toLowerCase()); 131 | this.tabBaseClassName = this.tabElem.getClassName(); 132 | } 133 | 134 | public void configure(final SliderMode sliderMode, final boolean flowInContent, final SliderTabPosition tabPosition, final Integer pixel) { 135 | if (!this.initialized) { 136 | setMode(sliderMode, flowInContent); 137 | setTabPosition(tabPosition); 138 | if (pixel > 0) { 139 | this.componentSize = pixel; 140 | } 141 | this.initialized = true; 142 | } 143 | } 144 | 145 | public void setFixedContentSize(final int pixel) { 146 | this.componentSize = pixel; 147 | } 148 | 149 | public void initialize(final boolean expand, final int tabSize) { 150 | this.expand = expand; 151 | this.tabSize = tabSize; 152 | animateTo(expand, 0, false); 153 | } 154 | 155 | public void setCaption(final String caption, final boolean captionAsHtml) { 156 | String captionContent = caption != null ? caption : ""; 157 | if (!captionAsHtml) { 158 | captionContent = SafeHtmlUtils.htmlEscape(captionContent); 159 | } 160 | this.captionNode.setInnerHTML(captionContent); 161 | } 162 | 163 | public void setExpand(final boolean expand, final boolean animated) { 164 | if (!isEnabled()) { 165 | return; 166 | } 167 | animateTo(expand, animated ? this.animationDuration : 0, true); 168 | } 169 | 170 | public void setAnimationDuration(final int animationDuration) { 171 | this.animationDuration = animationDuration; 172 | } 173 | 174 | public void setAutoCollapseSlider(boolean autoCollapseSlider) { 175 | this.autoCollapseSlider = autoCollapseSlider; 176 | } 177 | 178 | public void setZIndex(int zIndex) { 179 | this.contentNode.getStyle().setZIndex(zIndex); 180 | this.navigationElem.getStyle().setZIndex(zIndex+1); 181 | this.wrapperNode.getStyle().setZIndex(zIndex); 182 | } 183 | 184 | /** 185 | * handel the closed/open className on the TabElement 186 | */ 187 | private void updateTabElemClassName() { 188 | if (this.expand) { 189 | this.tabElem.removeClassName("closed"); 190 | this.tabElem.addClassName("open"); 191 | } 192 | else { 193 | this.tabElem.removeClassName("open"); 194 | this.tabElem.addClassName("closed"); 195 | } 196 | } 197 | 198 | @Override 199 | public void onBrowserEvent(final Event event) { 200 | if (!isEnabled()) { 201 | return; 202 | } 203 | if (event != null && (event.getTypeInt() == Event.ONCLICK)) { 204 | animateTo(!this.expand, this.animationDuration, true); 205 | } 206 | super.onBrowserEvent(event); 207 | } 208 | 209 | /** 210 | * used to log in javascript console 211 | * 212 | * @param message info to get logged 213 | */ 214 | native void consoleLog(final String message) /*-{ 215 | console.log( message ); 216 | }-*/; 217 | 218 | @SuppressWarnings("deprecation") 219 | @Override 220 | protected com.google.gwt.user.client.Element getContainerElement() { 221 | return DOM.asOld(this.contentNode); 222 | } 223 | 224 | public void setToggleListener(final ToggleListener toggleListener) { 225 | this.listener = toggleListener; 226 | } 227 | 228 | private class SliderAnimation extends Animation { 229 | private boolean animateToExpand = false; 230 | 231 | private boolean fireToggleEvent = true; 232 | 233 | public void setAnimateToExpand(final boolean expand, final boolean fireToggleEvent) { 234 | this.animateToExpand = expand; 235 | this.fireToggleEvent = fireToggleEvent; 236 | } 237 | 238 | private void changeSize(final double size) { 239 | if (VSliderPanel.this.mode.isVertical()) { 240 | if (VSliderPanel.this.mode.equals(SliderMode.RIGHT)) { 241 | VSliderPanel.this.contentNode.getStyle() 242 | .setWidth(size, Style.Unit.PX); 243 | 244 | if (VSliderPanel.this.flowInContent) { 245 | // new 246 | VSliderPanel.this.navigationElem.getStyle() 247 | .setLeft(-1 * (size + VSliderPanel.this.tabSize), Style.Unit.PX); 248 | VSliderPanel.this.contentNode.getStyle() 249 | .setLeft(-1 * size, Style.Unit.PX); 250 | } 251 | else { 252 | VSliderPanel.this.navigationElem.getStyle() 253 | .setLeft(-1 * size, Style.Unit.PX); 254 | VSliderPanel.this.contentNode.getStyle() 255 | .setLeft(-1 * size + VSliderPanel.this.tabSize, Style.Unit.PX); 256 | } 257 | } 258 | else { 259 | VSliderPanel.this.contentNode.getStyle() 260 | .setWidth(VSliderPanel.this.componentSize, Style.Unit.PX); 261 | VSliderPanel.this.contentNode.getStyle().setWidth(size, Style.Unit.PX); 262 | VSliderPanel.this.contentNode.getFirstChildElement().getStyle().setPosition(Position.ABSOLUTE); 263 | VSliderPanel.this.contentNode.getFirstChildElement().getStyle().setLeft(-1 * (VSliderPanel.this.componentSize - size), Style.Unit.PX); 264 | 265 | 266 | if (VSliderPanel.this.flowInContent) { 267 | VSliderPanel.this.navigationElem.getStyle() 268 | .setRight(-1 * (size + VSliderPanel.this.tabSize), Style.Unit.PX); 269 | } 270 | else { 271 | VSliderPanel.this.navigationElem.getStyle() 272 | .setRight(-1 * size, Style.Unit.PX); 273 | } 274 | } 275 | } 276 | else { 277 | VSliderPanel.this.contentNode.getStyle() 278 | .setHeight(size, Style.Unit.PX); 279 | if (VSliderPanel.this.mode.equals(SliderMode.BOTTOM)) { 280 | if (VSliderPanel.this.flowInContent) { 281 | // new 282 | VSliderPanel.this.contentNode.getStyle() 283 | .setTop(-1 * size, Style.Unit.PX); 284 | VSliderPanel.this.navigationElem.getStyle() 285 | .setTop(-1 * (size + VSliderPanel.this.tabSize), Style.Unit.PX); 286 | } 287 | else { 288 | VSliderPanel.this.contentNode.getStyle() 289 | .setTop(-1 * size + VSliderPanel.this.tabSize, Style.Unit.PX); 290 | VSliderPanel.this.navigationElem.getStyle() 291 | .setTop(-1 * size, Style.Unit.PX); 292 | } 293 | } 294 | else { 295 | VSliderPanel.this.contentNode.getFirstChildElement() 296 | .getStyle() 297 | .setPosition(Position.ABSOLUTE); 298 | VSliderPanel.this.contentNode.getFirstChildElement() 299 | .getStyle() 300 | .setTop(-1 * (VSliderPanel.this.componentSize - size), Style.Unit.PX); 301 | VSliderPanel.this.navigationElem.getStyle() 302 | .setTop(size, Style.Unit.PX); 303 | } 304 | } 305 | } 306 | 307 | @Override 308 | protected void onUpdate(final double progress) { 309 | changeSize(extractProportionalLength(progress)); 310 | } 311 | 312 | @Override 313 | protected void onStart() { 314 | VSliderPanel.this.contentNode.getStyle() 315 | .setDisplay(Display.BLOCK); 316 | if (VSliderPanel.this.componentSize == null || VSliderPanel.this.componentSize <= 0) { 317 | if (VSliderPanel.this.mode.isVertical()) { 318 | VSliderPanel.this.contentNode.getStyle() 319 | .clearWidth(); 320 | if (VSliderPanel.this.contentNode.getFirstChildElement() != null) { 321 | VSliderPanel.this.componentSize = VSliderPanel.this.contentNode.getFirstChildElement() 322 | .getOffsetWidth(); 323 | } 324 | } 325 | else { 326 | VSliderPanel.this.contentNode.getStyle() 327 | .clearHeight(); 328 | if (VSliderPanel.this.contentNode.getFirstChildElement() != null) { 329 | VSliderPanel.this.componentSize = VSliderPanel.this.contentNode.getFirstChildElement() 330 | .getOffsetHeight(); 331 | } 332 | } 333 | } 334 | }; 335 | 336 | @Override 337 | protected void onComplete() { 338 | VSliderPanel.this.expand = this.animateToExpand; 339 | updateTabElemClassName(); 340 | 341 | if (!VSliderPanel.this.expand) { 342 | changeSize(0); 343 | } 344 | else { 345 | changeSize(VSliderPanel.this.componentSize); 346 | } 347 | 348 | if (VSliderPanel.this.listener != null && this.fireToggleEvent) { 349 | VSliderPanel.this.listener.onToggle(VSliderPanel.this.expand); 350 | } 351 | }; 352 | 353 | private int extractProportionalLength(final double progress) { 354 | if (this.animateToExpand) { 355 | return (int) (VSliderPanel.this.componentSize * progress); 356 | } 357 | else { 358 | return (int) (VSliderPanel.this.componentSize * (1.0 - progress)); 359 | } 360 | } 361 | } 362 | 363 | /** 364 | * run animation with params 365 | * 366 | * @param expand final state 367 | * @param duration milliseconds how long the animation takes 368 | * @param fireToggleEvent should an event get fired afterwards 369 | */ 370 | public void animateTo(final boolean expand, final int duration, final boolean fireToggleEvent) { 371 | 372 | if (this.slideAnimation.isRunning()) 373 | return; 374 | 375 | this.slideAnimation.setAnimateToExpand(expand, fireToggleEvent); 376 | this.slideAnimation.run(duration); 377 | } 378 | 379 | public class ScheduleTimer extends Timer { 380 | private boolean expand, animated; 381 | 382 | @Override 383 | public void run() { 384 | setExpand(this.expand, this.animated); 385 | } 386 | 387 | public void setValues(final boolean expand, final boolean animated) { 388 | this.expand = expand; 389 | this.animated = animated; 390 | } 391 | } 392 | 393 | private ScheduleTimer scheduleTimer; 394 | 395 | /** 396 | * schedule animation with delay 397 | * 398 | * @param expand final state 399 | * @param animated should get animated 400 | * @param delayMillis milliseconds of delayed execution 401 | */ 402 | public void scheduleExpand(final boolean expand, final boolean animated, final int delayMillis) { 403 | if (this.scheduleTimer == null) { 404 | this.scheduleTimer = new ScheduleTimer(); 405 | } 406 | this.scheduleTimer.setValues(expand, animated); 407 | this.scheduleTimer.schedule(delayMillis); 408 | } 409 | 410 | /** 411 | * adds custom styleNames to wrapper 412 | * 413 | * @param styles add styleName to all nodes 414 | */ 415 | public void setStyles(final String styles) { 416 | this.wrapperNode.setClassName(this.wrapperBaseClassName + styles); 417 | this.contentNode.setClassName(VSliderPanel.CLASSNAME + "-content" + styles); 418 | this.navigationElem.setClassName(VSliderPanel.CLASSNAME + "-navigator" + styles); 419 | this.tabElem.setClassName(this.tabBaseClassName + styles); 420 | // to set old open/closed class 421 | updateTabElemClassName(); 422 | } 423 | 424 | /** 425 | * checks whether the event comes from an element within the slider dom tree 426 | * 427 | * @param event NativeEvent 428 | * @return true when events comes from within 429 | */ 430 | private boolean eventTargetsPopup(NativeEvent event) { 431 | EventTarget target = event.getEventTarget(); 432 | if (Element.is(target)) { 433 | return getElement().isOrHasChild(Element.as(target)); 434 | } 435 | return false; 436 | } 437 | 438 | /** 439 | * checks whether the event come's from a elements that lays visually within the slider
440 | * it doesn't lay directly in the dom tree - for example dropdown popups 441 | * 442 | * @param event NativeEvent 443 | * @return true when events comes from within 444 | */ 445 | private boolean eventTargetsInnerElementsPopover(NativeEvent event) { 446 | EventTarget target = event.getEventTarget(); 447 | if (Element.is(target)) { 448 | Element targetElement = Element.as(target); 449 | 450 | int absoluteLeft = targetElement.getAbsoluteLeft(); 451 | int absoluteTop = targetElement.getAbsoluteTop(); 452 | 453 | return contentNode.getAbsoluteLeft() <= absoluteLeft && contentNode.getAbsoluteRight() >= absoluteLeft && contentNode.getAbsoluteTop() <= absoluteTop 454 | && contentNode.getAbsoluteBottom() >= absoluteTop; 455 | } 456 | return false; 457 | } 458 | 459 | @Override 460 | public void onPreviewNativeEvent(NativePreviewEvent event) { 461 | if (autoCollapseSlider && event != null && !event.isCanceled() && expand) { 462 | Event nativeEvent = Event.as(event.getNativeEvent()); 463 | 464 | switch (nativeEvent.getTypeInt()) { 465 | case Event.ONMOUSEDOWN: 466 | case Event.ONTOUCHSTART: 467 | case Event.ONDBLCLICK: 468 | 469 | if (eventTargetsPopup(nativeEvent)) { 470 | return; 471 | } 472 | if (eventTargetsInnerElementsPopover(nativeEvent)) { 473 | return; 474 | } 475 | setExpand(false, true); 476 | } 477 | } 478 | } 479 | 480 | public boolean isEnabled() { 481 | return this.enabled; 482 | } 483 | 484 | public void setEnabled(boolean enabled) { 485 | this.enabled = enabled; 486 | if (!enabled) { 487 | wrapperNode.addClassName("v-disabled"); 488 | tabElem.setAttribute("disabled", "on"); 489 | return; 490 | } 491 | wrapperNode.removeClassName("v-disabled"); 492 | tabElem.removeAttribute("disabled"); 493 | } 494 | 495 | } 496 | --------------------------------------------------------------------------------