Statistics
| Branch: | Tag: | Revision:

root / web_client / src / com / google / gwt / user / cellview / client / GssSimplePager.java @ 58777026

History | View | Annotate | Download (15.4 kB)

1
/*
2
 * Copyright 2011 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35
package com.google.gwt.user.cellview.client;
36

    
37
import com.google.gwt.core.client.GWT;
38
import com.google.gwt.event.dom.client.ClickEvent;
39
import com.google.gwt.event.dom.client.ClickHandler;
40
import com.google.gwt.i18n.client.NumberFormat;
41
import com.google.gwt.resources.client.ClientBundle;
42
import com.google.gwt.resources.client.CssResource;
43
import com.google.gwt.resources.client.ImageResource;
44
import com.google.gwt.resources.client.ImageResource.ImageOptions;
45
import com.google.gwt.uibinder.client.UiConstructor;
46
import com.google.gwt.user.client.ui.HTML;
47
import com.google.gwt.user.client.ui.HasVerticalAlignment;
48
import com.google.gwt.user.client.ui.HorizontalPanel;
49
import com.google.gwt.user.client.ui.Image;
50
import com.google.gwt.view.client.HasRows;
51
import com.google.gwt.view.client.Range;
52

    
53
/**
54
 * A pager for controlling a {@link HasRows} that only supports simple page
55
 * navigation.
56
 *
57
 * <p>
58
 * <h3>Example</h3>
59
 * {@example com.google.gwt.examples.cellview.SimplePagerExample}
60
 * </p>
61
 */
