slint icon indicating copy to clipboard operation
slint copied to clipboard

Modifying ComboBox.model resets current-index/value

Open JakubKoralewski opened this issue 1 year ago • 6 comments

Problem

When changing the model of a ComboBox the selected value is reset. This breaks UX in some cases.

Motivation

I've already hit 2 instances where I'd like to be able to modify the model of a ComboBox. Maybe it's bad practice, but it's what I'd like my user interface to happen. For example with a SpinBox counter I'd like to conjugate the verbs of hours/minutes depending on the count. So that an "hour" becomes "hours" or in my case "godzina" becomes "godziny". In another case I wanted to add an element to a ComboBox.model instead of replacing it, and succeeded by modifying current-index and current-value from a Rust callback and pushing onto the VecModel instead of replacing it. But in one case I have a component, and the Rust solution requires access to a Window, and awkward to call a property setter from Rust code if the ComboBox is inside a component (if I'm doing things right).

Code

import {ComboBox, Switch} from "std-widgets.slint";

export component Demo {
    property <[string]> model-a: ["A", "B", "C"];
    property <[string]> model-b: ["a", "b", "c"];
    property <bool> v: false;

    VerticalLayout {

        s := Switch {
            checked: false;
        }

        ComboBox {
            model: s.checked == true ? model-a : model-b;
        }
    }
}

If that's the expected behavior that's fine, but at least I'd like to be able to save the current-index to a property and be able to restore that index, but I can't seem to be able to do that -- this code behaves the same as the one above:

import {ComboBox, Switch} from "std-widgets.slint";

export component Demo {
    property <[string]> model-a: ["A", "B", "C"];
    property <[string]> model-b: ["a", "b", "c"];
    property <int> current-index: 0;

    VerticalLayout {

        s := Switch {
            checked: false;
            toggled() => {
                c.current-index = root.current-index;
            }
        }
        

        c := ComboBox {
            model: s.checked == true ? model-a : model-b;
            selected(str) => {
                root.current-index = self.current-index;
            }
            init() => {
                self.current-index = root.current-index;
            }
        }
        Text {
            text: root.current-index + " " + c.current-index + " " +c.current-value;
        }
    }
}

same with current-value instead of current-index

JakubKoralewski avatar Aug 23 '24 14:08 JakubKoralewski