appDisplay: Show a dot when application is running

Show a dot in running applications.
Design request.
This commit is contained in:
Carlos Soriano 2014-10-16 19:51:30 +02:00
parent c5daf63976
commit 8891261dea
5 changed files with 102 additions and 37 deletions

View File

@ -492,7 +492,11 @@ StScrollBar {
}
}
.dash-item-container > StWidget {
padding: 4px 8px;
}
.dash-label { //osd tooltip
border-radius: 7px;
padding: 4px 12px;
@ -561,6 +565,12 @@ StScrollBar {
}
}
.app-well-app-running-dot { //running apps indicator
width: 10px; height: 3px;
background-color: $selected_bg_color;
margin-bottom: 2px; //FIXME will happen :)
}
%icon_tile {
border-radius: 4px;

View File

@ -1399,6 +1399,9 @@ StScrollBar {
width: 24px;
height: 24px; }
.dash-item-container > StWidget {
padding: 4px 8px; }
.dash-label {
border-radius: 7px;
padding: 4px 12px;
@ -1468,6 +1471,12 @@ StScrollBar {
border-image: none;
background-image: none; }
.app-well-app-running-dot {
width: 10px;
height: 3px;
background-color: #215d9c;
margin-bottom: 2px; }
.search-provider-icon,
.list-search-result, .app-well-app > .overview-icon,
.show-apps > .overview-icon,

View File

@ -1517,13 +1517,33 @@ const AppIcon = new Lang.Class({
this.id = app.get_id();
this.name = app.get_name();
this.actor = new St.Button({ style_class: 'app-well-app',
// We need to make it track_hover so dash item can connect to
// the hover signal of the actor in _hookupLabel to call
// shouldShowTooltip when hovered.
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
reactive: true,
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
can_focus: true,
x_fill: true,
y_fill: true });
track_hover: true });
this._dot = new St.Widget({ style_class: 'app-well-app-running-dot',
layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END });
this._dot.hide();
this._button = new St.Button({ style_class: 'app-well-app',
reactive: true,
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
can_focus: true,
x_fill: true,
y_fill: true });
this.actor.add_actor(this._button);
this.actor.add_actor(this._dot);
this.actor._delegate = this;
this._button._delegate = this;
if (!iconParams)
iconParams = {};
@ -1531,20 +1551,20 @@ const AppIcon = new Lang.Class({
iconParams['createIcon'] = Lang.bind(this, this._createIcon);
iconParams['setSizeManually'] = true;
this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
this.actor.set_child(this.icon.actor);
this._button.set_child(this.icon.actor);
this.actor.label_actor = this.icon.label;
this.actor.connect('leave-event', Lang.bind(this, this._onLeaveEvent));
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('touch-event', Lang.bind(this, this._onTouchEvent));
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
this.actor.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu));
this._button.connect('leave-event', Lang.bind(this, this._onLeaveEvent));
this._button.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this._button.connect('touch-event', Lang.bind(this, this._onTouchEvent));
this._button.connect('clicked', Lang.bind(this, this._onClicked));
this._button.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu));
this._menu = null;
this._menuManager = new PopupMenu.PopupMenuManager(this);
this._draggable = DND.makeDraggable(this.actor);
this._draggable = DND.makeDraggable(this._button);
this._draggable.connect('drag-begin', Lang.bind(this,
function () {
this._removeMenuTimeout();
@ -1569,6 +1589,18 @@ const AppIcon = new Lang.Class({
this._updateRunningStyle();
},
// Needed for containers that want to track focus of the widget
// for i.e. scroll the container when navigating through items
getFocusReceiver: function () {
return this._button;
},
// Needed for containers that want to change style of the widget
// for i.e. set as selected when searching in shell
getStyleReceiver: function () {
return this._button;
},
_onDestroy: function() {
if (this._stateChangedId > 0)
this.app.disconnect(this._stateChangedId);
@ -1588,10 +1620,13 @@ const AppIcon = new Lang.Class({
},
_updateRunningStyle: function() {
if (this.app.state != Shell.AppState.STOPPED)
this.actor.add_style_class_name('running');
else
this.actor.remove_style_class_name('running');
if (this.app.state != Shell.AppState.STOPPED) {
this._button.add_style_class_name('running');
this._dot.show();
} else {
this._button.remove_style_class_name('running');
this._dot.hide();
}
},
_setPopupTimeout: function() {
@ -1606,7 +1641,7 @@ const AppIcon = new Lang.Class({
},
_onLeaveEvent: function(actor, event) {
this.actor.fake_release();
this._button.fake_release();
this._removeMenuTimeout();
},
@ -1644,7 +1679,7 @@ const AppIcon = new Lang.Class({
popupMenu: function() {
this._removeMenuTimeout();
this.actor.fake_release();
this._button.fake_release();
this._draggable.fakeRelease();
if (!this._menu) {
@ -1663,7 +1698,7 @@ const AppIcon = new Lang.Class({
this.emit('menu-state-changed', true);
this.actor.set_hover(true);
this._button.set_hover(true);
this._menu.popup();
this._menuManager.ignoreRelease();
this.emit('sync-tooltip');
@ -1680,7 +1715,7 @@ const AppIcon = new Lang.Class({
},
_onMenuPoppedDown: function() {
this.actor.sync_hover();
this._button.sync_hover();
this.emit('menu-state-changed', false);
},

View File

@ -278,20 +278,6 @@ const IconGrid = new Lang.Class({
this._grid.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this._grid.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this._grid.connect('allocate', Lang.bind(this, this._allocate));
this._grid.connect('actor-added', Lang.bind(this, this._childAdded));
this._grid.connect('actor-removed', Lang.bind(this, this._childRemoved));
},
_keyFocusIn: function(actor) {
this.emit('key-focus-in', actor);
},
_childAdded: function(grid, child) {
child._iconGridKeyFocusInId = child.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
},
_childRemoved: function(grid, child) {
child.disconnect(child._iconGridKeyFocusInId);
},
_getPreferredWidth: function (grid, forHeight, alloc) {
@ -682,6 +668,10 @@ const IconGrid = new Lang.Class({
this._grid.destroy_all_children();
},
_keyFocusIn: function(actor) {
this.emit('key-focus-in', actor._associatedItem);
},
addItem: function(item, index) {
if (!item.icon instanceof BaseIcon)
throw new Error('Only items with a BaseIcon icon property can be added to IconGrid');
@ -691,9 +681,26 @@ const IconGrid = new Lang.Class({
this._grid.insert_child_at_index(item.actor, index);
else
this._grid.add_actor(item.actor);
// Maybe the item actor acts as a container, so ask the item if
// it has a specific actor to track focus
let focusReceiver = item.actor;
if (item.getFocusReceiver)
focusReceiver = item.getFocusReceiver();
focusReceiver._associatedItem = item.actor;
focusReceiver._iconGridKeyFocusInId = focusReceiver.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
},
removeItem: function(item) {
let focusReceiver = item.actor;
if (item.getFocusReceiver)
focusReceiver = item.getFocusReceiver();
focusReceiver._associatedItem = null;
focusReceiver.disconnect(focusReceiver._iconGridKeyFocusInId);
this._grid.remove_child(item.actor);
},

View File

@ -659,11 +659,15 @@ const SearchResults = new Lang.Class({
if (!result)
return;
let styleReceiver = result.actor;
if (result.getStyleReceiver)
styleReceiver = result.getStyleReceiver();
if (selected) {
result.actor.add_style_pseudo_class('selected');
styleReceiver.add_style_pseudo_class('selected');
Util.ensureActorVisibleInScrollView(this._scrollView, result.actor);
} else {
result.actor.remove_style_pseudo_class('selected');
styleReceiver.remove_style_pseudo_class('selected');
}
}
});