summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/demo/VaadinTunesLayout.java
blob: 695c4dc2cfcb4e7015066a2aa8030f1405f728bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
package com.vaadin.demo;

import java.util.Random;

import com.vaadin.Application;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.Slider;
import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

/**
 * Sample application layout, similar (almost identical) to Apple iTunes.
 * 
 * @author IT Mill Ltd.
 * 
 */
@SuppressWarnings("serial")
public class VaadinTunesLayout extends Application {

    @Override
    public void init() {

        /*
         * We'll build the whole UI here, since the application will not contain
         * any logic. Otherwise it would be more practical to separate parts of
         * the UI into different classes and methods.
         */

        // Main (browser) window, needed in all Vaadin applications
        final Window root = new Window("VaadinTunes");

        /*
         * We'll attach the window to the browser view already here, so we won't
         * forget it later.
         */
        setMainWindow(root);

        root
                .showNotification(
                        "This is an example of how you can do layouts in Vaadin.<br/>It is not a working sound player.",
                        Notification.TYPE_HUMANIZED_MESSAGE);

        // Our root window contains one VerticalLayout by default, let's make
        // sure it's 100% sized, and remove unwanted margins
        root.getLayout().setSizeFull();
        root.getLayout().setMargin(false);

        // Top area, containing playback and volume controls, play status, view
        // modes and search
        HorizontalLayout top = new HorizontalLayout();
        top.setWidth("100%");
        top.setMargin(false, true, false, true); // Enable horizontal margins
        top.setSpacing(true);

        // Let's attach that one straight away too
        root.addComponent(top);

        // Create the placeholders for all the components in the top area
        HorizontalLayout playback = new HorizontalLayout();
        HorizontalLayout volume = new HorizontalLayout();
        HorizontalLayout status = new HorizontalLayout();
        HorizontalLayout viewmodes = new HorizontalLayout();
        ComboBox search = new ComboBox();

        // Add the components and align them properly
        top.addComponent(playback);
        top.addComponent(volume);
        top.addComponent(status);
        top.addComponent(viewmodes);
        top.addComponent(search);
        top.setComponentAlignment(playback, "middle");
        top.setComponentAlignment(volume, "middle");
        top.setComponentAlignment(status, "middle center");
        top.setComponentAlignment(viewmodes, "middle");
        top.setComponentAlignment(search, "middle");

        /*
         * We want our status area to expand if the user resizes the root
         * window, and we want it to accommodate as much space as there is
         * available. All other components in the top layout should stay fixed
         * sized, so we don't need to specify any expand ratios for them (they
         * will automatically revert to zero after the following line).
         */
        top.setExpandRatio(status, 1.0F);

        // Playback controls
        Button prev = new Button("Previous");
        Button play = new Button("Play/pause");
        Button next = new Button("Next");
        playback.addComponent(prev);
        playback.addComponent(play);
        playback.addComponent(next);
        // Set spacing between the buttons
        playback.setSpacing(true);

        // Volume controls
        Button mute = new Button("mute");
        Slider vol = new Slider();
        vol.setOrientation(Slider.ORIENTATION_HORIZONTAL);
        vol.setWidth("100px");
        Button max = new Button("max");
        volume.addComponent(mute);
        volume.addComponent(vol);
        volume.addComponent(max);

        // Status area
        status.setWidth("80%");
        status.setSpacing(true);

        Button toggleVisualization = new Button("Mode");
        Label timeFromStart = new Label("0:00");

        // We'll need another layout to show currently playing track and
        // progress
        VerticalLayout trackDetails = new VerticalLayout();
        trackDetails.setWidth("100%");
        Label track = new Label("Track Name");
        Label album = new Label("Album Name - Artist");
        track.setWidth(null);
        album.setWidth(null);
        Slider progress = new Slider();
        progress.setOrientation(Slider.ORIENTATION_HORIZONTAL);
        progress.setWidth("100%");
        trackDetails.addComponent(track);
        trackDetails.addComponent(album);
        trackDetails.addComponent(progress);
        trackDetails.setComponentAlignment(track, "center");
        trackDetails.setComponentAlignment(album, "center");

        Label timeToEnd = new Label("-4:46");
        Button jumpToTrack = new Button("Show");

        // Place all components to the status layout and align them properly
        status.addComponent(toggleVisualization);
        status.setComponentAlignment(toggleVisualization, "middle");
        status.addComponent(timeFromStart);
        status.setComponentAlignment(timeFromStart, "bottom");
        status.addComponent(trackDetails);
        status.addComponent(timeToEnd);
        status.setComponentAlignment(timeToEnd, "bottom");
        status.addComponent(jumpToTrack);
        status.setComponentAlignment(jumpToTrack, "middle");

        // Then remember to specify the expand ratio
        status.setExpandRatio(trackDetails, 1.0F);

        // View mode buttons
        Button viewAsTable = new Button("Table");
        Button viewAsGrid = new Button("Grid");
        Button coverflow = new Button("Coverflow");
        viewmodes.addComponent(viewAsTable);
        viewmodes.addComponent(viewAsGrid);
        viewmodes.addComponent(coverflow);

        /*
         * That covers the top bar. Now let's move on to the sidebar and track
         * listing
         */

        // We'll need one splitpanel to separate the sidebar and track listing
        SplitPanel bottom = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL);
        root.addComponent(bottom);

