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:
Maxim Ermilov 2010-02-09 01:50:50 +03:00
parent fa5b0efdb4
commit 0b2eeccd4b
3 changed files with 175 additions and 6 deletions

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;