From ca9099997cd163907bf390a5c0e491686a07be7d Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 14 Jun 2013 08:06:27 -0400 Subject: [PATCH] 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. --- js/Makefile.am | 1 + js/ui/auth/loginDialog.js | 239 +----------------------------------- js/ui/auth/userList.js | 251 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+), 237 deletions(-) create mode 100644 js/ui/auth/userList.js diff --git a/js/Makefile.am b/js/Makefile.am index 3b41635bc..d59b8246d 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -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 \ diff --git a/js/ui/auth/loginDialog.js b/js/ui/auth/loginDialog.js index 75a88d25b..2aa582104 100644 --- a/js/ui/auth/loginDialog.js +++ b/js/ui/auth/loginDialog.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, diff --git a/js/ui/auth/userList.js b/js/ui/auth/userList.js new file mode 100644 index 000000000..4cc4c4f51 --- /dev/null +++ b/js/ui/auth/userList.js @@ -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);