AppFolderPopup: fix the position of close buttons

We need to adjust the offset of close buttons, in case the box
pointer has the arrow at the top. To do so, extend close buttons
to hook into a boxpointer (since that's the common use for them)
and automatically adjust their position.

https://bugzilla.gnome.org/show_bug.cgi?id=707842
This commit is contained in:
Giovanni Campagna 2013-09-10 11:48:55 +02:00
parent 367fb32493
commit 255cb8edb1
3 changed files with 60 additions and 20 deletions

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const Lang = imports.lang;
const St = imports.gi.St; const St = imports.gi.St;
const Main = imports.ui.main; const Main = imports.ui.main;
@ -189,28 +190,57 @@ function insertSorted(array, val, cmp) {
return pos; return pos;
} }
function makeCloseButton() { const CloseButton = new Lang.Class({
let closeButton = new St.Button({ style_class: 'notification-close'}); Name: 'CloseButton',
Extends: St.Button,
_init: function(boxpointer) {
this.parent({ style_class: 'notification-close'});
// This is a bit tricky. St.Bin has its own x-align/y-align properties // This is a bit tricky. St.Bin has its own x-align/y-align properties
// that compete with Clutter's properties. This should be fixed for // that compete with Clutter's properties. This should be fixed for
// Clutter 2.0. Since St.Bin doesn't define its own setters, the // Clutter 2.0. Since St.Bin doesn't define its own setters, the
// setters are a workaround to get Clutter's version. // setters are a workaround to get Clutter's version.
closeButton.set_x_align(Clutter.ActorAlign.END); this.set_x_align(Clutter.ActorAlign.END);
closeButton.set_y_align(Clutter.ActorAlign.START); this.set_y_align(Clutter.ActorAlign.START);
// XXX Clutter 2.0 workaround: ClutterBinLayout needs expand // XXX Clutter 2.0 workaround: ClutterBinLayout needs expand
// to respect the alignments. // to respect the alignments.
closeButton.set_x_expand(true); this.set_x_expand(true);
closeButton.set_y_expand(true); this.set_y_expand(true);
closeButton.connect('style-changed', function() { this._boxPointer = boxpointer;
let themeNode = closeButton.get_theme_node(); if (boxpointer)
closeButton.translation_x = themeNode.get_length('-shell-close-overlap-x'); this._boxPointer.connect('arrow-side-changed', Lang.bind(this, this._sync));
closeButton.translation_y = themeNode.get_length('-shell-close-overlap-y'); },
});
return closeButton; _computeBoxPointerOffset: function() {
if (!this._boxPointer || !this._boxPointer.actor.get_stage())
return 0;
let side = this._boxPointer.arrowSide;
if (side == St.Side.TOP)
return this._boxPointer.getArrowHeight();
else
return 0;
},
_sync: function() {
let themeNode = this.get_theme_node();
let offY = this._computeBoxPointerOffset();
this.translation_x = themeNode.get_length('-shell-close-overlap-x')
this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
},
vfunc_style_changed: function() {
this._sync();
this.parent();
},
});
function makeCloseButton(boxpointer) {
return new CloseButton(boxpointer);
} }
function ensureActorVisibleInScrollView(scrollView, actor) { function ensureActorVisibleInScrollView(scrollView, actor) {

View File

@ -1157,7 +1157,7 @@ const AppFolderPopup = new Lang.Class({
this.actor.add_actor(this._boxPointer.actor); this.actor.add_actor(this._boxPointer.actor);
this._boxPointer.bin.set_child(this._view.actor); this._boxPointer.bin.set_child(this._view.actor);
this.closeButton = Util.makeCloseButton(); this.closeButton = Util.makeCloseButton(this._boxPointer);
this.closeButton.connect('clicked', Lang.bind(this, this.popdown)); this.closeButton.connect('clicked', Lang.bind(this, this.popdown));
this.actor.add_actor(this.closeButton); this.actor.add_actor(this.closeButton);

View File

@ -3,8 +3,9 @@
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Lang = imports.lang; const Lang = imports.lang;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const St = imports.gi.St;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Main = imports.ui.main; const Main = imports.ui.main;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
@ -61,6 +62,10 @@ const BoxPointer = new Lang.Class({
this._muteInput(); this._muteInput();
}, },
get arrowSide() {
return this._arrowSide;
},
_muteInput: function() { _muteInput: function() {
if (this._capturedEventId == 0) if (this._capturedEventId == 0)
this._capturedEventId = this.actor.connect('captured-event', this._capturedEventId = this.actor.connect('captured-event',
@ -612,6 +617,8 @@ const BoxPointer = new Lang.Class({
this._container.queue_relayout(); this._container.queue_relayout();
return false; return false;
})); }));
this.emit('arrow-side-changed');
} }
}, },
@ -644,6 +651,8 @@ const BoxPointer = new Lang.Class({
updateArrowSide: function(side) { updateArrowSide: function(side) {
this._arrowSide = side; this._arrowSide = side;
this._border.queue_repaint(); this._border.queue_repaint();
this.emit('arrow-side-changed');
}, },
getPadding: function(side) { getPadding: function(side) {
@ -654,3 +663,4 @@ const BoxPointer = new Lang.Class({
return this.actor.get_theme_node().get_length('-arrow-rise'); return this.actor.get_theme_node().get_length('-arrow-rise');
} }
}); });
Signals.addSignalMethods(BoxPointer.prototype);