1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Qt Components project.
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
15 ** * Redistributions of source code must retain the above copyright
16 ** notice, this list of conditions and the following disclaimer.
17 ** * Redistributions in binary form must reproduce the above copyright
18 ** notice, this list of conditions and the following disclaimer in
19 ** the documentation and/or other materials provided with the
21 ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 ** the names of its contributors may be used to endorse or promote
23 ** products derived from this software without specific prior written
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
39 ****************************************************************************/
41 /// Helper code that is shared between ButtonRow.qml and ButtonColumn.qml.
44 var checkedButton = null;
46 var firstVisible = -1;
48 var visibleButtons = 0;
49 var buttonHandlers = [];
50 var styleComponent = undefined;
51 var params = undefined;
53 function isButton(item) {
54 return (item && item.hasOwnProperty("__buttonType"));
57 function hasChecked(item) {
58 return (item && item.hasOwnProperty("checked"));
62 buttons.forEach(function(button, i) {
63 if (button.visible && params.exclusive) {
64 button.checkedChanged.disconnect(buttonHandlers[i]);
67 button.visibleChanged.disconnect(buttonVisibleChanged);
73 function updateButtons() {
76 params.exclusive = self.exclusive;
79 var length = self.children.length;
80 for (var i = 0; i < length; i++) {
81 var item = self.children[i];
82 if (!hasChecked(item))
86 item.visibleChanged.connect(buttonVisibleChanged);
89 if (!checkedButton && (self.checkedButton === item || self.checkedButton == undefined))
91 else if (params.exclusive && self.checkedButton != item)
93 } else if (self.checkedButton === item) {
94 if (checkedButton && params.exclusive)
95 checkedButton.checked = false;
100 if (isButton(item)) {
102 item.platformStyle = styleComponent.createObject(item)
104 // Only ButtonRow supports tab buttons and care about screen orientation
105 if (params.orientation == Qt.Horizontal && item.platformStyle.hasOwnProperty("screenOrientation"))
106 switch (screen.currentOrientation) {
107 case Screen.Portrait:
108 case Screen.PortraitInverted:
109 item.platformStyle.screenOrientation = "portrait";
111 case Screen.Landscape:
112 case Screen.LandscapeInverted:
113 item.platformStyle.screenOrientation = "landscape";
117 if (params.exclusive) {
118 if (item["checkable"] !== undefined)
119 item.checkable = true;
120 var last = buttonHandlers.push(checkExclusive(item));
121 item.checkedChanged.connect(buttonHandlers[last - 1]);
125 if (!checkedButton && buttons.length > 0 && params.exclusive) {
126 checkedButton = buttons[0];
127 checkedButton.checked = true;
129 self.checkedButton = checkedButton;
131 buttonVisibleChanged();
134 var blockCheckedChanged = false;
136 function checkExclusive(item) {
139 if (blockCheckedChanged)
141 if (!button.checked) {
142 if (self.checkedButton === button) {
143 blockCheckedChanged = true;
144 button.checked = true;
145 blockCheckedChanged = false;
149 if (self.checkedButton === button)
151 if (self.checkedButton) {
152 blockCheckedChanged = true;
153 self.checkedButton.checked = false;
154 blockCheckedChanged = false;
156 checkedButton = button;
157 self.checkedButton = button;
161 function checkedButtonChanged() {
162 if (checkedButton === self.checkedButton)
164 blockCheckedChanged = true;
165 if (params.exclusive && checkedButton)
166 checkedButton.checked = false;
167 if (self.checkedButton)
168 self.checkedButton.checked = true;
169 blockCheckedChanged = false;
170 checkedButton = self.checkedButton;
173 function buttonVisibleChanged() {
177 buttons.forEach(function (button, i) {
178 if (button.visible) {
179 if (firstVisible === -1)
186 updateGroupPosition();
190 function updateGroupPosition() {
191 if (visibleButtons === 0)
194 // Fix the children group position
195 if (visibleButtons == 1) {
196 if (isButton(buttons[firstVisible]))
197 buttons[firstVisible].platformStyle.position = params.singlePos;
199 if (isButton(buttons[firstVisible]))
200 buttons[firstVisible].platformStyle.position = params.firstPos;
201 for (var i = firstVisible + 1; i < lastVisible; i++) {
202 if (buttons[i].visible && isButton(buttons[i]))
203 buttons[i].platformStyle.position = params.middlePos;
205 if (isButton(buttons[lastVisible]))
206 buttons[lastVisible].platformStyle.position = params.lastPos;
210 var resizing = false; // resizeChildren() may trigger reentrant calls
212 function resizeChildren() {
213 if (resizing || visibleButtons === 0)
216 if (typeof params.resizeChildren === "function") {
218 params.resizeChildren(self);
223 function create(s, p) {
225 console.log("Error creating ButtonGroup: invalid owner.");
228 if (!s.hasOwnProperty("checkedButton")) {
229 console.log("Error creating ButtonGroup: owner has no 'checkedButton' property.");
236 styleComponent = params.styleComponent;
238 if (styleComponent && styleComponent.status != Component.Ready) {
239 console.log("Error loading style:", styleComponent.errorString());
244 self.checkedButtonChanged.connect(checkedButtonChanged);
245 self.childrenChanged.connect(updateButtons);
246 self.exclusiveChanged.connect(Private.updateButtons);
247 self.widthChanged.connect(resizeChildren);
252 self.checkedButtonChanged.disconnect(checkedButtonChanged);
253 self.childrenChanged.disconnect(updateButtons);
254 self.widthChanged.disconnect(resizeChildren);
257 if (styleComponent) {
258 styleComponent.destroy();
259 styleComponent = undefined;