2 * Copyright (C) 2011 Lukáš Karas <lukas.karas@centrum.cz>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 import "./components/styles/default" as DefaultStyles
23 import org.makneto 0.1 as Makneto
27 SystemPalette{ id: syspal }
28 color: main.useSyspal ? syspal.mid : "#262626"
30 property variant expandedWidth : 200
31 property variant hidedWidth : 0
32 property variant animationLength: 200
34 property variant _model: ListModel {}
35 property variant _notifications: ListModel {}
37 function onSessionsModelChanged(model){
38 log("set sessions model");
39 leftPanel._model = model;
41 function onNotificationsModelChanged(model){
42 log("set notifications model");
43 leftPanel._notifications = model;
47 console.log("II [LeftPanel.qml]: "+msg);
50 console.log("EE [LeftPanel.qml]: "+msg);
53 console.log("WW [LeftPanel.qml]: "+msg);
59 PropertyChanges { target: leftPanelShadow; opacity: 1}
60 PropertyChanges { target: leftPanel; width: expandedWidth}
61 PropertyChanges { target: clipImage; source: "img/clip-hide.png"}
65 PropertyChanges { target: leftPanelShadow; opacity: 0}
66 PropertyChanges { target: leftPanel; width: hidedWidth}
67 PropertyChanges { target: clipImage; source: "img/clip-show.png"}
71 PropertyChanges { target: leftPanelShadow; opacity: 1}
76 from: "hided"; to: "expanded"
77 NumberAnimation { properties: "width,height"; easing.type: Easing.InOutQuad; duration: animationLength }
80 from: "expanded"; to: "hided"
81 NumberAnimation { properties: "width,height"; easing.type: Easing.InOutQuad; duration: animationLength }
84 from: "hold"; to: "expanded"
85 NumberAnimation { properties: "width,height"; easing.type: Easing.InOutQuad; duration: animationLength /2 }
88 from: "hold"; to: "hided"
89 NumberAnimation { properties: "width,height"; easing.type: Easing.InOutQuad; duration: animationLength /2 }
92 NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; duration: animationLength }
99 Component.onCompleted : {
100 main.sessionsModelChanged.connect(onSessionsModelChanged);
101 main.notificationsModelChanged.connect(onNotificationsModelChanged);
106 anchors{top: parent.top; bottom: parent.bottom; left: parent.right}
109 source: "./img/shadow-vertical.svg"
116 anchors.left: parent.right
117 anchors.top: parent.top
118 anchors.topMargin: leftPanel.height / 4
121 color: leftPanel.color
123 //property bool hold : false
124 property int dragStartX:0
125 property variant dragStartWidth:0
129 source: "img/clip-hide.png"
132 anchors.horizontalCenter: clip.horizontalCenter
133 anchors.verticalCenter: clip.verticalCenter
141 var pos = clipMouseArea.mapToItem(main,mouseX, mouseY);
142 var div = Math.abs(clip.dragStartX - pos.x);
144 //log("ignore clicked "+div);
147 //log("clicked "+div+" "+leftPanel.state);
149 leftPanel.state = (leftPanel.state == "hided")? "expanded": "hided";
152 if (clip.dragStartWidth == leftPanel.hidedWidth){
153 leftPanel.state = (leftPanel.width - leftPanel.hidedWidth) > ((leftPanel.expandedWidth - leftPanel.hidedWidth) * .25) ?
156 leftPanel.state = (leftPanel.width - leftPanel.hidedWidth) < ((leftPanel.expandedWidth - leftPanel.hidedWidth) * .75) ?
160 //log("onReleased "+leftPanel.state);
162 function startDrag(mouseX, mouseY){
163 var pos = clipMouseArea.mapToItem(main,mouseX, mouseY);
164 var currentWidth = leftPanel.width;
166 leftPanel.state = "hold";
167 leftPanel.width = currentWidth;
168 clip.dragStartX = pos.x;
169 clip.dragStartWidth = leftPanel.width;
171 //log("start hold w: "+leftPanel.width+", x: "+pos.x);
175 startDrag(mouseX, mouseY);
178 startDrag(mouseX, mouseY);
180 onMousePositionChanged: {
181 if (leftPanel.state != "hold")
184 var pos = clipMouseArea.mapToItem(main,mouseX, mouseY);
185 //log("move w: "+clip.dragStartWidth +" + x: "+ pos.x +" - s: "+ clip.dragStartX);
186 var w = clip.dragStartWidth + (pos.x - clip.dragStartX);
187 if (w < leftPanel.hidedWidth)
188 w = leftPanel.hidedWidth;
189 if (w > leftPanel.expandedWidth)
190 w = leftPanel.expandedWidth;
197 id: contactListButton
198 anchors{margins: 6; top: parent.top; right: parent.right}
199 width: leftPanel.expandedWidth - (contactListButton.anchors.margins * 2)
200 text: "Show Contact List"
202 main.getSessionController().showContactList();
208 anchors{ top: contactListButton.bottom; right: parent.right; }
209 anchors{ topMargin: 12; leftMargin: 6; bottomMargin: 10; rightMargin: 6}
210 width: leftPanel.expandedWidth - (contactListButton.anchors.margins * 2)
211 color: main.useSyspal? syspal.windowText :"white"
212 text: "Opened sessions:"
217 model: leftPanel._model;
218 anchors{margins: 6; topMargin: 20; top: sessionsLabel.bottom; right: parent.right; bottom: notificationsView.top}
219 width: leftPanel.expandedWidth - (contactListButton.anchors.margins * 2)
223 id: sessionCloseTimer
224 property variant sessionId:0
225 interval: 10; running: false; repeat: false
227 /* this method destroys this ListViewLine (id notificationLine).
228 invoking this code directly from Button's method onClicked
229 causes application SEGFAULT! This is workaround, we invoke
232 main.getSessionController().closeSession(sessionId);
236 delegate: ListViewLine{
238 width: sessionsView.width
239 property variant sessionId : id
240 property variant titleText: ((type & Makneto.Session.SessionTypeAudio) || (type & Makneto.Session.SessionTypeVideo)?
241 "call":"chat")+" with "+sessionName
242 property variant statusText: lastMessage // sessionId
243 property variant iconSource: icon !== ""?
244 "file:"+ icon : "qrc:/declarative/img/default_avatar.jpg"
246 property variant titleTextBold: main.getSessionController().getTopScene() == sessionId;
247 property variant textElide: Text.ElideRight;
252 main.getSessionController().activateSession(sessionId);
257 source: "img/cross.png"
258 height: parent.height * 0.8
259 anchors{ margins: parent.height*0.1; fill:parent}
261 color: leftPanel.color
262 height: parent.height
265 anchors{ margins: parent.height*0.1; right: parent.right; top: parent.top}
266 //BorderImage { source: "img/lineedit.sci"; anchors.fill: parent }
271 sessionCloseTimer.sessionId = sessionId;
272 sessionCloseTimer.start();
281 anchors{top: sessionsView.bottom; right: parent.right;}
282 width: sessionsView.width
289 source: "img/line-horizontal.svg"
295 id: notificationsView
296 model: leftPanel._notifications;
297 anchors{margins: 6; topMargin: 20; right: parent.right; bottom: parent.bottom}
298 width: sessionsView.width
299 height: Math.max(leftPanel.height * .2, 100)
304 property variant notificationId:0
305 interval: 10; running: false; repeat: false
307 /* this method destroys this ListViewLine (id notificationLine).
308 invoking this code directly from Button's method onClicked
309 causes application SEGFAULT! This is workaround, we invoke
312 leftPanel._notifications.acceptNotification(notificationId);
317 property variant notificationId:0
318 interval: 10; running: false; repeat: false
320 leftPanel._notifications.declineNotification(notificationId);
325 delegate: AbstractListViewLine{
327 width: notificationsView.width
328 height: titleText.height + contactText.height + acceptButton.height + acceptButton.anchors.topMargin +
329 (wrapper.anchors.topMargin + wrapper.anchors.bottomMargin ) + 2
331 property variant notificationId : id
332 property variant sessionId: sessionId
333 property variant name : sessionName
334 property variant notificationType : type
335 property variant notificationTitle: title
336 property variant notificationIcon: icon
337 property variant notificationMessage: message
341 anchors.topMargin: topMargin
342 anchors.bottomMargin: bottomMargin
343 anchors.leftMargin: leftMargin
344 anchors.rightMargin: rightMargin
350 source: notificationLine.notificationIcon !== "" ?
351 "file:"+ notificationLine.notificationIcon : "qrc:/declarative/img/default_avatar.jpg"
353 anchors{top: titleText.top; bottom: contactText.bottom; left: parent.left}
358 text: notificationLine.notificationTitle
359 anchors{left: notificationIcon.right; right: parent.right; top: parent.top}
360 anchors.leftMargin: 8
361 wrapMode: Text.NoWrap
368 text: notificationLine.name+ (notificationLine.notificationMessage === ""?"":": "+notificationLine.notificationMessage)
369 anchors{left: titleText.left; right: parent.right; top: titleText.bottom}
370 wrapMode: Text.NoWrap
376 anchors{ right: parent.right; top: contactText.bottom; topMargin: 4}
377 text: notificationLine.notificationType == Makneto.NotificationItem.CallErrorType? "Hide": "Accept"
379 acceptTimer.notificationId = notificationLine.notificationId;
385 opacity: notificationLine.notificationType == Makneto.NotificationItem.CallErrorType? 0: 1
386 anchors{ right: acceptButton.left; top: acceptButton.top}
389 closeTimer.notificationId = notificationLine.notificationId;