loginDialog: move user list to its own file
The userList code has no dependencies on anything else in loginDialog.js so move it to its own file. This is part of the greater reorganization effort to clean up the login dialog / unlock dialog situation.
This commit is contained in:
parent
4de18f2d4b
commit
ca9099997c
@ -109,6 +109,7 @@ nobase_dist_js_DATA = \
|
||||
ui/auth/realmd.js \
|
||||
ui/auth/sessionList.js \
|
||||
ui/auth/unlockDialog.js \
|
||||
ui/auth/userList.js \
|
||||
ui/auth/util.js \
|
||||
ui/components/__init__.js \
|
||||
ui/components/autorunManager.js \
|
||||
|
@ -42,6 +42,7 @@ const ModalDialog = imports.ui.modalDialog;
|
||||
const SessionList = imports.ui.auth.sessionList;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const UserAvatar = imports.ui.userAvatar;
|
||||
const UserList = imports.ui.auth.userList;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
|
||||
const _FADE_ANIMATION_TIME = 0.25;
|
||||
@ -51,242 +52,6 @@ const _LOGO_ICON_HEIGHT = 48;
|
||||
|
||||
let _loginDialog = null;
|
||||
|
||||
const UserListItem = new Lang.Class({
|
||||
Name: 'UserListItem',
|
||||
|
||||
_init: function(user) {
|
||||
this.user = user;
|
||||
this._userChangedId = this.user.connect('changed',
|
||||
Lang.bind(this, this._onUserChanged));
|
||||
|
||||
let layout = new St.BoxLayout({ vertical: false });
|
||||
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||
can_focus: true,
|
||||
child: layout,
|
||||
reactive: true,
|
||||
x_align: St.Align.START,
|
||||
x_fill: true });
|
||||
|
||||
this._userAvatar = new UserAvatar.UserAvatar(this.user,
|
||||
{ styleClass: 'login-dialog-user-list-item-icon' });
|
||||
layout.add(this._userAvatar.actor);
|
||||
let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box',
|
||||
vertical: true });
|
||||
layout.add(textLayout, { expand: true });
|
||||
|
||||
this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' });
|
||||
this.actor.label_actor = this._nameLabel;
|
||||
textLayout.add(this._nameLabel,
|
||||
{ y_fill: false,
|
||||
y_align: St.Align.MIDDLE,
|
||||
expand: true });
|
||||
|
||||
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
|
||||
scale_x: 0 });
|
||||
textLayout.add(this._timedLoginIndicator,
|
||||
{ x_fill: true,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_fill: false,
|
||||
y_align: St.Align.END });
|
||||
|
||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
this._onUserChanged();
|
||||
},
|
||||
|
||||
_onUserChanged: function() {
|
||||
this._nameLabel.set_text(this.user.get_real_name());
|
||||
this._userAvatar.update();
|
||||
this._updateLoggedIn();
|
||||
},
|
||||
|
||||
syncStyleClasses: function() {
|
||||
this._updateLoggedIn();
|
||||
|
||||
if (global.stage.get_key_focus() == this.actor)
|
||||
this.actor.add_style_pseudo_class('focus');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('focus');
|
||||
},
|
||||
|
||||
_updateLoggedIn: function() {
|
||||
if (this.user.is_logged_in())
|
||||
this.actor.add_style_pseudo_class('logged-in');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('logged-in');
|
||||
},
|
||||
|
||||
_onClicked: function() {
|
||||
this.emit('activate');
|
||||
},
|
||||
|
||||
showTimedLoginIndicator: function(time) {
|
||||
let hold = new Batch.Hold();
|
||||
|
||||
this.hideTimedLoginIndicator();
|
||||
Tweener.addTween(this._timedLoginIndicator,
|
||||
{ scale_x: 1.,
|
||||
time: time,
|
||||
transition: 'linear',
|
||||
onComplete: function() {
|
||||
hold.release();
|
||||
},
|
||||
onCompleteScope: this
|
||||
});
|
||||
return hold;
|
||||
},
|
||||
|
||||
hideTimedLoginIndicator: function() {
|
||||
Tweener.removeTweens(this._timedLoginIndicator);
|
||||
this._timedLoginIndicator.scale_x = 0.;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(UserListItem.prototype);
|
||||
|
||||
const UserList = new Lang.Class({
|
||||
Name: 'UserList',
|
||||
|
||||
_init: function() {
|
||||
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
|
||||
this.actor.set_policy(Gtk.PolicyType.NEVER,
|
||||
Gtk.PolicyType.AUTOMATIC);
|
||||
|
||||
this._box = new St.BoxLayout({ vertical: true,
|
||||
style_class: 'login-dialog-user-list',
|
||||
pseudo_class: 'expanded' });
|
||||
|
||||
this.actor.add_actor(this._box);
|
||||
this._items = {};
|
||||
|
||||
this.actor.connect('key-focus-in', Lang.bind(this, this._moveFocusToItems));
|
||||
},
|
||||
|
||||
_moveFocusToItems: function() {
|
||||
let hasItems = Object.keys(this._items).length > 0;
|
||||
|
||||
if (!hasItems)
|
||||
return;
|
||||
|
||||
if (global.stage.get_key_focus() != this.actor)
|
||||
return;
|
||||
|
||||
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
if (!focusSet) {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||
this._moveFocusToItems();
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_onItemActivated: function(activatedItem) {
|
||||
this.emit('activate', activatedItem);
|
||||
},
|
||||
|
||||
updateStyle: function(isExpanded) {
|
||||
let tasks = [];
|
||||
|
||||
if (isExpanded)
|
||||
this._box.add_style_pseudo_class('expanded');
|
||||
else
|
||||
this._box.remove_style_pseudo_class('expanded');
|
||||
|
||||
for (let userName in this._items) {
|
||||
let item = this._items[userName];
|
||||
item.actor.sync_hover();
|
||||
item.syncStyleClasses();
|
||||
}
|
||||
},
|
||||
|
||||
scrollToItem: function(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
|
||||
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
||||
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
Tweener.removeTweens(adjustment);
|
||||
Tweener.addTween (adjustment,
|
||||
{ value: value,
|
||||
time: _SCROLL_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
|
||||
jumpToItem: function(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
|
||||
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
||||
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
|
||||
adjustment.set_value(value);
|
||||
},
|
||||
|
||||
getItemFromUserName: function(userName) {
|
||||
let item = this._items[userName];
|
||||
|
||||
if (!item)
|
||||
return null;
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
addUser: function(user) {
|
||||
if (!user.is_loaded)
|
||||
return;
|
||||
|
||||
if (user.is_system_account())
|
||||
return;
|
||||
|
||||
if (user.locked)
|
||||
return;
|
||||
|
||||
let userName = user.get_user_name();
|
||||
|
||||
if (!userName)
|
||||
return;
|
||||
|
||||
this.removeUser(user);
|
||||
|
||||
let item = new UserListItem(user);
|
||||
this._box.add(item.actor, { x_fill: true });
|
||||
|
||||
this._items[userName] = item;
|
||||
|
||||
item.connect('activate',
|
||||
Lang.bind(this, this._onItemActivated));
|
||||
|
||||
// Try to keep the focused item front-and-center
|
||||
item.actor.connect('key-focus-in',
|
||||
Lang.bind(this,
|
||||
function() {
|
||||
this.scrollToItem(item);
|
||||
}));
|
||||
|
||||
this._moveFocusToItems();
|
||||
|
||||
this.emit('item-added', item);
|
||||
},
|
||||
|
||||
removeUser: function(user) {
|
||||
if (!user.is_loaded)
|
||||
return;
|
||||
|
||||
let userName = user.get_user_name();
|
||||
|
||||
if (!userName)
|
||||
return;
|
||||
|
||||
let item = this._items[userName];
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item.actor.destroy();
|
||||
delete this._items[userName];
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(UserList.prototype);
|
||||
|
||||
const LoginDialog = new Lang.Class({
|
||||
Name: 'LoginDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
@ -350,7 +115,7 @@ const LoginDialog = new Lang.Class({
|
||||
this._userSelectionBox.add(this._bannerLabel);
|
||||
this._updateBanner();
|
||||
|
||||
this._userList = new UserList();
|
||||
this._userList = new UserList.UserList();
|
||||
this._userSelectionBox.add(this._userList.actor,
|
||||
{ expand: true,
|
||||
x_fill: true,
|
||||
|
251
js/ui/auth/userList.js
Normal file
251
js/ui/auth/userList.js
Normal file
@ -0,0 +1,251 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const AccountsService = imports.gi.AccountsService;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Gdm = imports.gi.Gdm;
|
||||
|
||||
const Batch = imports.misc.batch;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const UserAvatar = imports.ui.userAvatar;
|
||||
|
||||
const _SCROLL_ANIMATION_TIME = 0.5;
|
||||
|
||||
const UserListItem = new Lang.Class({
|
||||
Name: 'UserListItem',
|
||||
|
||||
_init: function(user) {
|
||||
this.user = user;
|
||||
this._userChangedId = this.user.connect('changed',
|
||||
Lang.bind(this, this._onUserChanged));
|
||||
|
||||
let layout = new St.BoxLayout({ vertical: false });
|
||||
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||
can_focus: true,
|
||||
child: layout,
|
||||
reactive: true,
|
||||
x_align: St.Align.START,
|
||||
x_fill: true });
|
||||
|
||||
this._userAvatar = new UserAvatar.UserAvatar(this.user,
|
||||
{ styleClass: 'login-dialog-user-list-item-icon' });
|
||||
layout.add(this._userAvatar.actor);
|
||||
let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box',
|
||||
vertical: true });
|
||||
layout.add(textLayout, { expand: true });
|
||||
|
||||
this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' });
|
||||
this.actor.label_actor = this._nameLabel;
|
||||
textLayout.add(this._nameLabel,
|
||||
{ y_fill: false,
|
||||
y_align: St.Align.MIDDLE,
|
||||
expand: true });
|
||||
|
||||
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
|
||||
scale_x: 0 });
|
||||
textLayout.add(this._timedLoginIndicator,
|
||||
{ x_fill: true,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_fill: false,
|
||||
y_align: St.Align.END });
|
||||
|
||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
this._onUserChanged();
|
||||
},
|
||||
|
||||
_onUserChanged: function() {
|
||||
this._nameLabel.set_text(this.user.get_real_name());
|
||||
this._userAvatar.update();
|
||||
this._updateLoggedIn();
|
||||
},
|
||||
|
||||
syncStyleClasses: function() {
|
||||
this._updateLoggedIn();
|
||||
|
||||
if (global.stage.get_key_focus() == this.actor)
|
||||
this.actor.add_style_pseudo_class('focus');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('focus');
|
||||
},
|
||||
|
||||
_updateLoggedIn: function() {
|
||||
if (this.user.is_logged_in())
|
||||
this.actor.add_style_pseudo_class('logged-in');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('logged-in');
|
||||
},
|
||||
|
||||
_onClicked: function() {
|
||||
this.emit('activate');
|
||||
},
|
||||
|
||||
showTimedLoginIndicator: function(time) {
|
||||
let hold = new Batch.Hold();
|
||||
|
||||
this.hideTimedLoginIndicator();
|
||||
Tweener.addTween(this._timedLoginIndicator,
|
||||
{ scale_x: 1.,
|
||||
time: time,
|
||||
transition: 'linear',
|
||||
onComplete: function() {
|
||||
hold.release();
|
||||
},
|
||||
onCompleteScope: this
|
||||
});
|
||||
return hold;
|
||||
},
|
||||
|
||||
hideTimedLoginIndicator: function() {
|
||||
Tweener.removeTweens(this._timedLoginIndicator);
|
||||
this._timedLoginIndicator.scale_x = 0.;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(UserListItem.prototype);
|
||||
|
||||
const UserList = new Lang.Class({
|
||||
Name: 'UserList',
|
||||
|
||||
_init: function() {
|
||||
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
|
||||
this.actor.set_policy(Gtk.PolicyType.NEVER,
|
||||
Gtk.PolicyType.AUTOMATIC);
|
||||
|
||||
this._box = new St.BoxLayout({ vertical: true,
|
||||
style_class: 'login-dialog-user-list',
|
||||
pseudo_class: 'expanded' });
|
||||
|
||||
this.actor.add_actor(this._box);
|
||||
this._items = {};
|
||||
|
||||
this.actor.connect('key-focus-in', Lang.bind(this, this._moveFocusToItems));
|
||||
},
|
||||
|
||||
_moveFocusToItems: function() {
|
||||
let hasItems = Object.keys(this._items).length > 0;
|
||||
|
||||
if (!hasItems)
|
||||
return;
|
||||
|
||||
if (global.stage.get_key_focus() != this.actor)
|
||||
return;
|
||||
|
||||
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
if (!focusSet) {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||
this._moveFocusToItems();
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_onItemActivated: function(activatedItem) {
|
||||
this.emit('activate', activatedItem);
|
||||
},
|
||||
|
||||
updateStyle: function(isExpanded) {
|
||||
let tasks = [];
|
||||
|
||||
if (isExpanded)
|
||||
this._box.add_style_pseudo_class('expanded');
|
||||
else
|
||||
this._box.remove_style_pseudo_class('expanded');
|
||||
|
||||
for (let userName in this._items) {
|
||||
let item = this._items[userName];
|
||||
item.actor.sync_hover();
|
||||
item.syncStyleClasses();
|
||||
}
|
||||
},
|
||||
|
||||
scrollToItem: function(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
|
||||
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
||||
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
Tweener.removeTweens(adjustment);
|
||||
Tweener.addTween (adjustment,
|
||||
{ value: value,
|
||||
time: _SCROLL_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
|
||||
jumpToItem: function(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
|
||||
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
||||
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
|
||||
adjustment.set_value(value);
|
||||
},
|
||||
|
||||
getItemFromUserName: function(userName) {
|
||||
let item = this._items[userName];
|
||||
|
||||
if (!item)
|
||||
return null;
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
addUser: function(user) {
|
||||
if (!user.is_loaded)
|
||||
return;
|
||||
|
||||
if (user.is_system_account())
|
||||
return;
|
||||
|
||||
if (user.locked)
|
||||
return;
|
||||
|
||||
let userName = user.get_user_name();
|
||||
|
||||
if (!userName)
|
||||
return;
|
||||
|
||||
this.removeUser(user);
|
||||
|
||||
let item = new UserListItem(user);
|
||||
this._box.add(item.actor, { x_fill: true });
|
||||
|
||||
this._items[userName] = item;
|
||||
|
||||
item.connect('activate',
|
||||
Lang.bind(this, this._onItemActivated));
|
||||
|
||||
// Try to keep the focused item front-and-center
|
||||
item.actor.connect('key-focus-in',
|
||||
Lang.bind(this,
|
||||
function() {
|
||||
this.scrollToItem(item);
|
||||
}));
|
||||
|
||||
this._moveFocusToItems();
|
||||
|
||||
this.emit('item-added', item);
|
||||
},
|
||||
|
||||
removeUser: function(user) {
|
||||
if (!user.is_loaded)
|
||||
return;
|
||||
|
||||
let userName = user.get_user_name();
|
||||
|
||||
if (!userName)
|
||||
return;
|
||||
|
||||
let item = this._items[userName];
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item.actor.destroy();
|
||||
delete this._items[userName];
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(UserList.prototype);
|
Loading…
Reference in New Issue
Block a user