Changeset View
Changeset View
Standalone View
Standalone View
src/controls/templates/ApplicationHeader.qml
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Line(s) | 38 | AbstractApplicationHeader { | |||
---|---|---|---|---|---|
45 | * * Breadcrumb: the pages are hyerarchical and the separator will look like a > | 45 | * * Breadcrumb: the pages are hyerarchical and the separator will look like a > | ||
46 | * * TabBar: the pages are intended to behave like tabbar pages | 46 | * * TabBar: the pages are intended to behave like tabbar pages | ||
47 | * and the separator will look limke a dot. | 47 | * and the separator will look limke a dot. | ||
48 | * | 48 | * | ||
49 | * When the heaer is in wide screen mode, no separator will be drawn. | 49 | * When the heaer is in wide screen mode, no separator will be drawn. | ||
50 | */ | 50 | */ | ||
51 | property int headerStyle: ApplicationHeaderStyle.Auto | 51 | property int headerStyle: ApplicationHeaderStyle.Auto | ||
52 | 52 | | |||
53 | property alias pageDelegate: titleList.delegate | 53 | property Component pageDelegate: Component { | ||
54 | Row { | ||||
55 | height: parent.height | ||||
56 | | ||||
57 | spacing: Units.smallSpacing | ||||
58 | | ||||
59 | Icon { | ||||
60 | //in tabbar mode this is just a spacer | ||||
61 | visible: !__appWindow.wideScreen && (modelData > 0 || titleList.internalHeaderStyle == ApplicationHeaderStyle.TabBar) | ||||
62 | height: title.height | ||||
63 | width: height | ||||
64 | selected: header.background && header.background.color && header.background.color == Theme.highlightColor | ||||
65 | source: titleList.isTabBar ? "" : "go-next" | ||||
66 | } | ||||
67 | | ||||
68 | Heading { | ||||
69 | id: title | ||||
70 | width:Math.min(titleList.width, implicitWidth) | ||||
71 | anchors.verticalCenter: parent.verticalCenter | ||||
72 | opacity: current ? 1 : 0.4 | ||||
73 | //Scaling animate NativeRendering is too slow | ||||
74 | renderType: Text.QtRendering | ||||
75 | color: header.background && header.background.color && header.background.color == Theme.highlightColor ? Theme.highlightedTextColor : Theme.textColor | ||||
76 | elide: Text.ElideRight | ||||
77 | text: page ? page.title : "" | ||||
78 | font.pixelSize: titleList.height / 1.6 | ||||
79 | height: parent.height | ||||
80 | Rectangle { | ||||
81 | anchors { | ||||
82 | bottom: parent.bottom | ||||
83 | left: parent.left | ||||
84 | right: parent.right | ||||
85 | } | ||||
86 | height: Units.smallSpacing | ||||
87 | color: title.color | ||||
88 | opacity: 0.6 | ||||
89 | visible: titleList.isTabBar && current | ||||
90 | } | ||||
91 | } | ||||
92 | } | ||||
93 | } | ||||
54 | 94 | | |||
55 | Rectangle { | 95 | Rectangle { | ||
56 | anchors { | 96 | anchors { | ||
57 | right: titleList.left | 97 | right: titleList.left | ||
58 | verticalCenter: parent.verticalCenter | 98 | verticalCenter: parent.verticalCenter | ||
59 | } | 99 | } | ||
60 | visible: titleList.x > 0 && !titleList.atXBeginning | 100 | visible: titleList.x > 0 && !titleList.atXBeginning | ||
61 | height: parent.height * 0.7 | 101 | height: parent.height * 0.7 | ||
Show All 11 Lines | 112 | Component.onCompleted: { | |||
73 | //only iOS and desktop systems put the back button on top left corner | 113 | //only iOS and desktop systems put the back button on top left corner | ||
74 | if (!titleList.isTabBar && (!Settings.isMobile || Qt.platform.os == "ios")) { | 114 | if (!titleList.isTabBar && (!Settings.isMobile || Qt.platform.os == "ios")) { | ||
75 | var component = Qt.createComponent(Qt.resolvedUrl("private/BackButton.qml")); | 115 | var component = Qt.createComponent(Qt.resolvedUrl("private/BackButton.qml")); | ||
76 | titleList.backButton = component.createObject(titleList.parent); | 116 | titleList.backButton = component.createObject(titleList.parent); | ||
77 | } | 117 | } | ||
78 | } | 118 | } | ||
79 | property Item backButton | 119 | property Item backButton | ||
80 | clip: true | 120 | clip: true | ||
81 | anchors { | 121 | anchors.fill: parent | ||
82 | fill: parent | | |||
83 | leftMargin: (backButton ? backButton.width : (titleList.isTabBar ? 0 : Units.smallSpacing*2)) | | |||
84 | } | | |||
85 | cacheBuffer: width ? Math.max(0, width * count) : 0 | 122 | cacheBuffer: width ? Math.max(0, width * count) : 0 | ||
86 | displayMarginBeginning: __appWindow.pageStack.width * count | 123 | displayMarginBeginning: __appWindow.pageStack.width * count | ||
87 | orientation: ListView.Horizontal | 124 | orientation: ListView.Horizontal | ||
88 | boundsBehavior: Flickable.StopAtBounds | 125 | boundsBehavior: Flickable.StopAtBounds | ||
89 | model: __appWindow.pageStack.depth | 126 | model: __appWindow.pageStack.depth | ||
90 | spacing: 0 | 127 | spacing: 0 | ||
91 | currentIndex: __appWindow.pageStack && __appWindow.pageStack.currentIndex !== undefined ? __appWindow.pageStack.currentIndex : 0 | 128 | currentIndex: __appWindow.pageStack && __appWindow.pageStack.currentIndex !== undefined ? __appWindow.pageStack.currentIndex : 0 | ||
92 | 129 | | |||
Show All 36 Lines | 165 | if (__appWindow.wideScreen && !__appWindow.pageStack.contentItem.moving && titleList.moving) { | |||
129 | __appWindow.pageStack.contentItem.contentX = titleList.contentX | 166 | __appWindow.pageStack.contentItem.contentX = titleList.contentX | ||
130 | } | 167 | } | ||
131 | } | 168 | } | ||
132 | onHeightChanged: { | 169 | onHeightChanged: { | ||
133 | titleList.returnToBounds() | 170 | titleList.returnToBounds() | ||
134 | } | 171 | } | ||
135 | onMovementEnded: { | 172 | onMovementEnded: { | ||
136 | if (__appWindow.wideScreen) { | 173 | if (__appWindow.wideScreen) { | ||
137 | __appWindow.pageStack.contentItem.movementEnded(); | 174 | //this will trigger snap as well | ||
175 | __appWindow.pageStack.contentItem.flick(0,0); | ||||
138 | } | 176 | } | ||
139 | } | 177 | } | ||
140 | 178 | | |||
141 | NumberAnimation { | 179 | NumberAnimation { | ||
142 | id: scrollTopAnimation | 180 | id: scrollTopAnimation | ||
143 | target: __appWindow.pageStack.currentItem && __appWindow.pageStack.currentItem.flickable ? __appWindow.pageStack.currentItem.flickable : null | 181 | target: __appWindow.pageStack.currentItem && __appWindow.pageStack.currentItem.flickable ? __appWindow.pageStack.currentItem.flickable : null | ||
144 | property: "contentY" | 182 | property: "contentY" | ||
145 | to: 0 | 183 | to: 0 | ||
146 | duration: Units.longDuration | 184 | duration: Units.longDuration | ||
147 | easing.type: Easing.InOutQuad | 185 | easing.type: Easing.InOutQuad | ||
148 | } | 186 | } | ||
149 | 187 | | |||
150 | delegate: MouseArea { | 188 | delegate: MouseArea { | ||
151 | id: delegate | 189 | id: delegate | ||
152 | readonly property Page page: __appWindow.pageStack.get(modelData) | 190 | readonly property int currentIndex: index | ||
153 | //NOTE: why not use ListViewCurrentIndex? because listview itself resets | 191 | readonly property var currentModelData: modelData | ||
154 | //currentIndex in some situations (since here we are using an int as a model, | 192 | clip: true | ||
155 | //even more often) so the property binding gets broken | | |||
156 | readonly property bool current: __appWindow.pageStack.currentIndex == index | | |||
157 | 193 | | |||
158 | width: { | 194 | width: { | ||
159 | //more columns shown? | 195 | //more columns shown? | ||
160 | if (__appWindow.wideScreen && page) { | 196 | if (__appWindow.wideScreen && delegateLoader.page) { | ||
161 | if (modelData == 0 && titleList.backButton) { | 197 | return delegateLoader.page.width; | ||
162 | return page.width - titleList.backButton.width; | | |||
163 | } else { | 198 | } else { | ||
164 | return page.width; | 199 | return Math.min(titleList.width, delegateLoader.implicitWidth + Units.smallSpacing); | ||
165 | } | | |||
166 | } else { | | |||
167 | return Math.min(titleList.width, delegateRoot.implicitWidth + Units.smallSpacing); | | |||
168 | } | 200 | } | ||
169 | } | 201 | } | ||
170 | height: titleList.height | 202 | height: titleList.height | ||
171 | onClicked: { | 203 | onClicked: { | ||
172 | if (__appWindow.pageStack.currentIndex == modelData) { | 204 | if (__appWindow.pageStack.currentIndex == modelData) { | ||
173 | //scroll up if current otherwise make current | 205 | //scroll up if current otherwise make current | ||
174 | if (!__appWindow.pageStack.currentItem.flickable) { | 206 | if (!__appWindow.pageStack.currentItem.flickable) { | ||
175 | return; | 207 | return; | ||
176 | } | 208 | } | ||
177 | if (__appWindow.pageStack.currentItem.flickable.contentY > -__appWindow.header.height) { | 209 | if (__appWindow.pageStack.currentItem.flickable.contentY > -__appWindow.header.height) { | ||
178 | scrollTopAnimation.to = -__appWindow.pageStack.currentItem.flickable.topMargin; | 210 | scrollTopAnimation.to = -__appWindow.pageStack.currentItem.flickable.topMargin; | ||
179 | scrollTopAnimation.running = true; | 211 | scrollTopAnimation.running = true; | ||
180 | } | 212 | } | ||
181 | 213 | | |||
182 | } else { | 214 | } else { | ||
183 | __appWindow.pageStack.currentIndex = modelData; | 215 | __appWindow.pageStack.currentIndex = modelData; | ||
184 | } | 216 | } | ||
185 | } | 217 | } | ||
186 | 218 | | |||
187 | Row { | 219 | Loader { | ||
188 | id: delegateRoot | 220 | id: delegateLoader | ||
189 | x: Units.smallSpacing + __appWindow.wideScreen ? (Math.min(delegate.width - width, Math.max(0, titleList.contentX - delegate.x))) : 0 | | |||
190 | height: parent.height | 221 | height: parent.height | ||
222 | x: Units.smallSpacing + __appWindow.wideScreen ? (Math.min(delegate.width - implicitWidth, Math.max(0, titleList.contentX - delegate.x + (titleList.backButton ? titleList.backButton.width : 0)))) : 0 | ||||
223 | width: parent.width - x | ||||
191 | 224 | | |||
192 | spacing: Units.smallSpacing | 225 | sourceComponent: header.pageDelegate | ||
193 | | ||||
194 | Icon { | | |||
195 | //in tabbar mode this is just a spacer | | |||
196 | visible: !__appWindow.wideScreen && (modelData > 0 || titleList.internalHeaderStyle == ApplicationHeaderStyle.TabBar) | | |||
197 | height: title.height | | |||
198 | width: height | | |||
199 | selected: header.background && header.background.color && header.background.color == Theme.highlightColor | | |||
200 | source: titleList.isTabBar ? "" : "go-next" | | |||
201 | } | | |||
202 | 226 | | |||
203 | Heading { | 227 | readonly property Page page: __appWindow.pageStack.get(modelData) | ||
204 | id: title | 228 | //NOTE: why not use ListViewCurrentIndex? because listview itself resets | ||
205 | width:Math.min(titleList.width, implicitWidth) | 229 | //currentIndex in some situations (since here we are using an int as a model, | ||
206 | anchors.verticalCenter: parent.verticalCenter | 230 | //even more often) so the property binding gets broken | ||
207 | opacity: delegate.current ? 1 : 0.4 | 231 | readonly property bool current: __appWindow.pageStack.currentIndex == index | ||
208 | //Scaling animate NativeRendering is too slow | 232 | readonly property int index: parent.currentIndex | ||
209 | renderType: Text.QtRendering | 233 | readonly property var modelData: parent.currentModelData | ||
210 | color: header.background && header.background.color && header.background.color == Theme.highlightColor ? Theme.highlightedTextColor : Theme.textColor | | |||
211 | elide: Text.ElideRight | | |||
212 | text: page ? page.title : "" | | |||
213 | font.pixelSize: titleList.height / 1.6 | | |||
214 | height: parent.height | | |||
215 | Rectangle { | | |||
216 | anchors { | | |||
217 | bottom: parent.bottom | | |||
218 | left: parent.left | | |||
219 | right: parent.right | | |||
220 | } | | |||
221 | height: Units.smallSpacing | | |||
222 | color: title.color | | |||
223 | opacity: 0.6 | | |||
224 | visible: titleList.isTabBar && delegate.current | | |||
225 | } | | |||
226 | } | | |||
227 | } | 234 | } | ||
228 | } | 235 | } | ||
229 | Connections { | 236 | Connections { | ||
230 | target: __appWindow.wideScreen ? __appWindow.pageStack.contentItem : null | 237 | target: __appWindow.wideScreen ? __appWindow.pageStack.contentItem : null | ||
231 | onContentXChanged: { | 238 | onContentXChanged: { | ||
232 | if (!titleList.contentItem.moving) { | 239 | if (!titleList.contentItem.moving) { | ||
233 | titleList.contentX = __appWindow.pageStack.contentItem.contentX - __appWindow.pageStack.contentItem.originX + titleList.originX; | 240 | titleList.contentX = __appWindow.pageStack.contentItem.contentX - __appWindow.pageStack.contentItem.originX + titleList.originX; | ||
234 | } | 241 | } | ||
235 | } | 242 | } | ||
236 | } | 243 | } | ||
237 | } | 244 | } | ||
238 | } | 245 | } |