001/* 002 * #%L 003 * GwtMaterial 004 * %% 005 * Copyright (C) 2015 - 2017 GwtMaterialDesign 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package gwt.material.design.client.ui; 021 022import com.google.gwt.core.client.GWT; 023import com.google.gwt.core.client.Scheduler; 024import com.google.gwt.user.client.ui.Widget; 025import gwt.material.design.client.js.JsPushpinOptions; 026 027import static gwt.material.design.client.js.JsMaterialElement.$; 028//@formatter:off 029 030/** 031 * Pushpin is our fixed positioning plugin. You can check out our live examples: the fixed Table of Contents on the right. 032 * <h3>UiBinder Usage:</h3> 033 * <p> 034 * <pre> 035 * {@code 036 * // CAN BE CALLED AS A HELPER STATIC CONTEXT 037 * MaterialPushpin.apply(target, source.getOffsetHeight() + 600); 038 * 039 * // INSTANTIATE THE PUSHPIN COMPONENT 040 * MaterialPushpin pushpin = new MaterialPushpin(); 041 * pushpin.setWidget(source); 042 * pushpin.setTop(300.0); 043 * pushpin.setOffset(64.0); 044 * pushpin.setBottom(500.0); 045 * pushpin.apply(); 046 * } 047 * </pre> 048 * 049 * @author kevzlou7979 050 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#pushpin">Material PushPin</a> 051 */ 052public class MaterialPushpin { 053 054 private Widget widget; 055 private JsPushpinOptions options = new JsPushpinOptions(); 056 057 public MaterialPushpin() {} 058 059 /** 060 * Apply the pushpin feature into the target widget 061 */ 062 public void apply() { 063 Scheduler.get().scheduleDeferred(() -> { 064 if (widget != null) { 065 $(widget.getElement()).pushpin(options); 066 } else { 067 GWT.log("Please set your widget before applying the pushpin", new IllegalStateException()); 068 } 069 }); 070 } 071 072 /** 073 * A pushpinned element has 3 states. One above and below the scrolling threshold, 074 * and the pinned state where the element becomes fixed. 075 * 076 * @param widget - Target widget to apply the pushpin feature 077 * @param offset - The offset from the top the element will be fixed at. (Default: 0) 078 */ 079 public static void apply(Widget widget, Double offset) { 080 apply(widget, null, null, offset); 081 } 082 083 /** 084 * A pushpinned element has 3 states. One above and below the scrolling threshold, 085 * and the pinned state where the element becomes fixed. 086 * 087 * @param widget - Target widget to apply the pushpin feature 088 * @param top - The distance in pixels from the top of the page where the element becomes fixed. (Default: 0) 089 * @param offset - The offset from the top the element will be fixed at. (Default: 0) 090 */ 091 public static void apply(Widget widget, Double top, Double offset) { 092 apply(widget, top, null, offset); 093 } 094 095 /** 096 * A pushpinned element has 3 states. One above and below the scrolling threshold, 097 * and the pinned state where the element becomes fixed. 098 * 099 * @param widget - Target widget to apply the pushpin feature 100 * @param top - The distance in pixels from the top of the page where the element becomes fixed. (Default: 0) 101 * @param bottom - The distance in pixels from the top of the page where the elements stops being fixed. (Default: Infinity) 102 * @param offset - The offset from the top the element will be fixed at. (Default: 0) 103 */ 104 public static void apply(Widget widget, Double top, Double bottom, Double offset) { 105 MaterialPushpin pushpin = new MaterialPushpin(); 106 pushpin.setWidget(widget); 107 pushpin.setTop(top); 108 pushpin.setBottom(bottom); 109 pushpin.setOffset(offset); 110 pushpin.apply(); 111 } 112 113 /** 114 * Get the target widget which the pushpin was applied 115 */ 116 public Widget getWidget() { 117 return widget; 118 } 119 120 /** 121 * Set the target widget to apply the pushpin feature 122 */ 123 public void setWidget(Widget widget) { 124 this.widget = widget; 125 } 126 127 /** 128 * Get the offset from the top the element will be fixd at. 129 */ 130 public Double getOffset() { 131 return options.offset; 132 } 133 134 /** 135 * Set the offset from the top the element will be fixed at. (Default: 0) 136 */ 137 public void setOffset(Double offset) { 138 options.offset = (offset != null) ? offset : 0; 139 } 140 141 /** 142 * Get the distance in pixels from the top of the page where the element becomes fixed. (Default: 0) 143 */ 144 public Double getTop() { 145 return options.top; 146 } 147 148 /** 149 * Set the distance in pixels from the top of the page where the element becomes fixed. (Default: 0) 150 */ 151 public void setTop(Double top) { 152 options.top = (top != null) ? top : 0; 153 } 154 155 /** 156 * Get the distance in pixels from the top of the page where the elements stops being fixed. (Default: Infinity) 157 */ 158 public Double getBottom() { 159 return options.bottom; 160 } 161 162 /** 163 * Set the distance in pixels from the top of the page where the elements stops being fixed. (Default: Infinity) 164 */ 165 public void setBottom(Double bottom) { 166 // Avoid overriding the bottom property if it's null, 167 // as it takes "Infinity" as the default value 168 if (bottom != null) { 169 options.bottom = bottom; 170 } 171 } 172}