Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (14.5 kB)

1
/*
2
 * Copyright 2010 Google Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
 * use this file except in compliance with the License. You may obtain a copy of
6
 * the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
 * License for the specific language governing permissions and limitations under
14
 * the License.
15
 */
16
package com.google.gwt.user.cellview.client;
17

    
18
import com.google.gwt.core.client.GWT;
19
import com.google.gwt.event.dom.client.ClickEvent;
20
import com.google.gwt.event.dom.client.ClickHandler;
21
import com.google.gwt.i18n.client.NumberFormat;
22
import com.google.gwt.resources.client.ClientBundle;
23
import com.google.gwt.resources.client.CssResource;
24
import com.google.gwt.resources.client.ImageResource;
25
import com.google.gwt.resources.client.ImageResource.ImageOptions;
26
import com.google.gwt.uibinder.client.UiConstructor;
27
import com.google.gwt.user.client.ui.HTML;
28
import com.google.gwt.user.client.ui.HasVerticalAlignment;
29
import com.google.gwt.user.client.ui.HorizontalPanel;
30
import com.google.gwt.user.client.ui.Image;
31
import com.google.gwt.view.client.HasRows;
32
import com.google.gwt.view.client.Range;
33

    
34
/**
35
 * A pager for controlling a {@link HasRows} that only supports simple page
36
 * navigation.
37
 *
38
 * <p>
39
 * <h3>Example</h3>
40
 * {@example com.google.gwt.examples.cellview.SimplePagerExample}
41
 * </p>
42
 */
