viewSelector: Replace tab system with pages

The old tab system is no longer a good fit for the current design, so
replace most of the abstractions with a simpler page system.

https://bugzilla.gnome.org/show_bug.cgi?id=682109
This commit is contained in:
Joost Verdoorn 2012-06-22 00:52:56 +02:00 committed by Florian Müllner
parent c267a7a7f9
commit 8c40ded498
2 changed files with 69 additions and 163 deletions

View File

@ -648,16 +648,8 @@ StButton.popup-menu-item:insensitive {
spacing: 1em; spacing: 1em;
} }
#viewSelectorTabBar {
padding: 1em;
}
/* Search Box */ /* Search Box */
#searchArea {
padding: 0px 24px;
}
#searchEntry { #searchEntry {
border-radius: 17px; border-radius: 17px;
width: 250px; width: 250px;
@ -668,26 +660,6 @@ StButton.popup-menu-item:insensitive {
color: #8d8f8a; color: #8d8f8a;
} }
/* View Tabs */
.view-tab-title {
color: #888a85;
font-size: 12pt;
font-weight: bold;
padding: 0px 0.75em;
height: 1.5em;
}
.view-tab-title:hover {
color: #bbb;
}
.view-tab-title:selected {
color: #000000;
background-color: #c2c7cd;
border-radius: 0.25em;
}
/* Search Results */ /* Search Results */
#searchResults { #searchResults {

View File

