Как обновить виджет при применении нового стиля - PullRequest
0 голосов
/ 23 марта 2020

Я делаю расширение со списком, содержащим флажок с текстовым элементом (St.label), который меняет стиль при переключении.

Я слушаю событие переключения, и поскольку элемент переключив, я установил новый стиль для моего текста, используя set_style_class_name () на моем Stlabel. Но стиль объекта не меняется. Единственное решение, которое я нашел, это уничтожить и переделать весь элемент списка и установить другой класс в инициализации объекта.

Как я могу просто обновить проверенный элемент?

Здесь для элемента, который я использую, я ставлю слушателя на флажок, который запускает функцию toggle (), в этой функции я обновляю класс, который должен удалить класс 'text-checked', и так текст не должен иметь свойства text-художественное оформление: сквозное.

const PopupMenu = imports.ui.popupMenu;
const Lang = imports.lang;
const { Atk, Clutter, St, GObject } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const CheckboxLib = Me.imports.src.checkbox;

var PopupCheckBoxMenuItem = GObject.registerClass({
    Signals: {
      'toggled': { param_types: [GObject.TYPE_BOOLEAN] },
      'deleted': { param_types: [GObject.TYPE_BOOLEAN] }
    },
}, class PopupCheckBoxMenuItem extends PopupMenu.PopupBaseMenuItem {
    _init(text, active, params) {
        super._init(params);
        this.label = new St.Label({
          text: text,
          y_align:Clutter.ActorAlign.CENTER,
          x_expand: true,
          style_class: active ? "text-checked" : ""
        });
        this.tags = new St.Label({
          text: "API",
          y_align:Clutter.ActorAlign.CENTER,
          style_class: "tag-item"
        });
        this.icon = new St.Button({
          style_class: 'remove-task',
          can_focus: true,
        });

        this.icon.connect('clicked', Lang.bind(this,function(){
          this.emit('deleted', this._checkbox.state);
        }));

        this.icon.add_actor(new St.Icon({
          icon_name: 'window-close-symbolic',
          style_class: 'icon-remove-task'
        }));
        this._checkbox = new CheckboxLib.CheckBox(active);

        this._checkbox.connect('clicked', Lang.bind(this,function(){
          this.toggle();
                }));

        this.accessible_role = Atk.Role.CHECK_MENU_ITEM;
        this.checkAccessibleState();

        this._statusBin = new St.Bin({
            x_align: Clutter.ActorAlign.START,
            x_expand: false,
        });
        this.add_child(this._statusBin);

        this.label_actor = this.label;
        this.add_child(this.tags);
        this.add_child(this.label);

        this.add_child(this.icon);

        this._statusLabel = new St.Label({
            text: '',
            style_class: 'popup-status-menu-item',
        });
        this._statusBin.child = this._checkbox;
    }

    setStatus(text) {
        if (text != null) {
            this._statusLabel.text = text;
            this._statusBin.child = this._statusLabel;
            this.reactive = false;
            this.accessible_role = Atk.Role.MENU_ITEM;
        } else {
            this._statusBin.child = this._checkbox;
            this.reactive = true;
            this.accessible_role = Atk.Role.CHECK_MENU_ITEM;
        }
        this.checkAccessibleState();
    }

    activate(event) {
        super.activate(event);
    }

    toggle() {
        this._checkbox.toggle();
        this.emit('toggled', this._checkbox.state);
        //Updating class
        this.label.set_style_class_name("new_class");
        this.label.real_style_changed();
        this.checkAccessibleState();
    }

    get state() {
        return this._checkbox.state;
    }

    get delete_icon() {
        return this.icon;
    }

    setToggleState(state) {
        this._checkbox.state = state;
        this.checkAccessibleState();
    }

    checkAccessibleState() {
        switch (this.accessible_role) {
        case Atk.Role.CHECK_MENU_ITEM:
            if (this._checkbox.state)
                this.add_accessible_state(Atk.StateType.CHECKED);
            else
                this.remove_accessible_state(Atk.StateType.CHECKED);
            break;
        default:
            this.remove_accessible_state(Atk.StateType.CHECKED);
        }
    }
});

1 Ответ

0 голосов
/ 24 марта 2020

Наиболее прямым представляется St.Widget.style_changed(). Кажется, это принудительно помечает состояние стиля как грязное и вызывает перерисовку (St.Label является подклассом, поэтому просто вызовите myLabel.style_changed()).

Возможно, правильный маршрут - St.Widget.ensure_style() , хотя.

Я не смотрел слишком глубоко, но проблема может заключаться в том, что виджеты не помечаются как измененные, а их изменение не распространяется на детей или что-то в этом роде.

...