001    package org.gwtbootstrap3.client.ui.base.mixin;
002    
003    /*
004     * #%L
005     * GwtBootstrap3
006     * %%
007     * Copyright (C) 2013 GwtBootstrap3
008     * %%
009     * Licensed under the Apache License, Version 2.0 (the "License");
010     * you may not use this file except in compliance with the License.
011     * You may obtain a copy of the License at
012     * 
013     *      http://www.apache.org/licenses/LICENSE-2.0
014     * 
015     * Unless required by applicable law or agreed to in writing, software
016     * distributed under the License is distributed on an "AS IS" BASIS,
017     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018     * See the License for the specific language governing permissions and
019     * limitations under the License.
020     * #L%
021     */
022    
023    import org.gwtbootstrap3.client.ui.Icon;
024    import org.gwtbootstrap3.client.ui.base.ComplexWidget;
025    import org.gwtbootstrap3.client.ui.base.HasIcon;
026    import org.gwtbootstrap3.client.ui.base.HasIconPosition;
027    import org.gwtbootstrap3.client.ui.constants.IconFlip;
028    import org.gwtbootstrap3.client.ui.constants.IconPosition;
029    import org.gwtbootstrap3.client.ui.constants.IconRotate;
030    import org.gwtbootstrap3.client.ui.constants.IconSize;
031    import org.gwtbootstrap3.client.ui.constants.IconType;
032    import org.gwtbootstrap3.client.ui.html.Text;
033    
034    import com.google.gwt.core.client.Scheduler;
035    import com.google.gwt.user.client.ui.HasText;
036    
037    /**
038     * Mixin for Widgets that have text and an optional icon.
039     *
040     * @author Sven Jacobs
041     */
042    public class IconTextMixin<T extends ComplexWidget & HasText & HasIcon & HasIconPosition> implements
043            HasText, HasIcon, HasIconPosition {
044    
045        private final T widget;
046        private final Text text = new Text();
047        private final Text separator = new Text(" ");
048        private Icon icon;
049        private IconType iconType;
050        private IconPosition iconPosition = IconPosition.LEFT;
051        private IconSize iconSize = IconSize.NONE;
052        private IconFlip iconFlip = IconFlip.NONE;
053        private IconRotate iconRotate = IconRotate.NONE;
054        private boolean iconMuted = false;
055        private boolean iconSpin = false;
056        private boolean iconBordered = false;
057        private boolean iconLight = false;
058        private boolean iconFixedWidth = false;
059    
060        public IconTextMixin(final T widget) {
061            this.widget = widget;
062        }
063    
064        public void addTextWidgetToParent() {
065            widget.add(text);
066        }
067    
068        @Override
069        public void setText(final String text) {
070            this.text.setText(text);
071        }
072    
073        @Override
074        public String getText() {
075            return text.getText();
076        }
077    
078        @Override
079        public void setIcon(final IconType iconType) {
080            this.iconType = iconType;
081            render();
082        }
083    
084        @Override
085        public IconType getIcon() {
086            return icon == null ? null : icon.getType();
087        }
088    
089        @Override
090        public void setIconPosition(final IconPosition iconPosition) {
091            this.iconPosition = iconPosition;
092            render();
093        }
094    
095        @Override
096        public IconPosition getIconPosition() {
097            return iconPosition;
098        }
099    
100        @Override
101        public void setIconSize(final IconSize iconSize) {
102            this.iconSize = iconSize;
103            render();
104        }
105    
106        @Override
107        public IconSize getIconSize() {
108            return iconSize;
109        }
110    
111        @Override
112        public void setIconFlip(final IconFlip iconFlip) {
113            this.iconFlip = iconFlip;
114            render();
115        }
116    
117        @Override
118        public IconFlip getIconFlip() {
119            return iconFlip;
120        }
121    
122        @Override
123        public void setIconRotate(final IconRotate iconRotate) {
124            this.iconRotate = iconRotate;
125            render();
126        }
127    
128        @Override
129        public IconRotate getIconRotate() {
130            return iconRotate;
131        }
132    
133        @Override
134        public void setIconBordered(final boolean iconBordered) {
135            this.iconBordered = iconBordered;
136            render();
137        }
138    
139        @Override
140        public boolean isIconBordered() {
141            return iconBordered;
142        }
143    
144        @Override
145        public void setIconMuted(final boolean iconMuted) {
146            this.iconMuted = iconMuted;
147            render();
148        }
149    
150        @Override
151        public boolean isIconMuted() {
152            return iconMuted;
153        }
154    
155        @Override
156        public void setIconLight(final boolean iconLight) {
157            this.iconLight = iconLight;
158            render();
159        }
160    
161        @Override
162        public boolean isIconLight() {
163            return iconLight;
164        }
165    
166        @Override
167        public void setIconSpin(final boolean iconSpin) {
168            this.iconSpin = iconSpin;
169            render();
170        }
171    
172        @Override
173        public boolean isIconSpin() {
174            return iconSpin;
175        }
176    
177        @Override
178        public void setIconFixedWidth(final boolean iconFixedWidth) {
179            this.iconFixedWidth = iconFixedWidth;
180            render();
181        }
182    
183        @Override
184        public boolean isIconFixedWidth() {
185            return iconFixedWidth;
186        }
187    
188        private void render() {
189            // We defer to make sure the elements are available to manipulate their positions
190            Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
191                @Override
192                public void execute() {
193                    if (text.isAttached()) {
194                        text.removeFromParent();
195                    }
196                    if (separator.isAttached()) {
197                        separator.removeFromParent();
198                    }
199    
200                    if (icon != null) {
201                        icon.removeFromParent();
202                    }
203    
204                    icon = new Icon();
205                    icon.setType(iconType);
206                    icon.setSize(iconSize);
207                    icon.setFlip(iconFlip);
208                    icon.setRotate(iconRotate);
209                    icon.setMuted(iconMuted);
210                    icon.setSpin(iconSpin);
211                    icon.setBorder(iconBordered);
212                    icon.setLight(iconLight);
213                    icon.setFixedWidth(iconFixedWidth);
214    
215                    // Since we are dealing with Icon/Text, we can insert them at the right position
216                    // Helps on widgets like ButtonDropDown, where it has a caret added
217                    int position = 0;
218    
219                    if (iconPosition == IconPosition.LEFT) {
220                        widget.insert(icon, position++);
221                        widget.insert(separator, position++);
222                    }
223    
224                    if (text.getText() != null && text.getText().length() > 0) {
225                        widget.insert(text, position);
226                    }
227    
228                    if (iconPosition == IconPosition.RIGHT) {
229                        widget.insert(separator, position++);
230                        widget.insert(icon, position);
231                    }
232                }
233            });
234        }
235    }