@ -20,83 +20,6 @@ const Tweener = imports.ui.tweener;
const Wanda = imports.ui.wanda; const Wanda = imports.ui.wanda;
const WorkspacesView = imports.ui.workspacesView; const WorkspacesView = imports.ui.workspacesView;
const BaseTab = new Lang.Class({
Name: 'BaseTab',
_init: function(titleActor, pageActor, name, a11yIcon) {
this.title = titleActor;
this.page = new St.Bin({ child: pageActor,
x_align: St.Align.START,
y_align: St.Align.START,
x_fill: true,
y_fill: true,
style_class: 'view-tab-page' });
if (this.title.can_focus) {
Main.ctrlAltTabManager.addGroup(this.title, name, a11yIcon);
} else {
Main.ctrlAltTabManager.addGroup(this.page, name, a11yIcon,
{ proxy: this.title,
focusCallback: Lang.bind(this, this._a11yFocus) });
}
this.visible = false;
},
show: function(animate) {
this.visible = true;
this.page.show();
if (!animate)
return;
this.page.opacity = 0;
Tweener.addTween(this.page,
{ opacity: 255,
time: 0.1,
transition: 'easeOutQuad' });
},
hide: function() {
this.visible = false;
Tweener.addTween(this.page,
{ opacity: 0,
time: 0.1,
transition: 'easeOutQuad',
onComplete: Lang.bind(this,
function() {
this.page.hide();
})
});
},
_a11yFocus: function() {
this._activate();
this.page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
_activate: function() {
this.emit('activated');
}
});
Signals.addSignalMethods(BaseTab.prototype);
const ViewTab = new Lang.Class({
Name: 'ViewTab',
Extends: BaseTab,
_init: function(id, label, pageActor, a11yIcon) {
this.id = id;
let titleActor = new St.Button({ label: label,
style_class: 'view-tab-title' });
titleActor.connect('clicked', Lang.bind(this, this._activate));
this.parent(titleActor, pageActor, label, a11yIcon);
}
});
const ViewSelector = new Lang.Class({ const ViewSelector = new Lang.Class({
Name: 'ViewSelector', Name: 'ViewSelector',
@ -106,24 +29,14 @@ const ViewSelector = new Lang.Class({
vertical: true }); vertical: true });
this._showAppsButton = showAppsButton; this._showAppsButton = showAppsButton;
this._showAppsButton.connect('notify::checked', Lang.bind(this, this._showAppsButton.connect('notify::checked', Lang.bind(this, this._onShowAppsButtonToggled));
function() {
if (this._showAppsButton.checked)
this._switchTab(this._appsTab);
else
this._switchTab(this._windowsTab);
}));
// The page area holds the tab pages. Every page is given the
// area's full allocation, so that the pages would appear on top
// of each other if the inactive ones weren't hidden.
this._pageArea = new Shell.Stack(); this._pageArea = new Shell.Stack();
this.actor.add(this._pageArea, { x_fill: true, this.actor.add(this._pageArea, { x_fill: true,
y_fill: true, y_fill: true,
expand: true }); expand: true });
this._tabs = []; this._activePage = null;
this._activeTab = null;
this.active = false; this.active = false;
this._searchPending = false; this._searchPending = false;
@ -158,16 +71,16 @@ const ViewSelector = new Lang.Class({
this._capturedEventId = 0; this._capturedEventId = 0;
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay(); this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
this._windowsTab = new ViewTab('windows', _("Windows"), this._workspacesDisplay.actor, 'text-x-generic'); this._workspacesPage = this._addPage(this._workspacesDisplay.actor, null,
this._addViewTab(this._windowsTab); _("Windows"), 'text-x-generic');
let appView = new AppDisplay.AllAppDisplay(); this._appDisplay = new AppDisplay.AllAppDisplay();
this._appsTab = new ViewTab('applications', _("Applications"), appView.actor, 'system-run'); this._appsPage = this._addPage(this._appDisplay.actor, null,
this._addViewTab(this._appsTab); _("Applications"), 'system-run');
this._searchResults = new SearchDisplay.SearchResults(this._searchSystem); this._searchResults = new SearchDisplay.SearchResults(this._searchSystem);
this._searchTab = new BaseTab(new St.Bin(), this._searchResults.actor, _("Search"), 'edit-find'); this._searchPage = this._addPage(this._searchResults.actor, this._entry,
this._addTab(this._searchTab); _("Search"), 'edit-find');
// Default search providers // Default search providers
// Wanda comes obviously first // Wanda comes obviously first
@ -228,10 +141,16 @@ const ViewSelector = new Lang.Class({
}, },
show: function() { show: function() {
this._activePage = this._workspacesPage;
this._appsPage.hide();
this._searchPage.hide();
this._workspacesDisplay.show(); this._workspacesDisplay.show();
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows()) if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
Main.overview.fadeOutDesktop(); Main.overview.fadeOutDesktop();
this._showPage(this._workspacesPage);
}, },
zoomFromOverview: function() { zoomFromOverview: function() {
@ -245,47 +164,62 @@ const ViewSelector = new Lang.Class({
this._workspacesDisplay.hide(); this._workspacesDisplay.hide();
}, },
_addTab: function(tab) { _addPage: function(actor, a11yFocus, name, a11yIcon) {
tab.page.hide(); let page = new St.Bin({ child: actor,
this._pageArea.add_actor(tab.page); x_align: St.Align.START,
tab.connect('activated', Lang.bind(this, function(tab) { y_align: St.Align.START,
this._switchTab(tab); x_fill: true,
})); y_fill: true });
if (a11yFocus)
Main.ctrlAltTabManager.addGroup(a11yFocus, name, a11yIcon);
else
Main.ctrlAltTabManager.addGroup(actor, name, a11yIcon,
{ proxy: this.actor,
focusCallback: Lang.bind(this,
function() {
this._a11yFocusPage(page);
})
});;
this._pageArea.add_actor(page);
return page
}, },
_addViewTab: function(viewTab) { _showPage: function(page) {
this._tabs.push(viewTab); if(page == this._activePage)
this._addTab(viewTab);
},
_switchTab: function(tab) {
let firstSwitch = this._activeTab == null;
if (this._activeTab && this._activeTab.visible) {
if (this._activeTab == tab)
return; return;
this._activeTab.hide();
if(this._activePage) {
Tweener.addTween(this._activePage,
{ opacity: 0,
time: 0.1,
transition: 'easeOutQuad',
onComplete: Lang.bind(this,
function() {
this._activePage.hide();
this._activePage = page;
})
});
} }
if (tab != this._searchTab) { page.show();
this._activeTab = tab; Tweener.addTween(page,
if (this._searchTab.visible) { { opacity: 255,
this._searchTab.hide(); time: 0.1,
} transition: 'easeOutQuad'
} });
// Only fade when switching between tabs,
// not when setting the initially selected one.
if (!tab.visible)
tab.show(!firstSwitch);
}, },
switchTab: function(id) { _a11yFocusPage: function(page) {
for (let i = 0; i < this._tabs.length; i++) this._showAppsButton.checked = page == this._appsPage;
if (this._tabs[i].id == id) { page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
this._switchTab(this._tabs[i]); },
break;
} _onShowAppsButtonToggled: function() {
if (this.active)
this.reset();
else
this._showPage(this._showAppsButton.checked ? this._appsPage
: this._workspacesPage);
}, },
_resetShowAppsButton: function() { _resetShowAppsButton: function() {
@ -307,10 +241,10 @@ const ViewSelector = new Lang.Class({
this.startSearch(event); this.startSearch(event);
} else if (!this.active) { } else if (!this.active) {
if (symbol == Clutter.Tab) { if (symbol == Clutter.Tab) {
this._activeTab.page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return true; return true;
} else if (symbol == Clutter.ISO_Left_Tab) { } else if (symbol == Clutter.ISO_Left_Tab) {
this._activeTab.page.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false); this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false);
return true; return true;
} }
} }
@ -318,7 +252,8 @@ const ViewSelector = new Lang.Class({
}, },
_searchCancelled: function() { _searchCancelled: function() {
this._switchTab(this._activeTab); this._showPage(this._showAppsButton.checked ? this._appsPage
: this._workspacesPage);
// Leave the entry focused when it doesn't have any text; // Leave the entry focused when it doesn't have any text;
// when replacing a selected search term, Clutter emits // when replacing a selected search term, Clutter emits
@ -393,7 +328,6 @@ const ViewSelector = new Lang.Class({
this.reset(); this.reset();
})); }));
} }
this._switchTab(this._searchTab);
} else { } else {
if (this._iconClickedId > 0) if (this._iconClickedId > 0)
this._entry.disconnect(this._iconClickedId); this._entry.disconnect(this._iconClickedId);
@ -479,7 +413,7 @@ const ViewSelector = new Lang.Class({
let text = this._text.get_text().replace(/^\s+/g, '').replace(/\s+$/g, ''); let text = this._text.get_text().replace(/^\s+/g, '').replace(/\s+$/g, '');
this._searchResults.doSearch(text); this._searchResults.doSearch(text);
return false; this._showPage(this._searchPage);
}, },
addSearchProvider: function(provider) { addSearchProvider: function(provider) {