        // The splitpanel is by default 100% x 100%, but we'll need to adjust
        // our main window layout to accomodate the height
        ((VerticalLayout) root.getLayout()).setExpandRatio(bottom, 1.0F);

        // Give the sidebar less space than the listing
        bottom.setSplitPosition(200, SplitPanel.UNITS_PIXELS);

        // Let's add some content to the sidebar
        // First, we need a layout to but all components in
        VerticalLayout sidebar = new VerticalLayout();
        sidebar.setSizeFull();
        bottom.setFirstComponent(sidebar);

        /*
         * Then we need some labels and buttons, and an album cover image The
         * labels and buttons go into their own vertical layout, since we want
         * the 'sidebar' layout to be expanding (cover image in the bottom).
         * VerticalLayout is by default 100% wide.
         */
        VerticalLayout selections = new VerticalLayout();
        Label library = new Label("Library");
        Button music = new Button("Music");
        music.setWidth("100%");

        Label store = new Label("Store");
        Button vaadinTunesStore = new Button("VaadinTunes Store");
        vaadinTunesStore.setWidth("100%");
        Button purchased = new Button("Purchased");
        purchased.setWidth("100%");

        Label playlists = new Label("Playlists");
        Button genius = new Button("Geniues");
        genius.setWidth("100%");
        Button recent = new Button("Recently Added");
        recent.setWidth("100%");

        // Lets add them to the 'selections' layout
        selections.addComponent(library);
        selections.addComponent(music);
        selections.addComponent(store);
        selections.addComponent(vaadinTunesStore);
        selections.addComponent(purchased);
        selections.addComponent(playlists);
        selections.addComponent(genius);
        selections.addComponent(recent);

        // Then add the selections to the sidebar, and set it expanding
        sidebar.addComponent(selections);
        sidebar.setExpandRatio(selections, 1.0F);

        // Then comes the cover artwork (we'll add the actual image in the
        // themeing section)
        Embedded cover = new Embedded("Currently Playing");
        sidebar.addComponent(cover);

        /*
         * And lastly, we need the track listing table It should fill the whole
         * left side of our bottom layout
         */
        Table listing = new Table();
        listing.setSizeFull();
        listing.setSelectable(true);
        bottom.setSecondComponent(listing);

        // Add the table headers
        listing.addContainerProperty("Name", String.class, "");
        listing.addContainerProperty("Time", String.class, "0:00");
        listing.addContainerProperty("Artist", String.class, "");
        listing.addContainerProperty("Album", String.class, "");
        listing.addContainerProperty("Genre", String.class, "");
        listing.addContainerProperty("Rating", NativeSelect.class,
                new NativeSelect());

