Blame js/ui/dialog.js

Packit Service ed5168
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
Packit Service ed5168
Packit Service ed5168
const { Clutter, Gio, GObject, Pango, St } = imports.gi;
Packit Service ed5168
Packit Service ed5168
var Dialog = GObject.registerClass(
Packit Service ed5168
class Dialog extends St.Widget {
Packit Service ed5168
    _init(parentActor, styleClass) {
Packit Service ed5168
        super._init({ layout_manager: new Clutter.BinLayout() });
Packit Service ed5168
        this.connect('destroy', this._onDestroy.bind(this));
Packit Service ed5168
Packit Service ed5168
        this._initialKeyFocus = null;
Packit Service ed5168
        this._initialKeyFocusDestroyId = 0;
Packit Service ed5168
        this._pressedKey = null;
Packit Service ed5168
        this._buttonKeys = {};
Packit Service ed5168
        this._createDialog();
Packit Service ed5168
        this.add_child(this._dialog);
Packit Service ed5168
Packit Service ed5168
        if (styleClass != null)
Packit Service ed5168
            this._dialog.add_style_class_name(styleClass);
Packit Service ed5168
Packit Service ed5168
        this._parentActor = parentActor;
Packit Service ed5168
        this._eventId = this._parentActor.connect('event', this._modalEventHandler.bind(this));
Packit Service ed5168
        this._parentActor.add_child(this);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _createDialog() {
Packit Service ed5168
        this._dialog = new St.BoxLayout({ style_class: 'modal-dialog',
Packit Service ed5168
                                          x_align:     Clutter.ActorAlign.CENTER,
Packit Service ed5168
                                          y_align:     Clutter.ActorAlign.CENTER,
Packit Service ed5168
                                          vertical:    true });
Packit Service ed5168
Packit Service ed5168
        // modal dialogs are fixed width and grow vertically; set the request
Packit Service ed5168
        // mode accordingly so wrapped labels are handled correctly during
Packit Service ed5168
        // size requests.
Packit Service ed5168
        this._dialog.request_mode = Clutter.RequestMode.HEIGHT_FOR_WIDTH;
Packit Service ed5168
        this._dialog.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
Packit Service ed5168
Packit Service ed5168
        this.contentLayout = new St.BoxLayout({ vertical: true,
Packit Service ed5168
                                                style_class: "modal-dialog-content-box" });
Packit Service ed5168
        this._dialog.add(this.contentLayout,
Packit Service ed5168
                         { expand:  true,
Packit Service ed5168
                           x_fill:  true,
Packit Service ed5168
                           y_fill:  true,
Packit Service ed5168
                           x_align: St.Align.MIDDLE,
Packit Service ed5168
                           y_align: St.Align.START });
Packit Service ed5168
Packit Service ed5168
        this.buttonLayout = new St.Widget ({ layout_manager: new Clutter.BoxLayout({ homogeneous:true }) });
Packit Service ed5168
        this._dialog.add(this.buttonLayout,
Packit Service ed5168
                         { x_align: St.Align.MIDDLE,
Packit Service ed5168
                           y_align: St.Align.START });
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _onDestroy() {
Packit Service ed5168
        if (this._eventId != 0)
Packit Service ed5168
            this._parentActor.disconnect(this._eventId);
Packit Service ed5168
        this._eventId = 0;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _modalEventHandler(actor, event) {
Packit Service ed5168
        if (event.type() == Clutter.EventType.KEY_PRESS) {
Packit Service ed5168
            this._pressedKey = event.get_key_symbol();
Packit Service ed5168
        } else if (event.type() == Clutter.EventType.KEY_RELEASE) {
Packit Service ed5168
            let pressedKey = this._pressedKey;
Packit Service ed5168
            this._pressedKey = null;
Packit Service ed5168
Packit Service ed5168
            let symbol = event.get_key_symbol();
Packit Service ed5168
            if (symbol != pressedKey)
Packit Service ed5168
                return Clutter.EVENT_PROPAGATE;
Packit Service ed5168
Packit Service ed5168
            let buttonInfo = this._buttonKeys[symbol];
Packit Service ed5168
            if (!buttonInfo)
Packit Service ed5168
                return Clutter.EVENT_PROPAGATE;
Packit Service ed5168
Packit Service ed5168
            let { button, action } = buttonInfo;
Packit Service ed5168
Packit Service ed5168
            if (action && button.reactive) {
Packit Service ed5168
                action();
Packit Service ed5168
                return Clutter.EVENT_STOP;
Packit Service ed5168
            }
Packit Service ed5168
        }
Packit Service ed5168
Packit Service ed5168
        return Clutter.EVENT_PROPAGATE;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _setInitialKeyFocus(actor) {
Packit Service ed5168
        if (this._initialKeyFocus)
Packit Service ed5168
            this._initialKeyFocus.disconnect(this._initialKeyFocusDestroyId);
Packit Service ed5168
Packit Service ed5168
        this._initialKeyFocus = actor;
Packit Service ed5168
Packit Service ed5168
        this._initialKeyFocusDestroyId = actor.connect('destroy', () => {
Packit Service ed5168
            this._initialKeyFocus = null;
Packit Service ed5168
            this._initialKeyFocusDestroyId = 0;
Packit Service ed5168
        });
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    get initialKeyFocus() {
Packit Service ed5168
        return this._initialKeyFocus || this;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    addContent(actor) {
Packit Service ed5168
        this.contentLayout.add (actor, { expand: true });
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    addButton(buttonInfo) {
Packit Service ed5168
        let { label, action, key } = buttonInfo;
Packit Service ed5168
        let isDefault = buttonInfo['default'];
Packit Service ed5168
        let keys;
Packit Service ed5168
Packit Service ed5168
        if (key)
Packit Service ed5168
            keys = [key];
Packit Service ed5168
        else if (isDefault)
Packit Service ed5168
            keys = [Clutter.KEY_Return, Clutter.KEY_KP_Enter, Clutter.KEY_ISO_Enter];
Packit Service ed5168
        else
Packit Service ed5168
            keys = [];
Packit Service ed5168
Packit Service ed5168
        let button = new St.Button({ style_class: 'modal-dialog-linked-button',
Packit Service ed5168
                                     button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
Packit Service ed5168
                                     reactive:    true,
Packit Service ed5168
                                     can_focus:   true,
Packit Service ed5168
                                     x_expand:    true,
Packit Service ed5168
                                     y_expand:    true,
Packit Service ed5168
                                     label:       label });
Packit Service ed5168
        button.connect('clicked', action);
Packit Service ed5168
Packit Service ed5168
        buttonInfo['button'] = button;
Packit Service ed5168
Packit Service ed5168
        if (isDefault)
Packit Service ed5168
            button.add_style_pseudo_class('default');
Packit Service ed5168
Packit Service ed5168
        if (this._initialKeyFocus == null || isDefault)
Packit Service ed5168
            this._setInitialKeyFocus(button);
Packit Service ed5168
Packit Service ed5168
        for (let i in keys)
Packit Service ed5168
            this._buttonKeys[keys[i]] = buttonInfo;
Packit Service ed5168
Packit Service ed5168
        this.buttonLayout.add_actor(button);
Packit Service ed5168
Packit Service ed5168
        return button;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    clearButtons() {
Packit Service ed5168
        this.buttonLayout.destroy_all_children();
Packit Service ed5168
        this._buttonKeys = {};
Packit Service ed5168
    }
Packit Service ed5168
});
Packit Service ed5168
Packit Service ed5168
var MessageDialogContent = GObject.registerClass({
Packit Service ed5168
    Properties: {
Packit Service ed5168
        'icon': GObject.ParamSpec.object('icon', 'icon', 'icon',
Packit Service ed5168
                                         GObject.ParamFlags.READWRITE |
Packit Service ed5168
                                         GObject.ParamFlags.CONSTRUCT,
Packit Service ed5168
                                         Gio.Icon.$gtype),
Packit Service ed5168
        'title': GObject.ParamSpec.string('title', 'title', 'title',
Packit Service ed5168
                                          GObject.ParamFlags.READWRITE |
Packit Service ed5168
                                          GObject.ParamFlags.CONSTRUCT,
Packit Service ed5168
                                          null),
Packit Service ed5168
        'subtitle': GObject.ParamSpec.string('subtitle', 'subtitle', 'subtitle',
Packit Service ed5168
                                             GObject.ParamFlags.READWRITE |
Packit Service ed5168
                                             GObject.ParamFlags.CONSTRUCT,
Packit Service ed5168
                                             null),
Packit Service ed5168
        'body': GObject.ParamSpec.string('body', 'body', 'body',
Packit Service ed5168
                                         GObject.ParamFlags.READWRITE |
Packit Service ed5168
                                         GObject.ParamFlags.CONSTRUCT,
Packit Service ed5168
                                         null)
Packit Service ed5168
    }
Packit Service ed5168
}, class MessageDialogContent extends St.BoxLayout {
Packit Service ed5168
    _init(params) {
Packit Service ed5168
        this._icon = new St.Icon({ y_align: Clutter.ActorAlign.START });
Packit Service ed5168
        this._title = new St.Label({ style_class: 'headline' });
Packit Service ed5168
        this._subtitle = new St.Label();
Packit Service ed5168
        this._body = new St.Label();
Packit Service ed5168
Packit Service ed5168
        ['icon', 'title', 'subtitle', 'body'].forEach(prop => {
Packit Service ed5168
            this[`_${prop}`].add_style_class_name(`message-dialog-${prop}`);
Packit Service ed5168
        });
Packit Service ed5168
Packit Service ed5168
        let textProps = { ellipsize: Pango.EllipsizeMode.NONE,
Packit Service ed5168
                          line_wrap: true };
Packit Service ed5168
        Object.assign(this._subtitle.clutter_text, textProps);
Packit Service ed5168
        Object.assign(this._body.clutter_text, textProps);
Packit Service ed5168
Packit Service ed5168
        if (!params.hasOwnProperty('style_class'))
Packit Service ed5168
            params.style_class = 'message-dialog-main-layout';
Packit Service ed5168
Packit Service ed5168
        super._init(params);
Packit Service ed5168
Packit Service ed5168
        this.messageBox = new St.BoxLayout({ style_class: 'message-dialog-content',
Packit Service ed5168
                                             x_expand: true,
Packit Service ed5168
                                             vertical: true });
Packit Service ed5168
Packit Service ed5168
        this.messageBox.add_actor(this._title);
Packit Service ed5168
        this.messageBox.add_actor(this._subtitle);
Packit Service ed5168
        this.messageBox.add_actor(this._body);
Packit Service ed5168
Packit Service ed5168
        this.add_actor(this._icon);
Packit Service ed5168
        this.add_actor(this.messageBox);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    get icon() {
Packit Service ed5168
        return this._icon.gicon;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    get title() {
Packit Service ed5168
        return this._title.text;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    get subtitle() {
Packit Service ed5168
        return this._subtitle.text;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    get body() {
Packit Service ed5168
        return this._body.text;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    set icon(icon) {
Packit Service ed5168
        Object.assign(this._icon, { gicon: icon, visible: icon != null });
Packit Service ed5168
        this.notify('icon');
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    set title(title) {
Packit Service ed5168
        this._setLabel(this._title, 'title', title);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    set subtitle(subtitle) {
Packit Service ed5168
        this._setLabel(this._subtitle, 'subtitle', subtitle);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    set body(body) {
Packit Service ed5168
        this._setLabel(this._body, 'body', body);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _setLabel(label, prop, value) {
Packit Service ed5168
        Object.assign(label, { text: value || '', visible: value != null });
Packit Service ed5168
        this.notify(prop);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    insertBeforeBody(actor) {
Packit Service ed5168
        this.messageBox.insert_child_below(actor, this._body);
Packit Service ed5168
    }
Packit Service ed5168
});