62
public class GssSimplePager extends AbstractPager {
63

    
64
  /**
65
   * A ClientBundle that provides images for this widget.
66
   */
67
  public static interface Resources extends ClientBundle {
68

    
69
    /**
70
     * The image used to skip ahead multiple pages.
71
     */
72
    @ImageOptions(flipRtl = true)
73
    ImageResource simplePagerFastForward();
74

    
75
    /**
76
     * The disabled "fast forward" image.
77
     */
78
    @ImageOptions(flipRtl = true)
79
    ImageResource simplePagerFastForwardDisabled();
80

    
81
    /**
82
     * The image used to go to the first page.
83
     */
84
    @ImageOptions(flipRtl = true)
85
    ImageResource simplePagerFirstPage();
86

    
87
    /**
88
     * The disabled first page image.
89
     */
90
    @ImageOptions(flipRtl = true)
91
    ImageResource simplePagerFirstPageDisabled();
92

    
93
    /**
94
     * The image used to go to the last page.
95
     */
96
    @ImageOptions(flipRtl = true)
97
    ImageResource simplePagerLastPage();
98

    
99
    /**
100
     * The disabled last page image.
101
     */
102
    @ImageOptions(flipRtl = true)
103
    ImageResource simplePagerLastPageDisabled();
104

    
105
    /**
106
     * The image used to go to the next page.
107
     */
108
    @ImageOptions(flipRtl = true)
109
    ImageResource simplePagerNextPage();
110

    
111
    /**
112
     * The disabled next page image.
113
     */
114
    @ImageOptions(flipRtl = true)
115
    ImageResource simplePagerNextPageDisabled();
116

    
117
    /**
118
     * The image used to go to the previous page.
119
     */
120
    @ImageOptions(flipRtl = true)
121
    ImageResource simplePagerPreviousPage();
122

    
123
    /**
124
     * The disabled previous page image.
125
     */
126
    @ImageOptions(flipRtl = true)
127
    ImageResource simplePagerPreviousPageDisabled();
128

    
129
    /**
130
     * The styles used in this widget.
131
     */
132
    @Source("SimplePager.css")
133
    Style simplePagerStyle();
134
  }
135

    
136
  /**
137
   * Styles used by this widget.
138
   */
139
  public static interface Style extends CssResource {
140

    
141
    /**
142
     * Applied to buttons.
143
     */
144
    String button();
145

    
146
    /**
147
     * Applied to disabled buttons.
148
     */
149
    String disabledButton();
150

    
151
    /**
152
     * Applied to the details text.
153
     */
154
    String pageDetails();
155
  }
156

    
157
  /**
158
   * The location of the text relative to the paging buttons.
159
   */
160
  public static enum TextLocation {
161
    CENTER, LEFT, RIGHT;
162
  }
163

    
164
  private static int DEFAULT_FAST_FORWARD_ROWS = 1000;
165
  private static Resources DEFAULT_RESOURCES;
166

    
167
  private static Resources getDefaultResources() {
168
    if (DEFAULT_RESOURCES == null) {
169
      DEFAULT_RESOURCES = GWT.create(Resources.class);
170
    }
171
    return DEFAULT_RESOURCES;
172
  }
173

    
174
  private final Image fastForward;
175

    
176
  private final int fastForwardRows;
177

    
178
  private final Image firstPage;
179

    
180
  /**
181
   * We use an {@link HTML} so we can embed the loading image.
182
   */
183
  private final HTML label = new HTML();
184

    
185
  private final Image lastPage;
186

    
187
  /**
188
   * Set to true when the next and last buttons are disabled.
189
   */
190
  private boolean nextDisabled;
191

    
192
  private final Image nextPage;
193

    
194
  /**
195
   * Set to true when the prev and first buttons are disabled.
196
   */
197
  private boolean prevDisabled;
198

    
199
  private final Image prevPage;
200

    
201
  /**
202
   * The {@link Resources} used by this widget.
203
   */
204
  private final Resources resources;
205

    
206
  /**
207
   * The {@link Style} used by this widget.
208
   */
209
  private final Style style;
210

    
211
  /**
212
   * Construct a {@link GssSimplePager} with the default text location.
213
   */
214
  public GssSimplePager() {
215
    this(TextLocation.CENTER);
216
  }
217

    
218
  /**
219
   * Construct a {@link GssSimplePager} with the specified text location.
220
   *
221
   * @param location the location of the text relative to the buttons
222
   */
223
  @UiConstructor
224
  // Hack for Google I/O demo
225
  public GssSimplePager(TextLocation location) {
226
    this(location, getDefaultResources(), false, DEFAULT_FAST_FORWARD_ROWS,
227
        true);
228
  }
229

    
230
  /**
231
   * Construct a {@link GssSimplePager} with the specified resources.
232
   *
233
   * @param location the location of the text relative to the buttons
234
   * @param resources the {@link Resources} to use
235
   * @param showFastForwardButton if true, show a fast-forward button that
236
   *          advances by a larger increment than a single page
237
   * @param fastForwardRows the number of rows to jump when fast forwarding
238
   * @param showLastPageButton if true, show a button to go the the last page
239
   */
240
  public GssSimplePager(TextLocation location, Resources resources,
241
      boolean showFastForwardButton, final int fastForwardRows,
242
      boolean showLastPageButton) {
243
    this.resources = resources;
244
    this.fastForwardRows = fastForwardRows;
245
    this.style = resources.simplePagerStyle();
246
    this.style.ensureInjected();
247

    
248
    // Create the buttons.
249
    firstPage = new Image(resources.simplePagerFirstPage());
250
    firstPage.addClickHandler(new ClickHandler() {
251
      public void onClick(ClickEvent event) {
252
        firstPage();
253
      }
254
    });
255
    nextPage = new Image(resources.simplePagerNextPage());
256
    nextPage.addClickHandler(new ClickHandler() {
257
      public void onClick(ClickEvent event) {
258
        nextPage();
259
      }
260
    });
261
    prevPage = new Image(resources.simplePagerPreviousPage());
262
    prevPage.addClickHandler(new ClickHandler() {
263
      public void onClick(ClickEvent event) {
264
        previousPage();
265
      }
266
    });
267
    if (showLastPageButton) {
268
      lastPage = new Image(resources.simplePagerLastPage());
269
      lastPage.addClickHandler(new ClickHandler() {
270
        public void onClick(ClickEvent event) {
271
          lastPage();
272
        }
273
      });
274
    } else {
275
      lastPage = null;
276
    }
277
    if (showFastForwardButton) {
278
      fastForward = new Image(resources.simplePagerFastForward());
279
      fastForward.addClickHandler(new ClickHandler() {
280
        public void onClick(ClickEvent event) {
281
          setPage(getPage() + getFastForwardPages());
282
        }
283
      });
284
    } else {
285
      fastForward = null;
286
    }
287

    
288
    // Construct the widget.
289
    HorizontalPanel layout = new HorizontalPanel();
290
    layout.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
291
    initWidget(layout);
292
    if (location == TextLocation.RIGHT) {
293
      layout.add(label);
294
    }
295
    layout.add(firstPage);
296
    layout.add(prevPage);
297
    if (location == TextLocation.CENTER) {
298
      layout.add(label);
299
    }
300
    layout.add(nextPage);
301
    if (showFastForwardButton) {
302
      layout.add(fastForward);
303
    }
304
    if (showLastPageButton) {
305
      layout.add(lastPage);
306
    }
307
    if (location == TextLocation.LEFT) {
308
      layout.add(label);
309
    }
310

    
311
    // Add style names to the cells.
312
    firstPage.getElement().getParentElement().addClassName(style.button());
313
    prevPage.getElement().getParentElement().addClassName(style.button());
314
    label.getElement().getParentElement().addClassName(style.pageDetails());
315
    nextPage.getElement().getParentElement().addClassName(style.button());
316
    if (showFastForwardButton) {
317
      fastForward.getElement().getParentElement().addClassName(style.button());
318
    }
319
    if (showLastPageButton) {
320
      lastPage.getElement().getParentElement().addClassName(style.button());
321
    }
322

    
323
    // Disable the buttons by default.
324
    setDisplay(null);
325
  }
326

    
327
  @Override
328
  public void firstPage() {
329
    super.firstPage();
330
  }
331

    
332
  @Override
333
  public int getPage() {
334
    return super.getPage();
335
  }
336

    
337
  @Override
338
  public int getPageCount() {
339
    return super.getPageCount();
340
  }
341

    
342
  @Override
343
  public boolean hasNextPage() {
344
    return super.hasNextPage();
345
  }
346

    
347
  @Override
348
  public boolean hasNextPages(int pages) {
349
    return super.hasNextPages(pages);
350
  }
351

    
352
  @Override
353
  public boolean hasPage(int index) {
354
    return super.hasPage(index);
355
  }
356

    
357
  @Override
358
  public boolean hasPreviousPage() {
359
    return super.hasPreviousPage();
360
  }
361

    
362
  @Override
363
  public boolean hasPreviousPages(int pages) {
364
    return super.hasPreviousPages(pages);
365
  }
366

    
367
  @Override
368
  public void lastPage() {
369
    super.lastPage();
370
  }
371

    
372
  @Override
373
  public void lastPageStart() {
374
    super.lastPageStart();
375
  }
376

    
377
  @Override
378
  public void nextPage() {
379
    super.nextPage();
380
  }
381

    
382
  @Override
383
  public void previousPage() {
384
    super.previousPage();
385
  }
386

    
387
  @Override
388
  public void setDisplay(HasRows display) {
389
    // Enable or disable all buttons.
390
    boolean disableButtons = (display == null);
391
    setFastForwardDisabled(disableButtons);
392
    setNextPageButtonsDisabled(disableButtons);
393
    setPrevPageButtonsDisabled(disableButtons);
394
    super.setDisplay(display);
395
  }
396

    
397
  @Override
398
  public void setPage(int index) {
399
    super.setPage(index);
400
  }
401

    
402
  @Override
403
  public void setPageSize(int pageSize) {
404
    super.setPageSize(pageSize);
405
  }
406

    
407
  @Override
408
  public void setPageStart(int index) {
409
    super.setPageStart(index);
410
  }
411

    
412
  /**
413
   * Let the page know that the table is loading. Call this method to clear all
414
   * data from the table and hide the current range when new data is being
415
   * loaded into the table.
416
   */
417
  public void startLoading() {
418
    getDisplay().setRowCount(0, true);
419
    label.setHTML("");
420
  }
421

    
422
  /**
423
   * Get the text to display in the pager that reflects the state of the pager.
424
   *
425
   * @return the text
426
   */
427
  protected String createText() {
428
    // Default text is 1 based.
429
    NumberFormat formatter = NumberFormat.getFormat("#,###");
430
    HasRows display = getDisplay();
431
    Range range = display.getVisibleRange();
432
    int pageStart = range.getStart() + 1;
433
    int pageSize = range.getLength();
434
    int dataSize = display.getRowCount();
435
    int endIndex = Math.min(dataSize, pageStart + pageSize - 1);
436
    endIndex = Math.max(pageStart, endIndex);
437
    boolean exact = display.isRowCountExact();
438
    return formatter.format(pageStart) + "-" + formatter.format(endIndex)
439
        + (exact ? " of " : " of over ") + formatter.format(dataSize);
440
  }
441

    
442
  @Override
443
  protected void onRangeOrRowCountChanged() {
444
    HasRows display = getDisplay();
445
    label.setText(createText());
446

    
447
    // Update the prev and first buttons.
448
    setPrevPageButtonsDisabled(!hasPreviousPage());
449

    
450
    // Update the next and last buttons.
451
    if (isRangeLimited() || !display.isRowCountExact()) {
452
      setNextPageButtonsDisabled(!hasNextPage());
453
      setFastForwardDisabled(!hasNextPages(getFastForwardPages()));
454
    }
455
  }
456

    
457
  /**
458
   * Check if the next button is disabled. Visible for testing.
459
   */
460
  boolean isNextButtonDisabled() {
461
    return nextDisabled;
462
  }
463

    
464
  /**
465
   * Check if the previous button is disabled. Visible for testing.
466
   */
467
  boolean isPreviousButtonDisabled() {
468
    return prevDisabled;
469
  }
470

    
471
  /**
472
   * Get the number of pages to fast forward based on the current page size.
473
   *
474
   * @return the number of pages to fast forward
475
   */
476
  private int getFastForwardPages() {
477
    int pageSize = getPageSize();
478
    return pageSize > 0 ? fastForwardRows / pageSize : 0;
479
  }
480

    
481
  /**
482
   * Enable or disable the fast forward button.
483
   *
484
   * @param disabled true to disable, false to enable
485
   */
486
  private void setFastForwardDisabled(boolean disabled) {
487
    if (fastForward == null) {
488
      return;
489
    }
490
    if (disabled) {
491
      fastForward.setResource(resources.simplePagerFastForwardDisabled());
492
      fastForward.getElement().getParentElement().addClassName(
493
          style.disabledButton());
494
    } else {
495
      fastForward.setResource(resources.simplePagerFastForward());
496
      fastForward.getElement().getParentElement().removeClassName(
497
          style.disabledButton());
498
    }
499
  }
500

    
501
  /**
502
   * Enable or disable the next page buttons.
503
   *
504
   * @param disabled true to disable, false to enable
505
   */
506
  private void setNextPageButtonsDisabled(boolean disabled) {
507
    if (disabled == nextDisabled) {
508
      return;
509
    }
510

    
511
    nextDisabled = disabled;
512
    if (disabled) {
513
      nextPage.setResource(resources.simplePagerNextPageDisabled());
514
      nextPage.getElement().getParentElement().addClassName(
515
          style.disabledButton());
516
      if (lastPage != null) {
517
        lastPage.setResource(resources.simplePagerLastPageDisabled());
518
        lastPage.getElement().getParentElement().addClassName(
519
            style.disabledButton());
520
      }
521
    } else {
522
      nextPage.setResource(resources.simplePagerNextPage());
523
      nextPage.getElement().getParentElement().removeClassName(
524
          style.disabledButton());
525
      if (lastPage != null) {
526
        lastPage.setResource(resources.simplePagerLastPage());
527
        lastPage.getElement().getParentElement().removeClassName(
528
            style.disabledButton());
529
      }
530
    }
531
  }
532

    
533
  /**
534
   * Enable or disable the previous page buttons.
535
   *
536
   * @param disabled true to disable, false to enable
537
   */
538
  private void setPrevPageButtonsDisabled(boolean disabled) {
539
    if (disabled == prevDisabled) {
540
      return;
541
    }
542

    
543
    prevDisabled = disabled;
544
    if (disabled) {
545
      firstPage.setResource(resources.simplePagerFirstPageDisabled());
546
      firstPage.getElement().getParentElement().addClassName(
547
          style.disabledButton());
548
      prevPage.setResource(resources.simplePagerPreviousPageDisabled());
549
      prevPage.getElement().getParentElement().addClassName(
550
          style.disabledButton());
551
    } else {
552
      firstPage.setResource(resources.simplePagerFirstPage());
553
      firstPage.getElement().getParentElement().removeClassName(
554
          style.disabledButton());
555
      prevPage.setResource(resources.simplePagerPreviousPage());
556
      prevPage.getElement().getParentElement().removeClassName(
557
          style.disabledButton());
558
    }
559
  }
560
}