ibusCandidatePopup: Add pagination buttons

Makes switching candidates pages with pointer clicks possible.

https://bugzilla.gnome.org/show_bug.cgi?id=691902
This commit is contained in:
Rui Matos 2013-02-14 23:36:32 +01:00
parent 6cd1e38425
commit 4f8586d81d
2 changed files with 85 additions and 5 deletions

View File

@ -286,6 +286,7 @@ StScrollBar StButton#vhandle:active {
/* Buttons */ /* Buttons */
.candidate-page-button,
.dash-search-button, .dash-search-button,
.notification-button, .notification-button,
.notification-icon-button, .notification-icon-button,
@ -303,6 +304,7 @@ StScrollBar StButton#vhandle:active {
font-weight: bold; font-weight: bold;
} }
.candidate-page-button:hover,
.dash-search-button:hover, .dash-search-button:hover,
.notification-button:hover, .notification-button:hover,
.notification-icon-button:hover, .notification-icon-button:hover,
@ -322,6 +324,8 @@ StScrollBar StButton#vhandle:active {
border-width: 2px; border-width: 2px;
} }
.candidate-page-button:active,
.candidate-page-button:pressed,
.dash-search-button:active, .dash-search-button:active,
.dash-search-button:pressed, .dash-search-button:pressed,
.notification-button:active, .notification-button:active,
@ -334,6 +338,7 @@ StScrollBar StButton#vhandle:active {
background-gradient-end: rgba(255, 255, 255, 0.2); background-gradient-end: rgba(255, 255, 255, 0.2);
} }
.candidate-page-button:insensitive,
.notification-button:insensitive, .notification-button:insensitive,
.notification-icon-button:insensitive, .notification-icon-button:insensitive,
.modal-dialog-button:insensitive { .modal-dialog-button:insensitive {
@ -2121,6 +2126,31 @@ StScrollBar StButton#vhandle:active {
background-color: rgba(255,255,255,0.2); background-color: rgba(255,255,255,0.2);
} }
.candidate-page-button-box {
height: 2em;
width: 80px;
}
.vertical .candidate-page-button-box {
padding-top: 0.5em;
}
.horizontal .candidate-page-button-box {
padding-left: 0.5em;
}
.candidate-page-button-previous {
border-radius: 4px 0px 0px 4px;
}
.candidate-page-button-next {
border-radius: 0px 4px 4px 0px;
}
.candidate-page-button-icon {
icon-size: 1em;
}
/* Login Dialog */ /* Login Dialog */
.login-dialog-banner { .login-dialog-banner {

View File

@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const IBus = imports.gi.IBus; const IBus = imports.gi.IBus;
const Lang = imports.lang; const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St; const St = imports.gi.St;
const BoxPointer = imports.ui.boxpointer; const BoxPointer = imports.ui.boxpointer;
@ -27,6 +28,25 @@ const CandidateArea = new Lang.Class({
this.actor.add(box); this.actor.add(box);
} }
this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous' });
this._previousButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' });
this._buttonBox.add(this._previousButton, { expand: true });
this._nextButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-next' });
this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' });
this._buttonBox.add(this._nextButton, { expand: true });
this.actor.add(this._buttonBox);
this._previousButton.connect('clicked', Lang.bind(this, function() {
this.emit('previous-page');
}));
this._nextButton.connect('clicked', Lang.bind(this, function() {
this.emit('next-page');
}));
this._orientation = -1; this._orientation = -1;
this._cursorPosition = 0; this._cursorPosition = 0;
}, },
@ -37,10 +57,19 @@ const CandidateArea = new Lang.Class({
this._orientation = orientation; this._orientation = orientation;
if (this._orientation == IBus.Orientation.HORIZONTAL) if (this._orientation == IBus.Orientation.HORIZONTAL) {
this.actor.vertical = false; this.actor.vertical = false;
else // VERTICAL || SYSTEM this.actor.remove_style_class_name('vertical');
this.actor.add_style_class_name('horizontal');
this._previousButton.child.icon_name = 'go-previous-symbolic';
this._nextButton.child.icon_name = 'go-next-symbolic';
} else { // VERTICAL || SYSTEM
this.actor.vertical = true; this.actor.vertical = true;
this.actor.add_style_class_name('vertical');
this.actor.remove_style_class_name('horizontal');
this._previousButton.child.icon_name = 'go-up-symbolic';
this._nextButton.child.icon_name = 'go-down-symbolic';
}
}, },
setCandidates: function(indexes, candidates, orientation, cursorPosition, cursorVisible) { setCandidates: function(indexes, candidates, orientation, cursorPosition, cursorVisible) {
@ -63,7 +92,18 @@ const CandidateArea = new Lang.Class({
if (cursorVisible) if (cursorVisible)
this._candidateBoxes[cursorPosition].add_style_pseudo_class('selected'); this._candidateBoxes[cursorPosition].add_style_pseudo_class('selected');
}, },
updateButtons: function(wrapsAround, page, nPages) {
if (nPages < 2) {
this._buttonBox.hide();
return;
}
this._buttonBox.show();
this._previousButton.reactive = wrapsAround || page > 0;
this._nextButton.reactive = wrapsAround || page < nPages - 1;
},
}); });
Signals.addSignalMethods(CandidateArea.prototype);
const CandidatePopup = new Lang.Class({ const CandidatePopup = new Lang.Class({
Name: 'CandidatePopup', Name: 'CandidatePopup',
@ -75,7 +115,7 @@ const CandidatePopup = new Lang.Class({
this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP); this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
this._boxPointer.actor.visible = false; this._boxPointer.actor.visible = false;
this._boxPointer.actor.style_class = 'candidate-popup-boxpointer'; this._boxPointer.actor.style_class = 'candidate-popup-boxpointer';
Main.uiGroup.add_actor(this._boxPointer.actor); Main.layoutManager.addChrome(this._boxPointer.actor);
let box = new St.BoxLayout({ style_class: 'candidate-popup-content', let box = new St.BoxLayout({ style_class: 'candidate-popup-content',
vertical: true }); vertical: true });
@ -92,6 +132,13 @@ const CandidatePopup = new Lang.Class({
this._candidateArea = new CandidateArea(); this._candidateArea = new CandidateArea();
box.add(this._candidateArea.actor); box.add(this._candidateArea.actor);
this._candidateArea.connect('previous-page', Lang.bind(this, function() {
this._panelService.page_up();
}));
this._candidateArea.connect('next-page', Lang.bind(this, function() {
this._panelService.page_down();
}));
this._panelService = null; this._panelService = null;
}, },
@ -149,12 +196,14 @@ const CandidatePopup = new Lang.Class({
this._candidateArea.actor.visible = visible; this._candidateArea.actor.visible = visible;
this._updateVisibility(); this._updateVisibility();
let nCandidates = lookupTable.get_number_of_candidates();
let cursorPos = lookupTable.get_cursor_pos(); let cursorPos = lookupTable.get_cursor_pos();
let pageSize = lookupTable.get_page_size(); let pageSize = lookupTable.get_page_size();
let nPages = Math.ceil(nCandidates / pageSize);
let page = ((cursorPos == 0) ? 0 : Math.floor(cursorPos / pageSize)); let page = ((cursorPos == 0) ? 0 : Math.floor(cursorPos / pageSize));
let startIndex = page * pageSize; let startIndex = page * pageSize;
let endIndex = Math.min((page + 1) * pageSize, let endIndex = Math.min((page + 1) * pageSize, nCandidates);
lookupTable.get_number_of_candidates());
let indexes = []; let indexes = [];
let indexLabel; let indexLabel;
for (let i = 0; indexLabel = lookupTable.get_label(i); ++i) for (let i = 0; indexLabel = lookupTable.get_label(i); ++i)
@ -169,6 +218,7 @@ const CandidatePopup = new Lang.Class({
lookupTable.get_orientation(), lookupTable.get_orientation(),
cursorPos % pageSize, cursorPos % pageSize,
lookupTable.is_cursor_visible()); lookupTable.is_cursor_visible());
this._candidateArea.updateButtons(lookupTable.is_round(), page, nPages);
})); }));
panelService.connect('show-lookup-table', panelService.connect('show-lookup-table',
Lang.bind(this, function(ps) { Lang.bind(this, function(ps) {