Changeset View
Standalone View
applets/batterymonitor/package/contents/ui/BatteryItem.qml
Show All 22 Lines | |||||
23 | 23 | | |||
24 | import org.kde.plasma.core 2.0 as PlasmaCore | 24 | import org.kde.plasma.core 2.0 as PlasmaCore | ||
25 | import org.kde.plasma.components 2.0 as PlasmaComponents | 25 | import org.kde.plasma.components 2.0 as PlasmaComponents | ||
26 | import org.kde.plasma.extras 2.0 as PlasmaExtras | 26 | import org.kde.plasma.extras 2.0 as PlasmaExtras | ||
27 | import org.kde.plasma.workspace.components 2.0 | 27 | import org.kde.plasma.workspace.components 2.0 | ||
28 | import org.kde.kcoreaddons 1.0 as KCoreAddons | 28 | import org.kde.kcoreaddons 1.0 as KCoreAddons | ||
29 | import "logic.js" as Logic | 29 | import "logic.js" as Logic | ||
30 | 30 | | |||
31 | Item { | 31 | ColumnLayout { | ||
32 | id: batteryItem | 32 | id: batteryItem | ||
33 | height: childrenRect.height | | |||
34 | 33 | | |||
35 | property var battery | 34 | property var battery | ||
36 | 35 | | |||
37 | // NOTE: According to the UPower spec this property is only valid for primary batteries, however | 36 | // NOTE: According to the UPower spec this property is only valid for primary batteries, however | ||
38 | // UPower seems to set the Present property false when a device is added but not probed yet | 37 | // UPower seems to set the Present property false when a device is added but not probed yet | ||
39 | readonly property bool isPresent: model["Plugged in"] | 38 | readonly property bool isPresent: model["Plugged in"] | ||
40 | 39 | | |||
41 | readonly property bool isBroken: model.Capacity > 0 && model.Capacity < 50 | 40 | readonly property bool isBroken: model.Capacity > 0 && model.Capacity < 50 | ||
42 | 41 | | |||
43 | property Component batteryDetails: Flow { // GridLayout crashes with a Repeater in it somehow | 42 | ColumnLayout { | ||
44 | id: detailsLayout | | |||
45 | | ||||
46 | property int leftColumnWidth: 0 | | |||
47 | width: units.gridUnit * 11 | | |||
48 | | ||||
49 | PlasmaComponents.Label { | | |||
50 | id: brokenBatteryLabel | | |||
51 | width: parent ? parent.width : implicitWidth | | |||
52 | wrapMode: Text.WordWrap | | |||
53 | text: batteryItem.isBroken && typeof model.Capacity !== "undefined" ? i18n("This battery's health is at only %1% and should be replaced. Please contact your hardware vendor for more details.", model.Capacity) : "" | | |||
54 | font.pointSize: !!detailsLayout.parent.inListView ? theme.smallestFont.pointSize : theme.defaultFont.pointSize | | |||
55 | visible: batteryItem.isBroken | | |||
56 | } | | |||
57 | | ||||
58 | Repeater { | | |||
59 | id: detailsRepeater | | |||
60 | model: Logic.batteryDetails(batteryItem.battery, batterymonitor.remainingTime) | | |||
61 | | ||||
62 | PlasmaComponents.Label { | | |||
63 | id: detailsLabel | | |||
64 | width: modelData.value && parent ? parent.width - detailsLayout.leftColumnWidth - units.smallSpacing : detailsLayout.leftColumnWidth + units.smallSpacing | | |||
65 | wrapMode: Text.NoWrap | | |||
66 | onPaintedWidthChanged: { // horrible HACK to get a column layout | | |||
67 | if (paintedWidth > detailsLayout.leftColumnWidth) { | | |||
68 | detailsLayout.leftColumnWidth = paintedWidth | | |||
69 | } | | |||
70 | } | | |||
71 | height: implicitHeight | | |||
72 | text: modelData.value ? modelData.value : modelData.label | | |||
73 | | ||||
74 | states: [ | | |||
75 | State { | | |||
76 | when: !!detailsLayout.parent.inListView // HACK | | |||
77 | PropertyChanges { | | |||
78 | target: detailsLabel | | |||
79 | horizontalAlignment: modelData.value ? Text.AlignRight : Text.AlignLeft | | |||
80 | font.pointSize: theme.smallestFont.pointSize | | |||
81 | width: parent ? parent.width / 2 : 0 | | |||
82 | elide: Text.ElideNone // eliding and height: implicitHeight causes loops | | |||
83 | } | | |||
84 | } | | |||
85 | ] | | |||
86 | } | | |||
87 | } | | |||
88 | } | | |||
89 | | ||||
90 | Column { | | |||
91 | width: parent.width | | |||
92 | spacing: 0 | 43 | spacing: 0 | ||
93 | 44 | | |||
94 | PlasmaCore.ToolTipArea { | | |||
95 | width: parent.width | | |||
96 | height: infoRow.height | | |||
97 | active: !detailsLoader.active | | |||
98 | z: 2 | | |||
99 | | ||||
100 | mainItem: Row { | | |||
101 | id: batteryItemToolTip | | |||
102 | | ||||
103 | property int _s: units.largeSpacing / 2 | | |||
104 | | ||||
105 | Layout.minimumWidth: implicitWidth + batteryItemToolTip._s | | |||
106 | Layout.minimumHeight: implicitHeight + batteryItemToolTip._s * 2 | | |||
107 | Layout.maximumWidth: implicitWidth + batteryItemToolTip._s | | |||
108 | Layout.maximumHeight: implicitHeight + batteryItemToolTip._s * 2 | | |||
109 | width: implicitWidth + batteryItemToolTip._s | | |||
110 | height: implicitHeight + batteryItemToolTip._s * 2 | | |||
111 | | ||||
112 | spacing: batteryItemToolTip._s*2 | | |||
113 | | ||||
114 | BatteryIcon { | | |||
115 | x: batteryItemToolTip._s * 2 | | |||
116 | y: batteryItemToolTip._s | | |||
117 | width: units.iconSizes.desktop // looks weird and small but that's what DefaultTooltip uses | | |||
118 | height: width | | |||
119 | batteryType: batteryIcon.batteryType | | |||
120 | percent: batteryIcon.percent | | |||
121 | hasBattery: batteryIcon.hasBattery | | |||
122 | pluggedIn: batteryIcon.pluggedIn | | |||
123 | visible: !batteryItem.isBroken | | |||
124 | } | | |||
125 | | ||||
126 | Column { | | |||
127 | id: mainColumn | | |||
128 | x: batteryItemToolTip._s | | |||
129 | y: batteryItemToolTip._s | | |||
130 | | ||||
131 | PlasmaExtras.Heading { | | |||
132 | level: 3 | | |||
133 | text: batteryNameLabel.text | | |||
134 | } | | |||
135 | Loader { | | |||
136 | sourceComponent: batteryItem.batteryDetails | | |||
137 | opacity: 0.5 | | |||
138 | } | | |||
139 | } | | |||
140 | } | | |||
141 | | ||||
142 | RowLayout { | 45 | RowLayout { | ||
143 | id: infoRow | | |||
144 | width: parent.width | | |||
145 | spacing: units.gridUnit | | |||
146 | 46 | | |||
147 | BatteryIcon { | 47 | BatteryIcon { | ||
148 | id: batteryIcon | 48 | id: batteryIcon | ||
davidedmundson: width used inside a layout | |||||
149 | Layout.alignment: Qt.AlignTop | 49 | Layout.preferredWidth: units.iconSizes.smallMedium | ||
150 | width: units.iconSizes.medium | 50 | Layout.preferredHeight: Layout.preferredWidth | ||
151 | height: width | | |||
152 | batteryType: model.Type | 51 | batteryType: model.Type | ||
153 | percent: model.Percent | 52 | percent: model.Percent | ||
154 | hasBattery: batteryItem.isPresent | 53 | hasBattery: batteryItem.isPresent | ||
155 | pluggedIn: model.State === "Charging" && model["Is Power Supply"] | 54 | pluggedIn: model.State === "Charging" && model["Is Power Supply"] | ||
156 | } | 55 | } | ||
157 | 56 | | |||
158 | Column { | | |||
159 | Layout.fillWidth: true | | |||
160 | Layout.alignment: batteryItem.isPresent ? Qt.AlignTop : Qt.AlignVCenter | | |||
161 | | ||||
162 | RowLayout { | | |||
163 | width: parent.width | | |||
164 | spacing: units.smallSpacing | | |||
165 | | ||||
166 | PlasmaComponents.Label { | 57 | PlasmaComponents.Label { | ||
167 | id: batteryNameLabel | 58 | id: batteryNameLabel | ||
You can't do that. That'll change the column size, which will change our text bounding box which will change our paintedWidth. A loop. davidedmundson: You can't do that.
That'll change the column size, which will change our text bounding box… | |||||
broulik: That's been in there ever since the initial release 2013. | |||||
Well that explains "// GridLayout crashes with a Repeater in it somehow" davidedmundson: Well that explains "// GridLayout crashes with a Repeater in it somehow" | |||||
No, it does not. Those two comments were in the same commit, to avoid the GridLayout crash. gvgeo: No, it does not. Those two comments were in the same commit, to avoid the GridLayout crash. | |||||
davidedmundson: width/height used inside a layout | |||||
168 | Layout.fillWidth: true | 59 | Layout.fillWidth: true | ||
169 | height: implicitHeight | | |||
170 | elide: Text.ElideRight | 60 | elide: Text.ElideRight | ||
171 | text: model["Pretty Name"] | 61 | text: model["Pretty Name"] | ||
172 | } | 62 | } | ||
173 | 63 | | |||
174 | PlasmaComponents.Label { | 64 | PlasmaComponents.Label { | ||
175 | text: Logic.stringForBatteryState(model) | 65 | text: Logic.stringForBatteryState(model) | ||
We want to almost never specify a width inside a layout It's the layout's job to change the item's width, which means when it re does the layout this information gets lost. Instead, we want to set an implicitWidth or Layout.preferredWidth This applies throughout davidedmundson: We want to almost never specify a width inside a layout
It's the layout's job to change the… | |||||
176 | height: implicitHeight | | |||
177 | visible: model["Is Power Supply"] | 66 | visible: model["Is Power Supply"] | ||
davidedmundson: here | |||||
178 | opacity: 0.6 | 67 | opacity: 0.6 | ||
179 | } | 68 | } | ||
180 | 69 | | |||
181 | PlasmaComponents.Label { | 70 | PlasmaComponents.Label { | ||
182 | id: batteryPercent | 71 | id: batteryPercent | ||
183 | height: paintedHeight | | |||
184 | horizontalAlignment: Text.AlignRight | 72 | horizontalAlignment: Text.AlignRight | ||
185 | visible: batteryItem.isPresent | 73 | visible: batteryItem.isPresent | ||
186 | text: i18nc("Placeholder is battery percentage", "%1%", model.Percent) | 74 | text: i18nc("Placeholder is battery percentage", "%1%", model.Percent) | ||
187 | } | 75 | } | ||
188 | } | 76 | } | ||
189 | 77 | | |||
190 | PlasmaComponents.ProgressBar { | 78 | PlasmaComponents.ProgressBar { | ||
191 | width: parent.width | 79 | Layout.fillWidth: true | ||
192 | minimumValue: 0 | 80 | minimumValue: 0 | ||
193 | maximumValue: 100 | 81 | maximumValue: 100 | ||
194 | visible: batteryItem.isPresent | 82 | visible: batteryItem.isPresent | ||
195 | value: Number(model.Percent) | 83 | value: Number(model.Percent) | ||
196 | } | 84 | } | ||
85 | | ||||
86 | PlasmaComponents.Label { | ||||
87 | id: brokenBatteryLabel | ||||
88 | Layout.fillWidth: true | ||||
89 | wrapMode: Text.WordWrap | ||||
90 | text: batteryItem.isBroken && typeof model.Capacity !== "undefined" ? i18n("This battery's health is at only %1% and should be replaced. Please contact your hardware vendor for more details.", model.Capacity) : "This battery's health is low and should be replaced. Please contact your hardware vendor for more details." | ||||
91 | font.pointSize: theme.smallestFont.pointSize | ||||
92 | maximumLineCount: 3 | ||||
93 | visible: batteryItem.isBroken | ||||
94 | } | ||||
95 | | ||||
96 | Flow { // GridLayout crashes with a Repeater in it somehow | ||||
97 | id: detailsLayout | ||||
98 | | ||||
99 | property int leftColumnWidth: 0 | ||||
100 | property int rightColumnWidth: 0 | ||||
101 | spacing: units.smallSpacing | ||||
102 | Layout.preferredWidth: leftColumnWidth + spacing + rightColumnWidth | ||||
103 | Layout.alignment: Qt.AlignRight | ||||
104 | | ||||
105 | Repeater { | ||||
106 | id: detailsRepeater | ||||
107 | model: Logic.batteryDetails(batteryItem.battery, batterymonitor.remainingTime) | ||||
108 | | ||||
109 | PlasmaComponents.Label { | ||||
110 | id: detailsLabel | ||||
111 | height: implicitHeight | ||||
112 | width: modelData.label ? detailsLayout.leftColumnWidth : detailsLayout.rightColumnWidth | ||||
This does not react to preferredWidth, minimumWidth or maximumWidth. Is it really managed by Layout? gvgeo: This does not react to preferredWidth, minimumWidth or maximumWidth. Is it really managed by… | |||||
davidedmundson: It's not Flow isn't a layout. | |||||
113 | wrapMode: Text.NoWrap | ||||
114 | text: modelData.value ? modelData.value : modelData.label | ||||
115 | elide: Text.ElideNone // eliding and height: implicitHeight causes loops | ||||
116 | horizontalAlignment: Text.AlignRight | ||||
117 | opacity: modelData.label ? 0.6 : 1 | ||||
118 | | ||||
119 | onPaintedWidthChanged: { // horrible HACK to get a column layout | ||||
120 | if (modelData.label && paintedWidth > detailsLayout.leftColumnWidth) { | ||||
121 | detailsLayout.leftColumnWidth = Math.ceil(paintedWidth) | ||||
122 | } | ||||
123 | if (modelData.value && paintedWidth > detailsLayout.rightColumnWidth) { | ||||
124 | detailsLayout.rightColumnWidth = Math.ceil(paintedWidth) | ||||
125 | } | ||||
197 | } | 126 | } | ||
198 | } | 127 | } | ||
199 | } | 128 | } | ||
200 | | ||||
201 | Loader { | | |||
202 | id: detailsLoader | | |||
203 | property bool inListView: true | | |||
204 | anchors { | | |||
205 | left: parent.left | | |||
206 | leftMargin: batteryIcon.width + units.gridUnit | | |||
207 | right: parent.right | | |||
208 | } | | |||
209 | visible: !!item | | |||
210 | opacity: 0.5 | | |||
211 | sourceComponent: batteryDetails | | |||
212 | } | 129 | } | ||
213 | } | 130 | } | ||
can we use units.smallSpacing If we invent our own margin policy everywhere by multiplying by random factors we're not going to have any consistency. davidedmundson: can we use units.smallSpacing
If we invent our own margin policy everywhere by multiplying by… | |||||
214 | | ||||
215 | } | 131 | } | ||
davidedmundson: you're using Layout. in a child of something that's not a layout | |||||
davidedmundson: Setting X in a row is a bad idea, use a layout |
width used inside a layout