Add "InfoBar" and undo capability to overview
It allow to show some information to user and Undo his actions. https://bugzilla.gnome.org/show_bug.cgi?id=608933
This commit is contained in:
parent
fa5b0efdb4
commit
0b2eeccd4b
@ -133,6 +133,27 @@ StTooltip {
|
|||||||
|
|
||||||
/* Overlay */
|
/* Overlay */
|
||||||
|
|
||||||
|
.info-bar {
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid #5c5c5c;
|
||||||
|
background: #1e1e1e;
|
||||||
|
color: #cccccc;
|
||||||
|
font-size: 14px;
|
||||||
|
height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-bar-panel {
|
||||||
|
padding: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-bar-link-button {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-bar-link-button:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
.workspaces {
|
.workspaces {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
function AppFavorites() {
|
function AppFavorites() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -61,23 +64,50 @@ AppFavorites.prototype = {
|
|||||||
return appId in this._favorites;
|
return appId in this._favorites;
|
||||||
},
|
},
|
||||||
|
|
||||||
addFavorite: function(appId) {
|
_addFavorite: function(appId) {
|
||||||
if (appId in this._favorites)
|
if (appId in this._favorites)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
let app = Shell.AppSystem.get_default().get_app(appId);
|
let app = Shell.AppSystem.get_default().get_app(appId);
|
||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
let ids = this._getIds();
|
let ids = this._getIds();
|
||||||
ids.push(appId);
|
ids.push(appId);
|
||||||
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
||||||
this._favorites[appId] = app;
|
this._favorites[appId] = app;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
addFavorite: function(appId) {
|
||||||
|
if (!this._addFavorite(appId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let app = Shell.AppSystem.get_default().get_app(appId);
|
||||||
|
|
||||||
|
Main.overview.infoBar.setMessage(_('%s has been added to your favorites.').format(app.get_name()), Lang.bind(this, function () {
|
||||||
|
this._removeFavorite(appId);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeFavorite: function(appId) {
|
||||||
|
if (!appId in this._favorites)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let ids = this._getIds().filter(function (id) { return id != appId; });
|
||||||
|
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeFavorite: function(appId) {
|
removeFavorite: function(appId) {
|
||||||
if (!appId in this._favorites)
|
if (!this._removeFavorite(appId))
|
||||||
return;
|
return;
|
||||||
let ids = this._getIds().filter(function (id) { return id != appId; });
|
|
||||||
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
Main.overview.infoBar.setMessage(_('%s has been removed from your favorites.').format(this._favorites[appId].get_name()),
|
||||||
|
Lang.bind(this, function () {
|
||||||
|
this._addFavorite(appId);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(AppFavorites.prototype);
|
Signals.addSignalMethods(AppFavorites.prototype);
|
||||||
|
@ -9,6 +9,8 @@ const Shell = imports.gi.Shell;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const DocDisplay = imports.ui.docDisplay;
|
const DocDisplay = imports.ui.docDisplay;
|
||||||
@ -74,10 +76,119 @@ const SHADOW_WIDTH = 6;
|
|||||||
|
|
||||||
const NUMBER_OF_SECTIONS_IN_SEARCH = 2;
|
const NUMBER_OF_SECTIONS_IN_SEARCH = 2;
|
||||||
|
|
||||||
|
const INFO_BAR_HIDE_TIMEOUT = 30;
|
||||||
|
|
||||||
let wideScreen = false;
|
let wideScreen = false;
|
||||||
let displayGridColumnWidth = null;
|
let displayGridColumnWidth = null;
|
||||||
let displayGridRowHeight = null;
|
let displayGridRowHeight = null;
|
||||||
|
|
||||||
|
function InfoBar() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoBar.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new St.Bin({ style_class: 'info-bar-panel',
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: false });
|
||||||
|
this._label = new St.Label();
|
||||||
|
this._undo = new St.Button({ label: _('Undo'),
|
||||||
|
style_class: 'info-bar-link-button' });
|
||||||
|
|
||||||
|
let bin = new St.Bin({ style_class: 'info-bar',
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.MIDDLE,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
this.actor.set_child(bin);
|
||||||
|
|
||||||
|
let box = new St.BoxLayout();
|
||||||
|
bin.set_child(box);
|
||||||
|
this._timeoutId = 0;
|
||||||
|
|
||||||
|
box.add(this._label, {'y-fill' : false, 'y-align' : St.Align.MIDDLE});
|
||||||
|
box.add(this._undo);
|
||||||
|
|
||||||
|
this.actor.set_opacity(0);
|
||||||
|
|
||||||
|
this._undoCallback = null;
|
||||||
|
this._undo.connect('clicked', Lang.bind(this, this._onUndoClicked));
|
||||||
|
|
||||||
|
this._overviewWasHidden = false;
|
||||||
|
this._hidingOverviewId = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onUndoClicked: function() {
|
||||||
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
this._timeoutId = 0;
|
||||||
|
|
||||||
|
if (this._undoCallback)
|
||||||
|
this._undoCallback();
|
||||||
|
this.actor.set_opacity(0);
|
||||||
|
this._undoCallback = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_hideDone: function() {
|
||||||
|
this._undoCallback = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_hide: function() {
|
||||||
|
this._overviewWasHidden = false;
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: ANIMATION_TIME,
|
||||||
|
onComplete: this._hideDone,
|
||||||
|
onCompleteScope: this
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onTimeout: function() {
|
||||||
|
this._timeoutId = 0;
|
||||||
|
if (this._overviewWasHidden)
|
||||||
|
this._hide();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onOverviewHiding: function() {
|
||||||
|
if (this._timeoutId == 0)
|
||||||
|
this._hide();
|
||||||
|
else
|
||||||
|
this._overviewWasHidden = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
setMessage: function(text, undoCallback) {
|
||||||
|
if (this._timeoutId)
|
||||||
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
|
||||||
|
if (this._hidingOverviewId == 0) {
|
||||||
|
// Set here, because when constructor is called, overview is null.
|
||||||
|
if (!Main.overview)
|
||||||
|
return;
|
||||||
|
// We don't actually use the ID, it's just a way of tracking whether we've hooked up the signal
|
||||||
|
this._hidingOverviewId = Main.overview.connect('hiding', Lang.bind(this, this._onOverviewHiding));
|
||||||
|
}
|
||||||
|
this._timeout = false;
|
||||||
|
this._overviewWasHidden = false;
|
||||||
|
|
||||||
|
this._label.text = text + ' ';
|
||||||
|
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: ANIMATION_TIME
|
||||||
|
});
|
||||||
|
|
||||||
|
this._timeoutId = Mainloop.timeout_add_seconds(INFO_BAR_HIDE_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||||
|
|
||||||
|
this._undoCallback = undoCallback;
|
||||||
|
if (undoCallback)
|
||||||
|
this._undo.show();
|
||||||
|
else
|
||||||
|
this._undo.hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function Overview() {
|
function Overview() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
@ -87,6 +198,9 @@ Overview.prototype = {
|
|||||||
this._group = new Clutter.Group();
|
this._group = new Clutter.Group();
|
||||||
this._group._delegate = this;
|
this._group._delegate = this;
|
||||||
|
|
||||||
|
this.infoBar = new InfoBar();
|
||||||
|
this._group.add_actor(this.infoBar.actor);
|
||||||
|
|
||||||
this._workspacesViewSwitch = new WorkspacesView.WorkspacesViewSwitch();
|
this._workspacesViewSwitch = new WorkspacesView.WorkspacesViewSwitch();
|
||||||
this._workspacesViewSwitch.connect('view-changed', Lang.bind(this, this._onViewChanged));
|
this._workspacesViewSwitch.connect('view-changed', Lang.bind(this, this._onViewChanged));
|
||||||
|
|
||||||
@ -229,6 +343,10 @@ Overview.prototype = {
|
|||||||
this._dash.sectionArea.height = this._workspacesHeight;
|
this._dash.sectionArea.height = this._workspacesHeight;
|
||||||
this._dash.searchResults.actor.height = this._workspacesHeight;
|
this._dash.searchResults.actor.height = this._workspacesHeight;
|
||||||
|
|
||||||
|
this.infoBar.actor.set_position(displayGridColumnWidth, Panel.PANEL_HEIGHT);
|
||||||
|
this.infoBar.actor.set_size(primary.width - displayGridColumnWidth, this._workspacesY - Panel.PANEL_HEIGHT);
|
||||||
|
this.infoBar.actor.raise_top();
|
||||||
|
|
||||||
// place the 'Add Workspace' button in the bottom row of the grid
|
// place the 'Add Workspace' button in the bottom row of the grid
|
||||||
this._workspacesBarX = this._workspacesX;
|
this._workspacesBarX = this._workspacesX;
|
||||||
this._workspacesBarWidth = primary.width - this._workspacesBarX - WORKSPACE_GRID_PADDING;
|
this._workspacesBarWidth = primary.width - this._workspacesBarX - WORKSPACE_GRID_PADDING;
|
||||||
|
Loading…
Reference in New Issue
Block a user