43
public class GssSimplePager extends AbstractPager {
44

    
45
  /**
46
   * A ClientBundle that provides images for this widget.
47
   */
48
  public static interface Resources extends ClientBundle {
49

    
50
    /**
51
     * The image used to skip ahead multiple pages.
52
     */
53
    @ImageOptions(flipRtl = true)
54
    ImageResource simplePagerFastForward();
55

    
56
    /**
57
     * The disabled "fast forward" image.
58
     */
59
    @ImageOptions(flipRtl = true)
60
    ImageResource simplePagerFastForwardDisabled();
61

    
62
    /**
63
     * The image used to go to the first page.
64
     */
65
    @ImageOptions(flipRtl = true)
66
    ImageResource simplePagerFirstPage();
67

    
68
    /**
69
     * The disabled first page image.
70
     */
71
    @ImageOptions(flipRtl = true)
72
    ImageResource simplePagerFirstPageDisabled();
73

    
74
    /**
75
     * The image used to go to the last page.
76
     */
77
    @ImageOptions(flipRtl = true)
78
    ImageResource simplePagerLastPage();
79

    
80
    /**
81
     * The disabled last page image.
82
     */
83
    @ImageOptions(flipRtl = true)
84
    ImageResource simplePagerLastPageDisabled();
85

    
86
    /**
87
     * The image used to go to the next page.
88
     */
89
    @ImageOptions(flipRtl = true)
90
    ImageResource simplePagerNextPage();
91

    
92
    /**
93
     * The disabled next page image.
94
     */
95
    @ImageOptions(flipRtl = true)
96
    ImageResource simplePagerNextPageDisabled();
97

    
98
    /**
99
     * The image used to go to the previous page.
100
     */
101
    @ImageOptions(flipRtl = true)
102
    ImageResource simplePagerPreviousPage();
103

    
104
    /**
105
     * The disabled previous page image.
106
     */
107
    @ImageOptions(flipRtl = true)
108
    ImageResource simplePagerPreviousPageDisabled();
109

    
110
    /**
111
     * The styles used in this widget.
112
     */
113
    @Source("SimplePager.css")
114
    Style simplePagerStyle();
115
  }
116

    
117
  /**
118
   * Styles used by this widget.
119
   */
120
  public static interface Style extends CssResource {
121

    
122
    /**
123
     * Applied to buttons.
124
     */
125
    String button();
126

    
127
    /**
128
     * Applied to disabled buttons.
129
     */
130
    String disabledButton();
131

    
132
    /**
133
     * Applied to the details text.
134
     */
135
    String pageDetails();
136
  }
137

    
138
  /**
139
   * The location of the text relative to the paging buttons.
140
   */
141
  public static enum TextLocation {
142
    CENTER, LEFT, RIGHT;
143
  }
144

    
145
  private static int DEFAULT_FAST_FORWARD_ROWS = 1000;
146
  private static Resources DEFAULT_RESOURCES;
147

    
148
  private static Resources getDefaultResources() {
149
    if (DEFAULT_RESOURCES == null) {
150
      DEFAULT_RESOURCES = GWT.create(Resources.class);
151
    }
152
    return DEFAULT_RESOURCES;
153
  }
154

    
155
  private final Image fastForward;
156

    
157
  private final int fastForwardRows;
158

    
159
  private final Image firstPage;
160

    
161
  /**
162
   * We use an {@link HTML} so we can embed the loading image.
163
   */
164
  private final HTML label = new HTML();
165

    
166
  private final Image lastPage;
167

    
168
  /**
169
   * Set to true when the next and last buttons are disabled.
170
   */
171
  private boolean nextDisabled;
172

    
173
  private final Image nextPage;
174

    
175
  /**
176
   * Set to true when the prev and first buttons are disabled.
177
   */
178
  private boolean prevDisabled;
179

    
180
  private final Image prevPage;
181

    
182
  /**
183
   * The {@link Resources} used by this widget.
184
   */
185
  private final Resources resources;
186

    
187
  /**
188
   * The {@link Style} used by this widget.
189
   */
190
  private final Style style;
191

    
192
  /**
193
   * Construct a {@link GssSimplePager} with the default text location.
194
   */
195
  public GssSimplePager() {
196
    this(TextLocation.CENTER);
197
  }
198

    
199
  /**
200
   * Construct a {@link GssSimplePager} with the specified text location.
201
   *
202
   * @param location the location of the text relative to the buttons
203
   */
204
  @UiConstructor
205
  // Hack for Google I/O demo
206
  public GssSimplePager(TextLocation location) {
207
    this(location, getDefaultResources(), false, DEFAULT_FAST_FORWARD_ROWS,
208
        true);
209
  }
210

    
211
  /**
212
   * Construct a {@link GssSimplePager} with the specified resources.
213
   *
214
   * @param location the location of the text relative to the buttons
215
   * @param resources the {@link Resources} to use
216
   * @param showFastForwardButton if true, show a fast-forward button that
217
   *          advances by a larger increment than a single page
218
   * @param fastForwardRows the number of rows to jump when fast forwarding
219
   * @param showLastPageButton if true, show a button to go the the last page
220
   */
221
  public GssSimplePager(TextLocation location, Resources resources,
222
      boolean showFastForwardButton, final int fastForwardRows,
223
      boolean showLastPageButton) {
224
    this.resources = resources;
225
    this.fastForwardRows = fastForwardRows;
226
    this.style = resources.simplePagerStyle();
227
    this.style.ensureInjected();
228

    
229
    // Create the buttons.
230
    firstPage = new Image(resources.simplePagerFirstPage());
231
    firstPage.addClickHandler(new ClickHandler() {
232
      public void onClick(ClickEvent event) {
233
        firstPage();
234
      }
235
    });
236
    nextPage = new Image(resources.simplePagerNextPage());
237
    nextPage.addClickHandler(new ClickHandler() {
238
      public void onClick(ClickEvent event) {
239
        nextPage();
240
      }
241
    });
242
    prevPage = new Image(resources.simplePagerPreviousPage());
243
    prevPage.addClickHandler(new ClickHandler() {
244
      public void onClick(ClickEvent event) {
245
        previousPage();
246
      }
247
    });
248
    if (showLastPageButton) {
249
      lastPage = new Image(resources.simplePagerLastPage());
250
      lastPage.addClickHandler(new ClickHandler() {
251
        public void onClick(ClickEvent event) {
252
          lastPage();
253
        }
254
      });
255
    } else {
256
      lastPage = null;
257
    }
258
    if (showFastForwardButton) {
259
      fastForward = new Image(resources.simplePagerFastForward());
260
      fastForward.addClickHandler(new ClickHandler() {
261
        public void onClick(ClickEvent event) {
262
          setPage(getPage() + getFastForwardPages());
263
        }
264
      });
265
    } else {
266
      fastForward = null;
267
    }
268

    
269
    // Construct the widget.
270
    HorizontalPanel layout = new HorizontalPanel();
271
    layout.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
272
    initWidget(layout);
273
    if (location == TextLocation.RIGHT) {
274
      layout.add(label);
275
    }
276
    layout.add(firstPage);
277
    layout.add(prevPage);
278
    if (location == TextLocation.CENTER) {
279
      layout.add(label);
280
    }
281
    layout.add(nextPage);
282
    if (showFastForwardButton) {
283
      layout.add(fastForward);
284
    }
285
    if (showLastPageButton) {
286
      layout.add(lastPage);
287
    }
288
    if (location == TextLocation.LEFT) {
289
      layout.add(label);
290
    }
291

    
292
    // Add style names to the cells.
293
    firstPage.getElement().getParentElement().addClassName(style.button());
294
    prevPage.getElement().getParentElement().addClassName(style.button());
295
    label.getElement().getParentElement().addClassName(style.pageDetails());
296
    nextPage.getElement().getParentElement().addClassName(style.button());
297
    if (showFastForwardButton) {
298
      fastForward.getElement().getParentElement().addClassName(style.button());
299
    }
300
    if (showLastPageButton) {
301
      lastPage.getElement().getParentElement().addClassName(style.button());
302
    }
303

    
304
    // Disable the buttons by default.
305
    setDisplay(null);
306
  }
307

    
308
  @Override
309
  public void firstPage() {
310
    super.firstPage();
311
  }
312

    
313
  @Override
314
  public int getPage() {
315
    return super.getPage();
316
  }
317

    
318
  @Override
319
  public int getPageCount() {
320
    return super.getPageCount();
321
  }
322

    
323
  @Override
324
  public boolean hasNextPage() {
325
    return super.hasNextPage();
326
  }
327

    
328
  @Override
329
  public boolean hasNextPages(int pages) {
330
    return super.hasNextPages(pages);
331
  }
332

    
333
  @Override
334
  public boolean hasPage(int index) {
335
    return super.hasPage(index);
336
  }
337

    
338
  @Override
339
  public boolean hasPreviousPage() {
340
    return super.hasPreviousPage();
341
  }
342

    
343
  @Override
344
  public boolean hasPreviousPages(int pages) {
345
    return super.hasPreviousPages(pages);
346
  }
347

    
348
  @Override
349
  public void lastPage() {
350
    super.lastPage();
351
  }
352

    
353
  @Override
354
  public void lastPageStart() {
355
    super.lastPageStart();
356
  }
357

    
358
  @Override
359
  public void nextPage() {
360
    super.nextPage();
361
  }
362

    
363
  @Override
364
  public void previousPage() {
365
    super.previousPage();
366
  }
367

    
368
  @Override
369
  public void setDisplay(HasRows display) {
370
    // Enable or disable all buttons.
371
    boolean disableButtons = (display == null);
372
    setFastForwardDisabled(disableButtons);
373
    setNextPageButtonsDisabled(disableButtons);
374
    setPrevPageButtonsDisabled(disableButtons);
375
    super.setDisplay(display);
376
  }
377

    
378
  @Override
379
  public void setPage(int index) {
380
    super.setPage(index);
381
  }
382

    
383
  @Override
384
  public void setPageSize(int pageSize) {
385
    super.setPageSize(pageSize);
386
  }
387

    
388
  @Override
389
  public void setPageStart(int index) {
390
    super.setPageStart(index);
391
  }
392

    
393
  /**
394
   * Let the page know that the table is loading. Call this method to clear all
395
   * data from the table and hide the current range when new data is being
396
   * loaded into the table.
397
   */
398
  public void startLoading() {
399
    getDisplay().setRowCount(0, true);
400
    label.setHTML("");
401
  }
402

    
403
  /**
404
   * Get the text to display in the pager that reflects the state of the pager.
405
   *
406
   * @return the text
407
   */
408
  protected String createText() {
409
    // Default text is 1 based.
410
    NumberFormat formatter = NumberFormat.getFormat("#,###");
411
    HasRows display = getDisplay();
412
    Range range = display.getVisibleRange();
413
    int pageStart = range.getStart() + 1;
414
    int pageSize = range.getLength();
415
    int dataSize = display.getRowCount();
416
    int endIndex = Math.min(dataSize, pageStart + pageSize - 1);
417
    endIndex = Math.max(pageStart, endIndex);
418
    boolean exact = display.isRowCountExact();
419
    return formatter.format(pageStart) + "-" + formatter.format(endIndex)
420
        + (exact ? " of " : " of over ") + formatter.format(dataSize);
421
  }
422

    
423
  @Override
424
  protected void onRangeOrRowCountChanged() {
425
    HasRows display = getDisplay();
426
    label.setText(createText());
427

    
428
    // Update the prev and first buttons.
429
    setPrevPageButtonsDisabled(!hasPreviousPage());
430

    
431
    // Update the next and last buttons.
432
    if (isRangeLimited() || !display.isRowCountExact()) {
433
      setNextPageButtonsDisabled(!hasNextPage());
434
      setFastForwardDisabled(!hasNextPages(getFastForwardPages()));
435
    }
436
  }
437

    
438
  /**
439
   * Check if the next button is disabled. Visible for testing.
440
   */
441
  boolean isNextButtonDisabled() {
442
    return nextDisabled;
443
  }
444

    
445
  /**
446
   * Check if the previous button is disabled. Visible for testing.
447
   */
448
  boolean isPreviousButtonDisabled() {
449
    return prevDisabled;
450
  }
451

    
452
  /**
453
   * Get the number of pages to fast forward based on the current page size.
454
   *
455
   * @return the number of pages to fast forward
456
   */
457
  private int getFastForwardPages() {
458
    int pageSize = getPageSize();
459
    return pageSize > 0 ? fastForwardRows / pageSize : 0;
460
  }
461

    
462
  /**
463
   * Enable or disable the fast forward button.
464
   *
465
   * @param disabled true to disable, false to enable
466
   */
467
  private void setFastForwardDisabled(boolean disabled) {
468
    if (fastForward == null) {
469
      return;
470
    }
471
    if (disabled) {
472
      fastForward.setResource(resources.simplePagerFastForwardDisabled());
473
      fastForward.getElement().getParentElement().addClassName(
474
          style.disabledButton());
475
    } else {
476
      fastForward.setResource(resources.simplePagerFastForward());
477
      fastForward.getElement().getParentElement().removeClassName(
478
          style.disabledButton());
479
    }
480
  }
481

    
482
  /**
483
   * Enable or disable the next page buttons.
484
   *
485
   * @param disabled true to disable, false to enable
486
   */
487
  private void setNextPageButtonsDisabled(boolean disabled) {
488
    if (disabled == nextDisabled) {
489
      return;
490
    }
491

    
492
    nextDisabled = disabled;
493
    if (disabled) {
494
      nextPage.setResource(resources.simplePagerNextPageDisabled());
495
      nextPage.getElement().getParentElement().addClassName(
496
          style.disabledButton());
497
      if (lastPage != null) {
498
        lastPage.setResource(resources.simplePagerLastPageDisabled());
499
        lastPage.getElement().getParentElement().addClassName(
500
            style.disabledButton());
501
      }
502
    } else {
503
      nextPage.setResource(resources.simplePagerNextPage());
504
      nextPage.getElement().getParentElement().removeClassName(
505
          style.disabledButton());
506
      if (lastPage != null) {
507
        lastPage.setResource(resources.simplePagerLastPage());
508
        lastPage.getElement().getParentElement().removeClassName(
509
            style.disabledButton());
510
      }
511
    }
512
  }
513

    
514
  /**
515
   * Enable or disable the previous page buttons.
516
   *
517
   * @param disabled true to disable, false to enable
518
   */
519
  private void setPrevPageButtonsDisabled(boolean disabled) {
520
    if (disabled == prevDisabled) {
521
      return;
522
    }
523

    
524
    prevDisabled = disabled;
525
    if (disabled) {
526
      firstPage.setResource(resources.simplePagerFirstPageDisabled());
527
      firstPage.getElement().getParentElement().addClassName(
528
          style.disabledButton());
529
      prevPage.setResource(resources.simplePagerPreviousPageDisabled());
530
      prevPage.getElement().getParentElement().addClassName(
531
          style.disabledButton());
532
    } else {
533
      firstPage.setResource(resources.simplePagerFirstPage());
534
      firstPage.getElement().getParentElement().removeClassName(
535
          style.disabledButton());
536
      prevPage.setResource(resources.simplePagerPreviousPage());
537
      prevPage.getElement().getParentElement().removeClassName(
538
          style.disabledButton());
539
    }
540
  }
541
}