on xenial help sign in
Add support for wide icons.
d04b7fbMichał Sawicz
qml/Panel/Indicators.qml−1
@@ -255,7 +255,6 @@ Showable {
255 anchors {
255 anchors {
256 left: parent.left
256 left: parent.left
257 right: parent.right
257 right: parent.right
258− margins: units.gu(1)
259 }
258 }
260 height: indicators.panelHeight
259 height: indicators.panelHeight
261 indicatorsModel: visibleIndicators.model
260 indicatorsModel: visibleIndicators.model
qml/Panel/Indicators/DefaultIndicatorWidget.qml+58−20
@@ -43,7 +43,7 @@ Indicators.IndicatorBase {
43
43
44 Label {
44 Label {
45 id: itemLeftLabel
45 id: itemLeftLabel
46− width: guRoundUp(implicitWidth)
46+ width: paintedWidth + units.gu(1)
47 objectName: "leftLabel"
47 objectName: "leftLabel"
48 color: Theme.palette.selected.backgroundText
48 color: Theme.palette.selected.backgroundText
49 opacity: 0.8
49 opacity: 0.8
@@ -51,6 +51,7 @@ Indicators.IndicatorBase {
51 fontSize: "medium"
51 fontSize: "medium"
52 anchors.verticalCenter: parent.verticalCenter
52 anchors.verticalCenter: parent.verticalCenter
53 visible: text != ""
53 visible: text != ""
54+ horizontalAlignment: Text.AlignHCenter
54 }
55 }
55
56
56 Row {
57 Row {
@@ -63,20 +64,67 @@ Indicators.IndicatorBase {
63 model: indicatorWidget.icons
64 model: indicatorWidget.icons
64
65
65 Item {
66 Item {
66− width: guRoundUp(itemImage.width) + units.gu(1)
67+ width: itemImage.width + units.gu(1)
67 anchors { top: parent.top; bottom: parent.bottom }
68 anchors { top: parent.top; bottom: parent.bottom }
68
69
69− Icon {
70+ /*
71+ FIXME: should use Icon and the theme system
72+ There is an Icon component in the SDK that the colorization is copied from.
73+ We can't use it here unfortunately due to lack of support for image source
74+ URIs and keeping aspect ratio.
75+
76+ Related bugs:
77+ http://launchpad.net/bugs/1284235
78+ http://launchpad.net/bugs/1284233
79+ */
80+
81+ Image {
70 id: itemImage
82 id: itemImage
71 objectName: "itemImage"
83 objectName: "itemImage"
72− // FIXME: Should be dynamic width, see http://pad.lv/1284235
73− width: indicatorWidget.iconSize
74 height: indicatorWidget.iconSize
84 height: indicatorWidget.iconSize
85+ sourceSize.height: height
75 anchors.centerIn: parent
86 anchors.centerIn: parent
76
87
77− // FIXME: Icon needs to accept source, see http://pad.lv/1284233
88+ onSourceChanged: console.debug(source)
89+ visible: false
90+
91+ property string iconPath: "/usr/share/icons/suru/status/scalable/%1.svg"
78− name: modelData.replace("image://theme/", "")
92+ property var icons: modelData.replace("image://theme/", "").split(",")
93+ property int fallback: 0
94+
95+ onStatusChanged: if (status == Image.Error && fallback < icons.length - 1) fallback += 1;
96+
97+ // Needed to not introduce a binding loop on source
98+ onFallbackChanged: updateSource()
99+ Component.onCompleted: updateSource()
100+ onIconsChanged: updateSource()
101+
102+ function updateSource() {
103+ source = icons.length > 0 ? iconPath.arg(icons[fallback]) : "";
104+ }
105+ }
106+
107+ ShaderEffect {
108+ id: colorizedImage
109+
110+ anchors.fill: itemImage
111+
112+ property Image source: itemImage.status == Image.Ready ? itemImage : null
79− color: "#CCCCCC"
113+ property color keyColorOut: "#CCCCCC"
114+ property color keyColorIn: "#808080"
115+ property real threshold: 0.1
116+
117+ fragmentShader: "
118+ varying highp vec2 qt_TexCoord0;
119+ uniform sampler2D source;
120+ uniform highp vec4 keyColorOut;
121+ uniform highp vec4 keyColorIn;
122+ uniform lowp float threshold;
123+ uniform lowp float qt_Opacity;
124+ void main() {
125+ lowp vec4 sourceColor = texture2D(source, qt_TexCoord0);
126+ gl_FragColor = mix(vec4(keyColorOut.rgb, 1.0) * sourceColor.a, sourceColor, step(threshold, distance(sourceColor.rgb / sourceColor.a, keyColorIn.rgb))) * qt_Opacity;
127+ }"
80 }
128 }
81 }
129 }
82 }
130 }
@@ -84,7 +132,7 @@ Indicators.IndicatorBase {
84
132
85 Label {
133 Label {
86 id: itemRightLabel
134 id: itemRightLabel
87− width: guRoundUp(implicitWidth)
135+ width: paintedWidth + units.gu(1)
88 objectName: "rightLabel"
136 objectName: "rightLabel"
89 color: Theme.palette.selected.backgroundText
137 color: Theme.palette.selected.backgroundText
90 opacity: 0.8
138 opacity: 0.8
@@ -92,20 +140,10 @@ Indicators.IndicatorBase {
92 fontSize: "medium"
140 fontSize: "medium"
93 anchors.verticalCenter: parent.verticalCenter
141 anchors.verticalCenter: parent.verticalCenter
94 visible: text != ""
142 visible: text != ""
143+ horizontalAlignment: Text.AlignHCenter
95 }
144 }
96 }
145 }
97
146
98− // TODO: Use toolkit function https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1242575
99− function guRoundUp(width) {
100− if (width == 0) {
101− return 0;
102− }
103− var gu1 = units.gu(1.0);
104− var mod = (width % gu1);
105−
106− return mod == 0 ? width : width + (gu1 - mod);
107− }
108−
109 onRootActionStateChanged: {
147 onRootActionStateChanged: {
110 if (rootActionState == undefined) {
148 if (rootActionState == undefined) {
111 leftLabel = "";
149 leftLabel = "";
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorWidget.qml+10−36
@@ -41,12 +41,6 @@ Item {
41
41
42 iconSize: units.gu(3.2)
42 iconSize: units.gu(3.2)
43 height: units.gu(3)
43 height: units.gu(3)
44−
45− rootActionState {
46− icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ]
47− leftLabel: "left"
48− rightLabel: "right"
49− }
50 }
44 }
51
45
52 UT.UnityTestCase {
46 UT.UnityTestCase {
@@ -57,41 +51,21 @@ Item {
57 widget.rootActionState.icons = [];
51 widget.rootActionState.icons = [];
58 widget.rootActionState.leftLabel = "";
52 widget.rootActionState.leftLabel = "";
59 widget.rootActionState.rightLabel = "";
53 widget.rootActionState.rightLabel = "";
60− wait(50);
54+ waitForRendering(widget)
61− }
62−
63− function test_guRoundedWidth_data() {
64− return [
65− { tag: "empty", icons: [], leftLabel: "", rightLabel: "" },
66− { tag: "1-icon-no-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "", rightLabel: "" },
67− { tag: "2-icon-no-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "", rightLabel: "" },
68− { tag: "no-icon-l-label", icons: [], leftLabel: "left", rightLabel: "" },
69− { tag: "no-icon-lr-label", icons: [], leftLabel: "left", rightLabel: "right" },
70− { tag: "1-icon-l-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "left", rightLabel: "" },
71− { tag: "1-icon-lr-label", icons: [ "image://theme/audio-volume-high" ], leftLabel: "left", rightLabel: "right" },
72− { tag: "2-icon-l-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "left", rightLabel: "" },
73− { tag: "2-icon-lr-label", icons: [ "image://theme/audio-volume-high", "image://theme/audio-volume-low" ], leftLabel: "left", rightLabel: "right" }
74− ];
75 }
55 }
76
56
77− function test_guRoundedWidth(data) {
57+ function test_icon() {
78− widget.rootActionState.icons = data.icons
58+ widget.rootActionState.icons = [ "image://theme/gps,bar,baz" ];
79− widget.rootActionState.leftLabel = data.leftLabel;
80− widget.rootActionState.rightLabel = data.rightLabel;
81− wait(50);
82
59
83− compare(widget.width, guRoundUp(widget.width));
60+ var image = findInvisibleChild(widget, "itemImage");
61+ tryCompare(image, "source", "file://" + image.iconPath.arg("gps"));
84 }
62 }
85− }
86
63
87− // TODO: Use toolkit function https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1242575
64+ function test_iconFallback() {
88− function guRoundUp(width) {
65+ widget.rootActionState.icons = [ "image://theme/foo,bar,baz" ];
89− if (width == 0) {
90− return 0;
91− }
92− var gu1 = units.gu(1.0);
93− var mod = (width % gu1);
94
66
95− return mod == 0 ? width : width + (gu1 - mod);
67+ var image = findInvisibleChild(widget, "itemImage");
68+ tryCompare(image, "source", "file://" + image.iconPath.arg("baz"));
69+ }
96 }
70 }
97}
71}