        // Lets populate the table with random data
        String[] tracks = new String[] { "Red Flag", "Millstone",
                "Not The Sun", "Breath", "Here We Are", "Deep Heaven",
                "Her Voice Resides", "Natural Tan", "End It All", "Kings",
                "Daylight Slaving", "Mad Man", "Resolve", "Teargas",
                "African Air", "Passing Bird" };
        String[] times = new String[] { "4:12", "6:03", "5:43", "4:32", "3:42",
                "4:45", "2:56", "9:34", "2:10", "3:44", "5:49", "6:30", "5:18",
                "7:42", "3:13", "2:52" };
        String[] artists = new String[] { "Billy Talent", "Brand New",
                "Breaking Benjamin", "Becoming The Archetype",
                "Bullet For My Valentine", "Chasing Victory", "Chimaira",
                "Danko Jones", "Deadlock", "Deftones", "From Autumn To Ashes",
                "Haste The Day", "Four Year Strong", "In Flames", "Kemopetrol",
                "John Legend" };
        String[] albums = new String[] { "Once Again", "The Caitiff Choir",
                "The Devil And God", "Light Grenades", "Dicthonomy",
                "Back In Black", "Dreamer", "Come Clarity", "Year Zero",
                "Frames", "Fortress", "Phobia", "The Poison", "Manifesto",
                "White Pony", "The Big Dirty" };
        String[] genres = new String[] { "Rock", "Metal", "Hardcore", "Indie",
                "Pop", "Alternative", "Blues", "Jazz", "Hip Hop", "Electronica" };
        for (int i = 0; i < 1000; i++) {
            NativeSelect s = new NativeSelect();
            s.addItem("1 star");
            s.addItem("2 stars");
            s.addItem("3 stars");
            s.addItem("4 stars");
            s.addItem("5 stars");
            s.select(new Random().nextInt(5) + " stars");
            listing.addItem(new Object[] {
                    tracks[new Random().nextInt(tracks.length - 1)],
                    times[new Random().nextInt(times.length - 1)],
                    artists[new Random().nextInt(artists.length - 1)],
                    albums[new Random().nextInt(albums.length - 1)],
                    genres[new Random().nextInt(genres.length - 1)], s }, i);
        }

        // We'll align the track time column to right as well
        listing.setColumnAlignment("Time", Table.ALIGN_RIGHT);

        // TODO the footer

        // Now what's left to do? Themeing of course.
        setTheme("vaadintunes");

        /*
         * Let's give a namespace to our application window. This way, if
         * someone uses the same theme for different applications, we don't get
         * unwanted style conflicts.
         */
        root.setStyleName("tTunes");

        top.setStyleName("top");
        top.setHeight("75px"); // Same as the background image height

        playback.setStyleName("playback");
        playback.setMargin(false, true, false, false); // Add right-side margin
        play.setStyleName("play");
        next.setStyleName("next");
        prev.setStyleName("prev");
        playback.setComponentAlignment(prev, "middle");
        playback.setComponentAlignment(next, "middle");

        volume.setStyleName("volume");
        mute.setStyleName("mute");
        max.setStyleName("max");
        vol.setWidth("78px");

        status.setStyleName("status");
        status.setMargin(true);
        status.setHeight("46px"); // Height of the background image

        toggleVisualization.setStyleName("toggle-vis");
        jumpToTrack.setStyleName("jump");

        viewAsTable.setStyleName("viewmode-table");
        viewAsGrid.setStyleName("viewmode-grid");
        coverflow.setStyleName("viewmode-coverflow");

        sidebar.setStyleName("sidebar");

        music.setStyleName("selected");

        cover.setSource(new ThemeResource("images/album-cover.jpg"));
        // Because this is an image, it will retain it's aspect ratio
        cover.setWidth("100%");
    }

}