From 3ac2a8c8758d0f2a273a612e185ef93dc5ec5791 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 31 Oct 2011 14:08:03 +0100 Subject: [PATCH 01/87] if stack creates the component, is the owner too leak-- --- .../plasmacomponents/qml/PageStack.js | 6 +++++- .../plasmacomponents/qml/PageStack.qml | 14 ++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/PageStack.js b/declarativeimports/plasmacomponents/qml/PageStack.js index 5e6db40f7..b08b6823a 100644 --- a/declarativeimports/plasmacomponents/qml/PageStack.js +++ b/declarativeimports/plasmacomponents/qml/PageStack.js @@ -150,7 +150,11 @@ function initPage(page, properties) { } container.page = page; - container.owner = page.parent; + if (page.parent == null) { + container.owner = container; + } else { + container.owner = page.parent; + } // the page has to be reparented if if (page.parent != container) { diff --git a/declarativeimports/plasmacomponents/qml/PageStack.qml b/declarativeimports/plasmacomponents/qml/PageStack.qml index affc83854..e4f0c3f36 100644 --- a/declarativeimports/plasmacomponents/qml/PageStack.qml +++ b/declarativeimports/plasmacomponents/qml/PageStack.qml @@ -177,8 +177,8 @@ Item { // The owner of the page. property Item owner: null - // The width of the longer screen dimension - property int screenWidth: Math.max(screen.width, screen.height) + // The width of the longer stack dimension + property int stackWidth: Math.max(root.width, root.height) // Duration of transition animation (in ms) property int transitionDuration: 250 @@ -314,7 +314,7 @@ Item { // when exiting portrait and entering landscape. State { name: "LandscapeLeft" - PropertyChanges { target: container; x: -screenWidth / 2; opacity: 0 } + PropertyChanges { target: container; x: -stackWidth / 2; opacity: 0 } }, // Start state for push entry, end state for pop exit. State { @@ -325,7 +325,7 @@ Item { // when exiting portrait and entering landscape. State { name: "LandscapeRight" - PropertyChanges { target: container; x: screenWidth / 2; opacity: 0 } + PropertyChanges { target: container; x: stackWidth / 2; opacity: 0 } }, // Inactive state. State { @@ -443,14 +443,16 @@ Item { function cleanup() { if (page != null) { - if (page.status == PageStatus.Active) - internal.setPageStatus(page, PageStatus.Inactive); + if (page.status == PageStatus.Active) { + internal.setPageStatus(page, PageStatus.Inactive) + } if (owner != container) { // container is not the owner of the page - re-parent back to original owner page.visible = false; page.parent = owner; } } +print("KILLING"+container+" "+page+" "+owner) container.destroy(); } } From 38c8915cd7c7ba8b8eada3d859a943b9edc5d19e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 31 Oct 2011 16:41:43 +0100 Subject: [PATCH 02/87] ListItem element --- .../plasmacomponents/qml/ListItem.qml | 95 +++++++++++++++++++ .../plasmacomponents/qml/qmldir | 6 +- 2 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 declarativeimports/plasmacomponents/qml/ListItem.qml diff --git a/declarativeimports/plasmacomponents/qml/ListItem.qml b/declarativeimports/plasmacomponents/qml/ListItem.qml new file mode 100644 index 000000000..45c1e6e2c --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ListItem.qml @@ -0,0 +1,95 @@ +/* + * Copyright 2010 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: listItem + default property alias content: paddingItem.data + + //this defines if the item will emit clicked and look pressed on mouse down + property bool enabled: false + //item has been clicked or pressed+hold + signal clicked + signal pressAndHold + + //plasma extension + //always look pressed? + property bool checked: false + //is this to be used as section delegate? + property bool sectionDelegate: false + + width: parent.width + height: paddingItem.childrenRect.height + background.margins.top + background.margins.bottom + + property int implicitHeight: paddingItem.childrenRect.height + background.margins.top + background.margins.bottom + + + Connections { + target: listItem + onCheckedChanged: background.prefix = (listItem.checked ? "pressed" : "normal") + onSectionDelegateChanged: background.prefix = (listItem.sectionDelegate ? "section" : "normal") + } + PlasmaCore.FrameSvgItem { + id : background + imagePath: "widgets/listitem" + prefix: "normal" + + anchors.fill: parent + Component.onCompleted: { + prefix = (listItem.sectionDelegate ? "section" : (listItem.checked ? "pressed" : "normal")) + } + } + PlasmaCore.SvgItem { + svg: PlasmaCore.Svg {imagePath: "widgets/listitem"} + elementId: "separator" + anchors { + left: parent.left + right: parent.right + top: parent.top + } + height: naturalSize.height + visible: listItem.sectionDelegate || (index != undefined && index > 0 && !listItem.checked && !itemMouse.pressed) + } + + MouseArea { + id: itemMouse + property bool changeBackgroundOnPress: !listItem.checked && !listItem.sectionDelegate + anchors.fill: background + enabled: listItem.enabled + + onClicked: listItem.clicked() + onPressAndHold: listItem.pressAndHold() + onPressed: if (changeBackgroundOnPress) background.prefix = "pressed" + onReleased: if (changeBackgroundOnPress) background.prefix = "normal" + onCanceled: if (changeBackgroundOnPress) background.prefix = "normal" + } + + Item { + id: paddingItem + anchors { + fill: background + leftMargin: background.margins.left + topMargin: background.margins.top + rightMargin: background.margins.right + bottomMargin: background.margins.bottom + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/qmldir b/declarativeimports/plasmacomponents/qml/qmldir index 6ac3c235b..1ebd340e8 100644 --- a/declarativeimports/plasmacomponents/qml/qmldir +++ b/declarativeimports/plasmacomponents/qml/qmldir @@ -22,12 +22,12 @@ TextArea 0.1 TextArea.qml TextField 0.1 TextField.qml ToolBar 0.1 ToolBar.qml ToolButton 0.1 ToolButton.qml -ListItem 0.1 ToolButton.qml +ListItem 0.1 ListItem.qml + + Page 0.1 Page.qml PageStack 0.1 PageStack.qml -Window 0.1 Window.qml - TabBar 0.1 TabBar.qml TabButton 0.1 TabButton.qml From 2bb756cfe7f052669dac3a0edcc30f653a7c3045 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 1 Nov 2011 18:55:57 +0100 Subject: [PATCH 03/87] register extra types on QScriptEngine only if hasn't been done yet --- declarativeimports/core/CMakeLists.txt | 2 +- declarativeimports/core/corebindingsplugin.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/declarativeimports/core/CMakeLists.txt b/declarativeimports/core/CMakeLists.txt index 64254ac8d..30ad3d3ed 100644 --- a/declarativeimports/core/CMakeLists.txt +++ b/declarativeimports/core/CMakeLists.txt @@ -23,7 +23,7 @@ qt4_automoc(${corebindings_SRCS}) add_library(corebindingsplugin SHARED ${corebindings_SRCS}) -target_link_libraries(corebindingsplugin ${KDE4_PLASMA_LIBS} ${QT_QTSCRIPT_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) +target_link_libraries(corebindingsplugin ${KDE4_PLASMA_LIBS} ${QT_QTSCRIPT_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} kdeclarative) install(TARGETS corebindingsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/core) install(FILES qmldir DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/core) diff --git a/declarativeimports/core/corebindingsplugin.cpp b/declarativeimports/core/corebindingsplugin.cpp index 6e06c2e6c..041023e25 100644 --- a/declarativeimports/core/corebindingsplugin.cpp +++ b/declarativeimports/core/corebindingsplugin.cpp @@ -23,6 +23,9 @@ #include #include +#include + +#include #include #include @@ -43,6 +46,17 @@ void CoreBindingsPlugin::initializeEngine(QDeclarativeEngine *engine, const char ThemeProxy *theme = new ThemeProxy(context); context->setContextProperty("theme", theme); + + KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(engine); + kdeclarative.initialize(); + QScriptEngine *scriptEngine = kdeclarative.scriptEngine(); +kWarning()<<"AAAAA"<globalObject().property("i18n").isValid(); + //inject the hack only if wasn't injected already + if (!scriptEngine->globalObject().property("i18n").isValid()) { + //binds things like kconfig and icons + kdeclarative.setupBindings(); + } } void CoreBindingsPlugin::registerTypes(const char *uri) From 43a069c68186f5ae8e6d0d8504d06039a2c90cb3 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 1 Nov 2011 19:18:41 +0100 Subject: [PATCH 04/87] bind types for dataengines in the palsmacore import --- declarativeimports/core/CMakeLists.txt | 1 + .../core/corebindingsplugin.cpp | 5 +- .../core/dataenginebindings.cpp | 66 +++++++++++++++ .../core/dataenginebindings_p.h | 83 +++++++++++++++++++ 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 declarativeimports/core/dataenginebindings.cpp create mode 100644 declarativeimports/core/dataenginebindings_p.h diff --git a/declarativeimports/core/CMakeLists.txt b/declarativeimports/core/CMakeLists.txt index 30ad3d3ed..3626816a4 100644 --- a/declarativeimports/core/CMakeLists.txt +++ b/declarativeimports/core/CMakeLists.txt @@ -11,6 +11,7 @@ set(corebindings_SRCS framesvgitem.cpp dialog.cpp tooltip.cpp + dataenginebindings.cpp ) INCLUDE_DIRECTORIES( diff --git a/declarativeimports/core/corebindingsplugin.cpp b/declarativeimports/core/corebindingsplugin.cpp index 041023e25..fe0c95d36 100644 --- a/declarativeimports/core/corebindingsplugin.cpp +++ b/declarativeimports/core/corebindingsplugin.cpp @@ -37,6 +37,7 @@ #include "theme_p.h" #include "dialog.h" #include "tooltip.h" +#include "dataenginebindings_p.h" void CoreBindingsPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri) { @@ -51,12 +52,14 @@ void CoreBindingsPlugin::initializeEngine(QDeclarativeEngine *engine, const char kdeclarative.setDeclarativeEngine(engine); kdeclarative.initialize(); QScriptEngine *scriptEngine = kdeclarative.scriptEngine(); -kWarning()<<"AAAAA"<globalObject().property("i18n").isValid(); + //inject the hack only if wasn't injected already if (!scriptEngine->globalObject().property("i18n").isValid()) { //binds things like kconfig and icons kdeclarative.setupBindings(); } + + registerDataEngineMetaTypes(scriptEngine); } void CoreBindingsPlugin::registerTypes(const char *uri) diff --git a/declarativeimports/core/dataenginebindings.cpp b/declarativeimports/core/dataenginebindings.cpp new file mode 100644 index 000000000..8fb608028 --- /dev/null +++ b/declarativeimports/core/dataenginebindings.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2007 Richard J. Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "dataenginebindings_p.h" + +typedef Plasma::Service *ServicePtr; +QScriptValue qScriptValueFromService(QScriptEngine *engine, const ServicePtr &service) +{ + return engine->newQObject(const_cast(service), QScriptEngine::AutoOwnership, QScriptEngine::PreferExistingWrapperObject); +} + +void serviceFromQScriptValue(const QScriptValue &scriptValue, ServicePtr &service) +{ + QObject *obj = scriptValue.toQObject(); + service = static_cast(obj); +} + +typedef Plasma::DataEngine *DataEnginePtr; +QScriptValue qScriptValueFromDataEngine(QScriptEngine *engine, const DataEnginePtr &dataEngine) +{ + return engine->newQObject(const_cast(dataEngine), QScriptEngine::AutoOwnership, QScriptEngine::PreferExistingWrapperObject); +} + +void dataEngineFromQScriptValue(const QScriptValue &scriptValue, DataEnginePtr &dataEngine) +{ + QObject *obj = scriptValue.toQObject(); + dataEngine = static_cast(obj); +} + +typedef Plasma::ServiceJob *ServiceJobPtr; +QScriptValue qScriptValueFromServiceJob(QScriptEngine *engine, const ServiceJobPtr &serviceJob) +{ + return engine->newQObject(const_cast(serviceJob), QScriptEngine::AutoOwnership, QScriptEngine::PreferExistingWrapperObject); +} + +void serviceJobFromQScriptValue(const QScriptValue &scriptValue, ServiceJobPtr &serviceJob) +{ + QObject *obj = scriptValue.toQObject(); + serviceJob = static_cast(obj); +} + +void registerDataEngineMetaTypes(QScriptEngine *engine) +{ + qRegisterMetaType("Plasma::DataEngine::Data"); + qRegisterMetaType("DataEngine::Data"); + qScriptRegisterMapMetaType(engine); + qScriptRegisterMetaType(engine, qScriptValueFromService, serviceFromQScriptValue); + qScriptRegisterMetaType(engine, qScriptValueFromDataEngine, dataEngineFromQScriptValue); + qScriptRegisterMetaType(engine, qScriptValueFromServiceJob, serviceJobFromQScriptValue); +} + diff --git a/declarativeimports/core/dataenginebindings_p.h b/declarativeimports/core/dataenginebindings_p.h new file mode 100644 index 000000000..17193c1ee --- /dev/null +++ b/declarativeimports/core/dataenginebindings_p.h @@ -0,0 +1,83 @@ +/* + * Copyright 2007 Richard J. Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef DATAENGINEBIND_H +#define DATAENGINEBIND_H + +#include +#include +#include +#include + +#include +#include +#include + +using namespace Plasma; + +Q_DECLARE_METATYPE(DataEngine::Dict) +Q_DECLARE_METATYPE(DataEngine::Data) + +template +QScriptValue qScriptValueFromMap(QScriptEngine *eng, const M &map) +{ + //kDebug() << "qScriptValueFromMap called"; + QScriptValue obj = eng->newObject(); + typename M::const_iterator begin = map.constBegin(); + typename M::const_iterator end = map.constEnd(); + typename M::const_iterator it; + for (it = begin; it != end; ++it) { + if (it.value().type() == QVariant::Hash) { + obj.setProperty(it.key(), qScriptValueFromMap(eng, it.value().toHash())); + } else if (it.value().type() == QVariant::Map) { + obj.setProperty(it.key(), qScriptValueFromMap(eng, it.value().toMap())); + } else { + obj.setProperty(it.key(), qScriptValueFromValue(eng, it.value())); + } + } + + return obj; +} + +template +void qScriptValueToMap(const QScriptValue &value, M &map) +{ + //kDebug() << "qScriptValueToMap called"; + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + map[it.name()] = qscriptvalue_cast(it.value()); + } +} + +template +int qScriptRegisterMapMetaType( + QScriptEngine *engine, + const QScriptValue &prototype = QScriptValue() +#ifndef qdoc + , T * /* dummy */ = 0 +#endif +) +{ + return qScriptRegisterMetaType(engine, qScriptValueFromMap, qScriptValueToMap, prototype); +} + +void registerDataEngineMetaTypes(QScriptEngine *engine); + +#endif // DATAENGINE_H + From 7a325f46581a7ad90dd8df92b28db1d70aee1fab Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 1 Nov 2011 19:27:55 +0100 Subject: [PATCH 05/87] i_p suffix only for stuff not exported from qml general rule: if the header if from a class that will be made available as qml type, foo.h, otherwise foo_p.h --- declarativeimports/core/corebindingsplugin.cpp | 8 ++++---- declarativeimports/core/datamodel.cpp | 2 +- declarativeimports/core/datasource.cpp | 4 ++-- declarativeimports/core/{datasource_p.h => datasource.h} | 0 declarativeimports/core/framesvgitem.cpp | 4 ++-- .../core/{framesvgitem_p.h => framesvgitem.h} | 0 declarativeimports/core/svgitem.cpp | 4 ++-- declarativeimports/core/{svgitem_p.h => svgitem.h} | 0 declarativeimports/core/theme.cpp | 4 ++-- declarativeimports/core/{theme_p.h => theme.h} | 0 10 files changed, 13 insertions(+), 13 deletions(-) rename declarativeimports/core/{datasource_p.h => datasource.h} (100%) rename declarativeimports/core/{framesvgitem_p.h => framesvgitem.h} (100%) rename declarativeimports/core/{svgitem_p.h => svgitem.h} (100%) rename declarativeimports/core/{theme_p.h => theme.h} (100%) diff --git a/declarativeimports/core/corebindingsplugin.cpp b/declarativeimports/core/corebindingsplugin.cpp index fe0c95d36..f08d8b36d 100644 --- a/declarativeimports/core/corebindingsplugin.cpp +++ b/declarativeimports/core/corebindingsplugin.cpp @@ -30,11 +30,11 @@ #include #include -#include "datasource_p.h" +#include "datasource.h" #include "datamodel.h" -#include "framesvgitem_p.h" -#include "svgitem_p.h" -#include "theme_p.h" +#include "framesvgitem.h" +#include "svgitem.h" +#include "theme.h" #include "dialog.h" #include "tooltip.h" #include "dataenginebindings_p.h" diff --git a/declarativeimports/core/datamodel.cpp b/declarativeimports/core/datamodel.cpp index 29da9e13c..0b260af4f 100644 --- a/declarativeimports/core/datamodel.cpp +++ b/declarativeimports/core/datamodel.cpp @@ -18,7 +18,7 @@ */ #include "datamodel.h" -#include "datasource_p.h" +#include "datasource.h" #include diff --git a/declarativeimports/core/datasource.cpp b/declarativeimports/core/datasource.cpp index b33a38728..b29158809 100644 --- a/declarativeimports/core/datasource.cpp +++ b/declarativeimports/core/datasource.cpp @@ -19,7 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "datasource_p.h" +#include "datasource.h" #include "qdeclarativeengine.h" #include "qdeclarativecontext.h" @@ -196,4 +196,4 @@ void DataSource::disconnectSource(const QString &source) } } -#include "datasource_p.moc" +#include "datasource.moc" diff --git a/declarativeimports/core/datasource_p.h b/declarativeimports/core/datasource.h similarity index 100% rename from declarativeimports/core/datasource_p.h rename to declarativeimports/core/datasource.h diff --git a/declarativeimports/core/framesvgitem.cpp b/declarativeimports/core/framesvgitem.cpp index 4c030f356..edfcbc934 100644 --- a/declarativeimports/core/framesvgitem.cpp +++ b/declarativeimports/core/framesvgitem.cpp @@ -17,7 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "framesvgitem_p.h" +#include "framesvgitem.h" #include @@ -130,4 +130,4 @@ void FrameSvgItem::doUpdate() } // Plasma namespace -#include "framesvgitem_p.moc" +#include "framesvgitem.moc" diff --git a/declarativeimports/core/framesvgitem_p.h b/declarativeimports/core/framesvgitem.h similarity index 100% rename from declarativeimports/core/framesvgitem_p.h rename to declarativeimports/core/framesvgitem.h diff --git a/declarativeimports/core/svgitem.cpp b/declarativeimports/core/svgitem.cpp index ae246e717..00e6d2a84 100644 --- a/declarativeimports/core/svgitem.cpp +++ b/declarativeimports/core/svgitem.cpp @@ -17,7 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "svgitem_p.h" +#include "svgitem.h" #include @@ -124,4 +124,4 @@ void SvgItem::updateNeeded() } // Plasma namespace -#include "svgitem_p.moc" +#include "svgitem.moc" diff --git a/declarativeimports/core/svgitem_p.h b/declarativeimports/core/svgitem.h similarity index 100% rename from declarativeimports/core/svgitem_p.h rename to declarativeimports/core/svgitem.h diff --git a/declarativeimports/core/theme.cpp b/declarativeimports/core/theme.cpp index 262afff59..0976fd5f3 100644 --- a/declarativeimports/core/theme.cpp +++ b/declarativeimports/core/theme.cpp @@ -17,7 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ -#include "theme_p.h" +#include "theme.h" #include @@ -299,5 +299,5 @@ int ThemeProxy::enormousIconSize() const return KIconLoader::SizeEnormous; } -#include "theme_p.moc" +#include "theme.moc" diff --git a/declarativeimports/core/theme_p.h b/declarativeimports/core/theme.h similarity index 100% rename from declarativeimports/core/theme_p.h rename to declarativeimports/core/theme.h From f6f9c26fdd97d6befea971f8ff9a1b4fbd3f5151 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 1 Nov 2011 21:30:03 +0100 Subject: [PATCH 06/87] support popup with timeout --- scriptengines/javascript/plasmoid/appletinterface.cpp | 5 +++++ scriptengines/javascript/plasmoid/appletinterface.h | 1 + 2 files changed, 6 insertions(+) diff --git a/scriptengines/javascript/plasmoid/appletinterface.cpp b/scriptengines/javascript/plasmoid/appletinterface.cpp index 7dcfa8f2a..cc70e8b27 100644 --- a/scriptengines/javascript/plasmoid/appletinterface.cpp +++ b/scriptengines/javascript/plasmoid/appletinterface.cpp @@ -463,6 +463,11 @@ void PopupAppletInterface::showPopup() popupApplet()->showPopup(); } +void PopupAppletInterface::showPopup(int timeout) +{ + popupApplet()->showPopup(timeout); +} + void PopupAppletInterface::setPopupWidget(QGraphicsWidget *widget) { popupApplet()->setGraphicsWidget(widget); diff --git a/scriptengines/javascript/plasmoid/appletinterface.h b/scriptengines/javascript/plasmoid/appletinterface.h index d2cd9a4b5..53d0a2c0a 100644 --- a/scriptengines/javascript/plasmoid/appletinterface.h +++ b/scriptengines/javascript/plasmoid/appletinterface.h @@ -372,6 +372,7 @@ public Q_SLOTS: void togglePopup(); void hidePopup(); void showPopup(); + void showPopup(int timeout); }; From 5282287b55154b3598fa9a96f0833fc30f222479 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 1 Nov 2011 22:45:38 +0100 Subject: [PATCH 07/87] anchors a page to its container --- declarativeimports/plasmacomponents/qml/PageStack.js | 2 ++ declarativeimports/plasmacomponents/qml/PageStack.qml | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/PageStack.js b/declarativeimports/plasmacomponents/qml/PageStack.js index b08b6823a..eaac5ff8f 100644 --- a/declarativeimports/plasmacomponents/qml/PageStack.js +++ b/declarativeimports/plasmacomponents/qml/PageStack.js @@ -165,6 +165,8 @@ function initPage(page, properties) { page.pageStack = root; } + page.anchors.fill = container + return container; } diff --git a/declarativeimports/plasmacomponents/qml/PageStack.qml b/declarativeimports/plasmacomponents/qml/PageStack.qml index e4f0c3f36..e604c5302 100644 --- a/declarativeimports/plasmacomponents/qml/PageStack.qml +++ b/declarativeimports/plasmacomponents/qml/PageStack.qml @@ -281,8 +281,9 @@ Item { { transitionAnimationRunning = true; internal.ongoingTransitionCount++; - if (root.visible) + if (root.visible) { internal.setPageStatus(page, (state == "") ? PageStatus.Activating : PageStatus.Deactivating); + } } // Called when a transition has ended. @@ -449,10 +450,11 @@ Item { if (owner != container) { // container is not the owner of the page - re-parent back to original owner page.visible = false; + page.anchors.fill = undefined page.parent = owner; } } -print("KILLING"+container+" "+page+" "+owner) + container.destroy(); } } From 147df3a274edea749e7b076ecb16abb233113400 Mon Sep 17 00:00:00 2001 From: Mark Gaiser Date: Tue, 1 Nov 2011 23:51:42 +0100 Subject: [PATCH 08/87] Updated Button.qml form PlasmaComponents to have: - Animations - A state machine - More margin when an icon is used - A few cleanups REVIEW: 103020 --- .../plasmacomponents/qml/Button.qml | 114 +++++++++++------- 1 file changed, 73 insertions(+), 41 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index d7b62d754..3bed4ab35 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright (C) 2011 by Mark Gaiser * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -33,37 +34,36 @@ Item { signal clicked() + width: Math.max(50, icon.width + label.paintedWidth + surfaceNormal.margins.left + surfaceNormal.margins.right) + ((icon.valid) ? surfaceNormal.margins.left : 0); + height: Math.max(20, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom) - function pressButton() { - if (button.enabled) - surface.prefix = "pressed"; - } - - function releaseButton() { - if (!button.enabled) - return; - - if (button.checkable) - button.checked = !button.checked; - - // TODO: "checked" state must have special graphics? - if (button.checked) - surface.prefix = "pressed"; - else - surface.prefix = "normal"; - - button.clicked(); - button.forceActiveFocus(); - } - - width: Math.max(50, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) - height: Math.max(20, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) // TODO: needs to define if there will be specific graphics for // disabled buttons opacity: enabled ? 1.0 : 0.5 - Keys.onSpacePressed: pressButton(); - Keys.onReturnPressed: pressButton(); + function pressButton() { + if(button.enabled) { + buttonContent.state = "pressed" + } + } + + function releaseButton() { + if(button.enabled) { + buttonContent.state = "normal" + + if (button.checkable) { + button.checked = !button.checked; + } + + // TODO: "checked" state must have special graphics? + + button.clicked(); + button.forceActiveFocus(); + } + } + + Keys.onSpacePressed: pressButton() + Keys.onReturnPressed: pressButton() Keys.onReleased: { if (event.key == Qt.Key_Space || event.key == Qt.Key_Return) @@ -85,21 +85,57 @@ Item { anchors.fill: parent } + // The normal button state PlasmaCore.FrameSvgItem { - id: surface + id: surfaceNormal anchors.fill: parent imagePath: "widgets/button" prefix: "normal" } + // The pressed state + PlasmaCore.FrameSvgItem { + id: surfacePressed + + anchors.fill: parent + imagePath: "widgets/button" + prefix: "pressed" + opacity: 0 + } + Item { + id: buttonContent + + states: [ + State { name: "normal" }, + State { name: "pressed" } + ] + transitions: [ + Transition { + to: "normal" + // Cross fade from pressed to normal + ParallelAnimation { + NumberAnimation { target: surfaceNormal; property: "opacity"; to: 1; duration: 100 } + NumberAnimation { target: surfacePressed; property: "opacity"; to: 0; duration: 100 } + } + }, + Transition { + to: "pressed" + // Cross fade from normal to pressed + ParallelAnimation { + NumberAnimation { target: surfaceNormal; property: "opacity"; to: 0; duration: 100 } + NumberAnimation { target: surfacePressed; property: "opacity"; to: 1; duration: 100 } + } + } + ] + anchors { fill: parent - leftMargin: surface.margins.left - topMargin: surface.margins.top - rightMargin: surface.margins.right - bottomMargin: surface.margins.bottom + leftMargin: surfaceNormal.margins.left + topMargin: surfaceNormal.margins.top + rightMargin: surfaceNormal.margins.right + bottomMargin: surfaceNormal.margins.bottom } IconLoader { @@ -118,9 +154,11 @@ Item { anchors { top: parent.top bottom: parent.bottom - left: icon.valid ? icon.right : parent.left right: parent.right + left: icon.valid ? icon.right : parent.left + leftMargin: icon.valid ? parent.anchors.leftMargin : 0 } + font.capitalization: theme.defaultFont.capitalization font.family: theme.defaultFont.family font.italic: theme.defaultFont.italic @@ -141,13 +179,8 @@ Item { anchors.fill: parent hoverEnabled: true - - onPressed: { - pressButton(); - } - onReleased: { - releaseButton(); - } + onPressed: pressButton() + onReleased: releaseButton() onEntered: { shadow.state = "hover" } @@ -161,5 +194,4 @@ Item { } } } -} - +} \ No newline at end of file From 67ab75c0fd00457cb2ef32415841ca0dfd0f6288 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 2 Nov 2011 14:48:41 +0100 Subject: [PATCH 09/87] the catalog is called "plasma_applet_"+pluginname --- scriptengines/javascript/plasmoid/declarativeappletscript.cpp | 2 +- scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scriptengines/javascript/plasmoid/declarativeappletscript.cpp b/scriptengines/javascript/plasmoid/declarativeappletscript.cpp index 249f5e3c0..005894a2f 100644 --- a/scriptengines/javascript/plasmoid/declarativeappletscript.cpp +++ b/scriptengines/javascript/plasmoid/declarativeappletscript.cpp @@ -82,7 +82,7 @@ bool DeclarativeAppletScript::init() { m_declarativeWidget = new Plasma::DeclarativeWidget(applet()); m_declarativeWidget->setInitializationDelayed(true); - KGlobal::locale()->insertCatalog(description().pluginName()); + KGlobal::locale()->insertCatalog("plasma_applet_" % description().pluginName()); //make possible to import extensions from the package //FIXME: probably to be removed, would make possible to use native code from within the package :/ diff --git a/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp b/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp index f879ae94b..112c26520 100644 --- a/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp +++ b/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp @@ -314,7 +314,7 @@ bool SimpleJavaScriptApplet::init() this, SLOT(extenderItemRestored(Plasma::ExtenderItem*))); connect(applet(), SIGNAL(activate()), this, SLOT(activate())); - KGlobal::locale()->insertCatalog(description().pluginName()); + KGlobal::locale()->insertCatalog("plasma_applet_" % description().pluginName()); setupObjects(); AppletAuthorization auth(this); From 270b6296b91f1f2e26f99004f8cf14afb287f338 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 2 Nov 2011 18:15:17 +0100 Subject: [PATCH 10/87] fallback when there is no corona autonomous positioning when there is no corona (usually relies on addoffscreenwidget and popupposition from it) --- declarativeimports/core/dialog.cpp | 66 +++++++++++++++++++++++++++++- declarativeimports/core/dialog.h | 2 + 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/declarativeimports/core/dialog.cpp b/declarativeimports/core/dialog.cpp index 3b063f36e..6470ac363 100644 --- a/declarativeimports/core/dialog.cpp +++ b/declarativeimports/core/dialog.cpp @@ -20,7 +20,9 @@ #include "dialog.h" #include "declarativeitemcontainer_p.h" +#include #include +#include #include #include #include @@ -31,6 +33,9 @@ #include +int DialogProxy::offscreenX = 0; +int DialogProxy::offscreenY = 0; + DialogMargins::DialogMargins(Plasma::Dialog *dialog, QObject *parent) : QObject(parent), m_dialog(dialog) @@ -171,6 +176,12 @@ void DialogProxy::syncMainItem() } } m_dialog->setGraphicsWidget(widget); + + if (!qobject_cast(scene)) { + offscreenX -= 1024; + offscreenY -= 1024; + widget->setPos(offscreenX, offscreenY); + } } bool DialogProxy::isVisible() const @@ -199,7 +210,60 @@ QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const if (corona) { return corona->popupPosition(item, m_dialog->size(), (Qt::AlignmentFlag)alignment); } else { - return QPoint(); + + QList views = item->scene()->views(); + + if (views.size() < 1) { + return QPoint(); + } + + QGraphicsView *view = 0; + if (views.size() == 1) { + view = views[0]; + } else { + QGraphicsView *found = 0; + QGraphicsView *possibleFind = 0; + foreach (QGraphicsView *v, views) { + if (v->sceneRect().intersects(item->sceneBoundingRect()) || + v->sceneRect().contains(item->scenePos())) { + if (v->isActiveWindow()) { + found = v; + } else { + possibleFind = v; + } + } + } + view = found ? found : possibleFind; + } + + if (!view) { + return QPoint(); + } + + //swap direction if necessary + if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) { + if (alignment == Qt::AlignRight) { + alignment = Qt::AlignLeft; + } else { + alignment = Qt::AlignRight; + } + } + + int xOffset = 0; + + if (alignment == Qt::AlignCenter) { + xOffset = item->boundingRect().width()/2 - m_dialog->width()/2; + } else if (alignment == Qt::AlignRight) { + xOffset = item->boundingRect().width() - m_dialog->width(); + } + + const QRect avail = QApplication::desktop()->availableGeometry(view); + QPoint menuPos = view->mapToGlobal(view->mapFromScene(item->scenePos()+QPoint(xOffset, item->boundingRect().height()))); + + if (menuPos.y() + m_dialog->height() > avail.bottom()) { + menuPos = view->mapToGlobal(view->mapFromScene(item->scenePos() - QPoint(-xOffset, m_dialog->height()))); + } + return menuPos; } } diff --git a/declarativeimports/core/dialog.h b/declarativeimports/core/dialog.h index a871a80d1..28ee62858 100644 --- a/declarativeimports/core/dialog.h +++ b/declarativeimports/core/dialog.h @@ -148,6 +148,8 @@ private: DialogMargins *m_margins; bool m_activeWindow; Plasma::Location m_location; + static int offscreenX; + static int offscreenY; }; #endif From 41bd519f43041377120f52fb259c1cb24c0e20ee Mon Sep 17 00:00:00 2001 From: Mark Gaiser Date: Wed, 2 Nov 2011 21:28:30 +0100 Subject: [PATCH 11/87] Made the icon property a QVariant. If a string is passed a KIcon(string) object will be created. If a QIcon is passed that will be used. REVIEW: 103009 --- declarativeimports/qtextracomponents/CMakeLists.txt | 2 +- declarativeimports/qtextracomponents/qiconitem.cpp | 10 ++++++++-- declarativeimports/qtextracomponents/qiconitem.h | 5 +++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/declarativeimports/qtextracomponents/CMakeLists.txt b/declarativeimports/qtextracomponents/CMakeLists.txt index 3264ae8e2..a78644ff2 100644 --- a/declarativeimports/qtextracomponents/CMakeLists.txt +++ b/declarativeimports/qtextracomponents/CMakeLists.txt @@ -19,7 +19,7 @@ qt4_automoc(${qtextracomponents_SRCS}) add_library(qtextracomponentsplugin SHARED ${qtextracomponents_SRCS}) -target_link_libraries(qtextracomponentsplugin ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) +target_link_libraries(qtextracomponentsplugin ${KDE4_KDEUI_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) install(TARGETS qtextracomponentsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/qtextracomponents) diff --git a/declarativeimports/qtextracomponents/qiconitem.cpp b/declarativeimports/qtextracomponents/qiconitem.cpp index d72381e47..ef96c3df4 100644 --- a/declarativeimports/qtextracomponents/qiconitem.cpp +++ b/declarativeimports/qtextracomponents/qiconitem.cpp @@ -19,6 +19,7 @@ #include "qiconitem.h" +#include #include @@ -34,9 +35,14 @@ QIconItem::~QIconItem() { } -void QIconItem::setIcon(const QIcon &icon) +void QIconItem::setIcon(QVariant &icon) { - m_icon = icon; + if(icon.canConvert()) { + m_icon = icon.value(); + } + else if(icon.canConvert()) { + m_icon = KIcon(icon.toString()); + } update(); } diff --git a/declarativeimports/qtextracomponents/qiconitem.h b/declarativeimports/qtextracomponents/qiconitem.h index 9972a98fe..e31059c46 100644 --- a/declarativeimports/qtextracomponents/qiconitem.h +++ b/declarativeimports/qtextracomponents/qiconitem.h @@ -21,19 +21,20 @@ #include #include +#include class QIconItem : public QDeclarativeItem { Q_OBJECT - Q_PROPERTY(QIcon icon READ icon WRITE setIcon) + Q_PROPERTY(QVariant icon READ icon WRITE setIcon) Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) public: QIconItem(QDeclarativeItem *parent=0); ~QIconItem(); - void setIcon(const QIcon &icon); + void setIcon(QVariant &icon); QIcon icon() const; void setSmooth(const bool smooth); From 3accb9baf530f17585a85dc288dc296dead35a23 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 2 Nov 2011 21:38:44 +0100 Subject: [PATCH 12/87] n mSize property in fontproxy: like em for css --- declarativeimports/core/theme.cpp | 6 ++ declarativeimports/core/theme.h | 7 ++ .../plasmacomponents/qml/AppManager.js | 85 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 declarativeimports/plasmacomponents/qml/AppManager.js diff --git a/declarativeimports/core/theme.cpp b/declarativeimports/core/theme.cpp index 0976fd5f3..702503d1f 100644 --- a/declarativeimports/core/theme.cpp +++ b/declarativeimports/core/theme.cpp @@ -64,6 +64,8 @@ FontProxy::FontProxy(Plasma::Theme::FontRole role, QObject *parent) this, SIGNAL(weightChanged())); connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SIGNAL(wordSpacingChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SIGNAL(mSizeChanged())); } FontProxy::~FontProxy() @@ -140,6 +142,10 @@ qreal FontProxy::wordSpacing() const return Plasma::Theme::defaultTheme()->font(m_fontRole).wordSpacing(); } +QSize FontProxy::mSize() const +{ + return QFontMetrics(Plasma::Theme::defaultTheme()->font(m_fontRole)).boundingRect("M").size(); +} //********** Theme ************* diff --git a/declarativeimports/core/theme.h b/declarativeimports/core/theme.h index e83e492e2..389cfb5cb 100644 --- a/declarativeimports/core/theme.h +++ b/declarativeimports/core/theme.h @@ -41,6 +41,7 @@ class FontProxy : public QObject Q_PROPERTY(bool underline READ underline NOTIFY underlineChanged ) Q_PROPERTY(Weight weight READ weight NOTIFY weightChanged ) Q_PROPERTY(qreal wordSpacing READ wordSpacing NOTIFY wordSpacingChanged ) + Q_PROPERTY(QSize mSize READ mSize NOTIFY mSizeChanged ) Q_ENUMS(Capitalization) Q_ENUMS(Weight) @@ -80,6 +81,11 @@ public: Weight weight() const; qreal wordSpacing() const; + /** + * @return The size of an uppercase M in this font + */ + QSize mSize() const; + Q_SIGNALS: void boldChanged(); void capitalizationChanged(); @@ -92,6 +98,7 @@ Q_SIGNALS: void underlineChanged(); void weightChanged(); void wordSpacingChanged(); + void mSizeChanged(); private: Plasma::Theme::FontRole m_fontRole; diff --git a/declarativeimports/plasmacomponents/qml/AppManager.js b/declarativeimports/plasmacomponents/qml/AppManager.js new file mode 100644 index 000000000..daed77a05 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/AppManager.js @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function rootObject() { + var next = parent + while (next && next.parent) + next = next.parent + return next +} + +function findParent(child, propertyName) { + if (!child) + return null + var next = child.parent + while (next && !next.hasOwnProperty(propertyName)) + next = next.parent + return next +} + +function sceneX(item) { + // Binding may cause that this function is evaluated even when item is undefined, + // but in that case the Binding isn't active however so we can safely return 0 + var x = 0 + if (item) { + x = item.x + var p = item.parent + while (p) { + x += p.x + p = p.parent + } + } + return x +} + +function sceneY(item) { + // Binding may cause that this function is evaluated even when item is undefined, + // but in that case the Binding isn't active however so we can safely return 0 + var y = 0 + if (item) { + y = item.y + var p = item.parent + while (p) { + y += p.y + p = p.parent + } + } + return y +} From f83a899bc86c6dc130f7678337ac0544402efb46 Mon Sep 17 00:00:00 2001 From: Mark Gaiser Date: Wed, 2 Nov 2011 23:12:46 +0100 Subject: [PATCH 13/87] Lets use const. REVIEW: 103009 --- declarativeimports/qtextracomponents/qiconitem.cpp | 2 +- declarativeimports/qtextracomponents/qiconitem.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/declarativeimports/qtextracomponents/qiconitem.cpp b/declarativeimports/qtextracomponents/qiconitem.cpp index ef96c3df4..378a0eac7 100644 --- a/declarativeimports/qtextracomponents/qiconitem.cpp +++ b/declarativeimports/qtextracomponents/qiconitem.cpp @@ -35,7 +35,7 @@ QIconItem::~QIconItem() { } -void QIconItem::setIcon(QVariant &icon) +void QIconItem::setIcon(const QVariant &icon) { if(icon.canConvert()) { m_icon = icon.value(); diff --git a/declarativeimports/qtextracomponents/qiconitem.h b/declarativeimports/qtextracomponents/qiconitem.h index e31059c46..fa89057e8 100644 --- a/declarativeimports/qtextracomponents/qiconitem.h +++ b/declarativeimports/qtextracomponents/qiconitem.h @@ -34,7 +34,7 @@ public: QIconItem(QDeclarativeItem *parent=0); ~QIconItem(); - void setIcon(QVariant &icon); + void setIcon(const QVariant &icon); QIcon icon() const; void setSmooth(const bool smooth); From 2bb8101e6f92bd08aff2f74bb0e53746992fca61 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 3 Nov 2011 13:48:11 +0100 Subject: [PATCH 14/87] check the pointer --- declarativeimports/core/tooltip.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/declarativeimports/core/tooltip.cpp b/declarativeimports/core/tooltip.cpp index 966450ce5..603bfd277 100644 --- a/declarativeimports/core/tooltip.cpp +++ b/declarativeimports/core/tooltip.cpp @@ -70,6 +70,9 @@ void ToolTipProxy::setTarget(QGraphicsObject *target) void ToolTipProxy::syncTarget() { + if (!m_target) { + return; + } // find the scene QGraphicsScene *scene = m_target.data()->scene(); if (!scene) { From 478cd9d3f0bdd18d985da070761529ffeecf04de Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 3 Nov 2011 14:46:05 +0100 Subject: [PATCH 15/87] add Dialogs CommonDialog QueryDialog SelectionDialog the base Dialog is still not exported in future version on the desktop, QueryDialog will create a standard qt dialog instead --- declarativeimports/core/dialog.cpp | 55 ++++-- declarativeimports/core/dialog.h | 7 +- .../plasmacomponents/qml/CommonDialog.qml | 185 ++++++++++++++++++ .../plasmacomponents/qml/Dialog.qml | 161 +++++++++++++++ .../plasmacomponents/qml/QueryDialog.qml | 122 ++++++++++++ .../plasmacomponents/qml/SelectionDialog.qml | 135 +++++++++++++ .../plasmacomponents/qml/qmldir | 4 +- 7 files changed, 654 insertions(+), 15 deletions(-) create mode 100644 declarativeimports/plasmacomponents/qml/CommonDialog.qml create mode 100644 declarativeimports/plasmacomponents/qml/Dialog.qml create mode 100644 declarativeimports/plasmacomponents/qml/QueryDialog.qml create mode 100644 declarativeimports/plasmacomponents/qml/SelectionDialog.qml diff --git a/declarativeimports/core/dialog.cpp b/declarativeimports/core/dialog.cpp index 6470ac363..45fb30413 100644 --- a/declarativeimports/core/dialog.cpp +++ b/declarativeimports/core/dialog.cpp @@ -201,17 +201,40 @@ void DialogProxy::setVisible(const bool visible) } } -QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const +QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) { - if (!item) { - return QPoint(); + QGraphicsObject *actualItem = item; + + //if no item is passed search the root item in order to figure out the view + if (!actualItem) { + actualItem = qobject_cast(parent()); + + //search the root object + while (true) { + QGraphicsObject *ancestor = qobject_cast(actualItem->parent()); + + if (ancestor) { + actualItem = ancestor; + } else { + break; + } + } + if (!actualItem) { + return QPoint(); + } } - Plasma::Corona *corona = qobject_cast(item->scene()); - if (corona) { - return corona->popupPosition(item, m_dialog->size(), (Qt::AlignmentFlag)alignment); + + //ensure the dialog has the proper size + syncMainItem(); + m_dialog->syncToGraphicsWidget(); + + Plasma::Corona *corona = qobject_cast(actualItem->scene()); + if (corona && item) { + return corona->popupPosition(actualItem, m_dialog->size(), (Qt::AlignmentFlag)alignment); } else { - QList views = item->scene()->views(); + QList views = actualItem->scene()->views(); + if (views.size() < 1) { return QPoint(); @@ -223,9 +246,10 @@ QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const } else { QGraphicsView *found = 0; QGraphicsView *possibleFind = 0; + foreach (QGraphicsView *v, views) { - if (v->sceneRect().intersects(item->sceneBoundingRect()) || - v->sceneRect().contains(item->scenePos())) { + if (v->sceneRect().intersects(actualItem->sceneBoundingRect()) || + v->sceneRect().contains(actualItem->scenePos())) { if (v->isActiveWindow()) { found = v; } else { @@ -240,6 +264,11 @@ QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const return QPoint(); } + //if no item was explicitly specified, align the dialog in the center of the parent view + if (!item) { + return view->geometry().center() - QPoint(m_dialog->width()/2, m_dialog->height()/2); + } + //swap direction if necessary if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) { if (alignment == Qt::AlignRight) { @@ -252,16 +281,16 @@ QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const int xOffset = 0; if (alignment == Qt::AlignCenter) { - xOffset = item->boundingRect().width()/2 - m_dialog->width()/2; + xOffset = actualItem->boundingRect().width()/2 - m_dialog->width()/2; } else if (alignment == Qt::AlignRight) { - xOffset = item->boundingRect().width() - m_dialog->width(); + xOffset = actualItem->boundingRect().width() - m_dialog->width(); } const QRect avail = QApplication::desktop()->availableGeometry(view); - QPoint menuPos = view->mapToGlobal(view->mapFromScene(item->scenePos()+QPoint(xOffset, item->boundingRect().height()))); + QPoint menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos()+QPoint(xOffset, actualItem->boundingRect().height()))); if (menuPos.y() + m_dialog->height() > avail.bottom()) { - menuPos = view->mapToGlobal(view->mapFromScene(item->scenePos() - QPoint(-xOffset, m_dialog->height()))); + menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos() - QPoint(-xOffset, m_dialog->height()))); } return menuPos; } diff --git a/declarativeimports/core/dialog.h b/declarativeimports/core/dialog.h index 28ee62858..5e307bea3 100644 --- a/declarativeimports/core/dialog.h +++ b/declarativeimports/core/dialog.h @@ -119,8 +119,13 @@ public: QObject *margins() const; + /** + * @returns The suggested screen position for the popup + * @arg item the item the popup has to be positioned relatively to. if null, the popup will be positioned in the center of the window + * @arg alignment alignment of the popup compared to the item + */ //FIXME: alignment should be Qt::AlignmentFlag - Q_INVOKABLE QPoint popupPosition(QGraphicsObject *item, int alignment=Qt::AlignLeft) const; + Q_INVOKABLE QPoint popupPosition(QGraphicsObject *item, int alignment=Qt::AlignLeft) ; //FIXME:: Qt::WidgetAttribute should be already Q_INVOKABLE void setAttribute(int attribute, bool on); diff --git a/declarativeimports/plasmacomponents/qml/CommonDialog.qml b/declarativeimports/plasmacomponents/qml/CommonDialog.qml new file mode 100644 index 000000000..2232ab79a --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/CommonDialog.qml @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Marco Martin +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import "." 0.1 + +Dialog { + id: root + + property alias titleText: titleAreaText.text + property url titleIcon + property variant buttonTexts: [] + property bool privateCloseIcon: false + + signal buttonClicked(int index) + + onButtonTextsChanged: { + for (var i = buttonRow.children.length; i > 0; --i) { + buttonRow.children[i - 1].destroy() + } + for (var j = 0; j < buttonTexts.length; ++j) { + var button = buttonComponent.createObject(buttonRow) + button.text = buttonTexts[j] + button.index = j + } + } + + Component { + id: buttonComponent + Button { + property int index + + onClicked: { + if (root.status == DialogStatus.Open) { + root.buttonClicked(index) + root.close() + } + } + } + } + + QtObject { + id: internal + + function buttonWidth() { + switch (buttonTexts.length) { + case 0: return 0 + case 1: return Math.round((800 - 3 * 4) / 2) + default: return (buttonContainer.width - (buttonTexts.length + 1) * + 4) / buttonTexts.length + } + } + + function iconSource() { + return root.titleIcon + } + } + + title: PlasmaCore.FrameSvgItem { + imagePath: "widgets/extender-dragger" + prefix: "root" + anchors.left: parent.left + anchors.right: parent.right + //FIXME: +5 because of Plasma::Dialog margins + height: titleAreaText.paintedHeight + margins.top + margins.bottom + + LayoutMirroring.enabled: privateCloseIcon ? false : undefined + LayoutMirroring.childrenInherit: true + + Item { + id: titleLayoutHelper // needed to make the text mirror correctly + + anchors { + left: parent.left + right: titleAreaIcon.source == "" ? parent.right : titleAreaIcon.left + top: parent.top + bottom: parent.bottom + leftMargin: parent.margins.left + rightMargin: parent.margins.right + topMargin: parent.margins.top + bottomMargin: parent.margins.bottom + } + + Label { + id: titleAreaText + + LayoutMirroring.enabled: root.LayoutMirroring.enabled + + anchors.fill: parent + + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + Image { + id: titleAreaIcon + + anchors.right: parent.right + anchors.rightMargin: 4 + anchors.verticalCenter: parent.verticalCenter + source: internal.iconSource() + sourceSize.height: 16 + sourceSize.width: 16 + + MouseArea { + id: iconMouseArea + + property bool pressCancelled + + anchors.centerIn: parent + width: parent.width + 4 + height: parent.height + 4 + enabled: privateCloseIcon && root.status == DialogStatus.Open + + onPressed: { + pressCancelled = false + } + onClicked: { + if (!pressCancelled) + root.reject() + } + onExited: pressCancelled = true + } + } + } + + buttons: Item { + id: buttonContainer + + LayoutMirroring.enabled: false + LayoutMirroring.childrenInherit: true + + width: parent.width + height: buttonTexts.length ? 48 + 2 * 2 : 0 + + Row { + id: buttonRow + objectName: "buttonRow" + anchors.centerIn: parent + spacing: 4 + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/Dialog.qml b/declarativeimports/plasmacomponents/qml/Dialog.qml new file mode 100644 index 000000000..c5696594c --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/Dialog.qml @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Marco Martin +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore +import "AppManager.js" as Utils +import "." 0.1 + +Item { + id: root + + property alias title: titleBar.children + property alias content: contentItem.children + property alias buttons: buttonItem.children +// property alias visualParent: dialog.visualParent + property int status: DialogStatus.Closed + + + property alias privateTitleHeight: titleBar.height + property alias privateButtonsHeight: buttonItem.height + + signal accepted + signal rejected + signal clickedOutside + + function open() + { + var pos = dialog.popupPosition(null, Qt.alignCenter) + dialog.x = pos.x + dialog.y = pos.y + + dialog.visible = true + dialog.focus = true + } + + function accept() + { + if (status == DialogStatus.Open) { + dialog.visible = false + accepted() + } + } + + function reject() { + if (status == DialogStatus.Open) { + dialog.visible = false + rejected() + } + } + + function close() { + dialog.visible = false + } + + visible: false + + PlasmaCore.Dialog { + id: dialog + + + //onFaderClicked: root.clickedOutside() + property Item rootItem + + //state: "Hidden" + visible: false + onVisibleChanged: { + if (visible) { + status = DialogStatus.Open + } else { + status = DialogStatus.Closed + } + } + + mainItem: Item { + width: theme.defaultFont.mSize.width * 40 + height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonItem.childrenRect.height + + // Consume all key events that are not processed by children + Keys.onPressed: event.accepted = true + Keys.onReleased: event.accepted = true + + Item { + id: titleBar + + height: childrenRect.height + anchors { + top: parent.top + left: parent.left + right: parent.right + } + } + + Item { + id: contentItem + + clip: true + anchors { + top: titleBar.bottom + left: parent.left + right: parent.right + bottom: buttonItem.top + } + } + + Item { + id: buttonItem + + height: childrenRect.height + clip: true + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + } + } + + Component.onCompleted: { + rootItem = Utils.rootObject() + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/QueryDialog.qml b/declarativeimports/plasmacomponents/qml/QueryDialog.qml new file mode 100644 index 000000000..383a5b09b --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/QueryDialog.qml @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Marco Martin +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 + +import "." 0.1 + +CommonDialog { + id: root + objectName: "root" + + property string message + property string acceptButtonText + property string rejectButtonText + property alias icon: root.titleIcon // for backwards compatibility + + onAcceptButtonTextChanged: internal.updateButtonTexts() + onRejectButtonTextChanged: internal.updateButtonTexts() + + onButtonClicked: { + if (acceptButtonText && index == 0) + accepted() + else + rejected() + } + + content: Item { + implicitHeight: Math.min(theme.defaultFont.mSize.height*12, label.paintedHeight+12) + width: parent.width + + Item { + anchors { + top: parent.top; topMargin: 6 + bottom: parent.bottom; bottomMargin: 6 + left: parent.left; leftMargin: 6 + right: parent.right + } + + Flickable { + id: flickable + width: parent.width + height: parent.height + anchors { left: parent.left; top: parent.top } + contentHeight: label.paintedHeight + flickableDirection: Flickable.VerticalFlick + clip: true + interactive: contentHeight > height + + Label { + id: label + anchors { right: parent.right } + width: flickable.width + wrapMode: Text.WordWrap + text: root.message + horizontalAlignment: Text.AlignLeft + } + } + + ScrollBar { + id: scrollBar + height: parent.height + anchors { top: flickable.top; right: flickable.right } + flickableItem: flickable + interactive: false + orientation: Qt.Vertical + //platformInverted: root.platformInverted + } + } + } + + QtObject { + id: internal + + function updateButtonTexts() { + var newButtonTexts = [] + if (acceptButtonText) + newButtonTexts.push(acceptButtonText) + if (rejectButtonText) + newButtonTexts.push(rejectButtonText) + root.buttonTexts = newButtonTexts + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/SelectionDialog.qml b/declarativeimports/plasmacomponents/qml/SelectionDialog.qml new file mode 100644 index 000000000..60f3349a6 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/SelectionDialog.qml @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Marco Martin +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 + +import "." 0.1 + +CommonDialog { + id: root + + // Common API + property alias model: listView.model + property int selectedIndex: -1 + property Component delegate: defaultDelegate + + privateCloseIcon: true + + Component { + id: defaultDelegate + + Label { + //platformInverted: root.platformInverted + text: modelData + MouseArea { + anchors.fill: parent + onClicked: { + selectedIndex = index + root.accept() + } + } + + Keys.onPressed: { + if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) + scrollBar.flash() + } + } + } + + content: Item { + id: contentItem + + width: theme.defaultFont.mSize.width * 80 + height: theme.defaultFont.mSize.height * 12 + + Item { + // Clipping item with bottom margin added to align content with rounded background graphics + id: clipItem + anchors.fill: parent + anchors.bottomMargin: 4 + clip: true + ListView { + id: listView + + currentIndex : -1 + width: contentItem.width + height: contentItem.height + delegate: root.delegate + clip: true + + Keys.onPressed: { + if (event.key == Qt.Key_Up || event.key == Qt.Key_Down + || event.key == Qt.Key_Left || event.key == Qt.Key_Right + || event.key == Qt.Key_Select || event.key == Qt.Key_Enter + || event.key == Qt.Key_Return) { + listView.currentIndex = 0 + event.accepted = true + } + } + } + } + ScrollBar { + id: scrollBar + flickableItem: listView + visible: listView.contentHeight > contentItem.height + //platformInverted: root.platformInverted + anchors { top: clipItem.top; right: clipItem.right } + } + } + + onClickedOutside: { + reject() + } + + onStatusChanged: { + if (status == DialogStatus.Opening) { + if (listView.currentItem != null) { + listView.currentItem.focus = false + } + listView.currentIndex = -1 + listView.positionViewAtIndex(0, ListView.Beginning) + } + else if (status == DialogStatus.Open) { + listView.focus = true + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/qmldir b/declarativeimports/plasmacomponents/qml/qmldir index 1ebd340e8..f0940f3ce 100644 --- a/declarativeimports/plasmacomponents/qml/qmldir +++ b/declarativeimports/plasmacomponents/qml/qmldir @@ -24,7 +24,9 @@ ToolBar 0.1 ToolBar.qml ToolButton 0.1 ToolButton.qml ListItem 0.1 ListItem.qml - +CommonDialog 0.1 CommonDialog.qml +QueryDialog 0.1 QueryDialog.qml +SelectionDialog 0.1 SelectionDialog.qml Page 0.1 Page.qml PageStack 0.1 PageStack.qml From a462112815b96ecf4c249b022f8b668be099a388 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 3 Nov 2011 16:53:11 +0100 Subject: [PATCH 16/87] fix icon loading --- .../plasmacomponents/qml/CommonDialog.qml | 37 ++++--------------- .../plasmacomponents/qml/QueryDialog.qml | 1 - 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/CommonDialog.qml b/declarativeimports/plasmacomponents/qml/CommonDialog.qml index 2232ab79a..3aeb5724e 100644 --- a/declarativeimports/plasmacomponents/qml/CommonDialog.qml +++ b/declarativeimports/plasmacomponents/qml/CommonDialog.qml @@ -48,7 +48,7 @@ Dialog { id: root property alias titleText: titleAreaText.text - property url titleIcon + property string titleIcon property variant buttonTexts: [] property bool privateCloseIcon: false @@ -111,8 +111,8 @@ Dialog { id: titleLayoutHelper // needed to make the text mirror correctly anchors { - left: parent.left - right: titleAreaIcon.source == "" ? parent.right : titleAreaIcon.left + right: parent.right + left: titleAreaIcon.source == "" ? parent.left : titleAreaIcon.right top: parent.top bottom: parent.bottom leftMargin: parent.margins.left @@ -134,35 +134,14 @@ Dialog { } } - Image { + IconLoader { id: titleAreaIcon - - anchors.right: parent.right + width: theme.iconSizeSmall + height: theme.iconSizeSmall + source: titleIcon + anchors.left: parent.left anchors.rightMargin: 4 anchors.verticalCenter: parent.verticalCenter - source: internal.iconSource() - sourceSize.height: 16 - sourceSize.width: 16 - - MouseArea { - id: iconMouseArea - - property bool pressCancelled - - anchors.centerIn: parent - width: parent.width + 4 - height: parent.height + 4 - enabled: privateCloseIcon && root.status == DialogStatus.Open - - onPressed: { - pressCancelled = false - } - onClicked: { - if (!pressCancelled) - root.reject() - } - onExited: pressCancelled = true - } } } diff --git a/declarativeimports/plasmacomponents/qml/QueryDialog.qml b/declarativeimports/plasmacomponents/qml/QueryDialog.qml index 383a5b09b..75126dc91 100644 --- a/declarativeimports/plasmacomponents/qml/QueryDialog.qml +++ b/declarativeimports/plasmacomponents/qml/QueryDialog.qml @@ -51,7 +51,6 @@ CommonDialog { property string message property string acceptButtonText property string rejectButtonText - property alias icon: root.titleIcon // for backwards compatibility onAcceptButtonTextChanged: internal.updateButtonTexts() onRejectButtonTextChanged: internal.updateButtonTexts() From 3e1359a8bc4003c0f2c5695c22f885caea31ef8b Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 3 Nov 2011 18:23:26 +0100 Subject: [PATCH 17/87] use a system KDialog for QueryDialog --- .../plasmacomponents/CMakeLists.txt | 3 +- .../plasmacomponents/kdialogproxy.cpp | 150 ++++++++++++++++++ .../plasmacomponents/kdialogproxy.h | 88 ++++++++++ .../plasmacomponentsplugin.cpp | 3 + 4 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 declarativeimports/plasmacomponents/kdialogproxy.cpp create mode 100644 declarativeimports/plasmacomponents/kdialogproxy.h diff --git a/declarativeimports/plasmacomponents/CMakeLists.txt b/declarativeimports/plasmacomponents/CMakeLists.txt index e60727554..a8605950a 100644 --- a/declarativeimports/plasmacomponents/CMakeLists.txt +++ b/declarativeimports/plasmacomponents/CMakeLists.txt @@ -6,6 +6,7 @@ set(plasmacomponents_SRCS enums.cpp qmenu.cpp qmenuitem.cpp + kdialogproxy.cpp ) INCLUDE_DIRECTORIES( @@ -18,7 +19,7 @@ qt4_automoc(${plasmacomponents_SRCS}) add_library(plasmacomponentsplugin SHARED ${plasmacomponents_SRCS}) -target_link_libraries(plasmacomponentsplugin ${QT_QTCORE_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} ${QT_QTGUI_LIBRARY}) +target_link_libraries(plasmacomponentsplugin ${QT_QTCORE_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDEUI_LIBRARY}) install(TARGETS plasmacomponentsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/components) diff --git a/declarativeimports/plasmacomponents/kdialogproxy.cpp b/declarativeimports/plasmacomponents/kdialogproxy.cpp new file mode 100644 index 000000000..89b7aa4cf --- /dev/null +++ b/declarativeimports/plasmacomponents/kdialogproxy.cpp @@ -0,0 +1,150 @@ +/* +* Copyright (C) 2011 by Marco MArtin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "kdialogproxy.h" + +#include + +#include + +KDialogProxy::KDialogProxy (QObject *parent) + : QObject(parent), + m_status(DialogStatus::Closed) +{ + m_dialog = new KDialog(0); + m_label = new QLabel(m_dialog); + m_label->setWordWrap(true); + m_dialog->setMainWidget(m_label); + m_dialog->setButtons( KDialog::Ok | KDialog::Cancel); + connect(m_dialog, SIGNAL(okClicked()), this, SIGNAL(accepted())); + connect(m_dialog, SIGNAL(cancelClicked()), this, SIGNAL(rejected())); +} + +KDialogProxy::~KDialogProxy() +{ + delete m_dialog; +} + + +void KDialogProxy::setTitleText(const QString &text) +{ + if (text == m_titleText) { + return; + } + + m_dialog->setCaption(text); + m_titleText = text; + emit titleTextChanged(); +} + +QString KDialogProxy::titleText() const +{ + return m_titleText; +} + + +void KDialogProxy::setTitleIcon(const QString &icon) +{ + if (icon == m_titleIcon) { + return; + } + + m_dialog->setWindowIcon(KIcon(icon)); + m_titleIcon = icon; + emit titleIconChanged(); +} + +QString KDialogProxy::titleIcon() const +{ + return m_titleIcon; +} + + +void KDialogProxy::setMessage(const QString &message) +{ + if (message == m_message) { + return; + } + + m_label->setText(message); + m_message = message; + emit messageChanged(); +} + +QString KDialogProxy::message() const +{ + return m_message; +} + + +void KDialogProxy::setAcceptButtonText(const QString &text) +{ + if (text == m_acceptButtonText) { + return; + } + + m_dialog->setButtonText(KDialog::Ok, text); + m_acceptButtonText = text; + emit acceptButtonTextChanged(); +} + +QString KDialogProxy::acceptButtonText() const +{ + return m_acceptButtonText; +} + + +void KDialogProxy::setRejectButtonText(const QString &text) +{ + if (text == m_rejectButtonText) { + return; + } + + m_dialog->setButtonText(KDialog::Cancel, text); + m_rejectButtonText = text; + emit rejectButtonTextChanged(); +} + +QString KDialogProxy::rejectButtonText() const +{ + return m_rejectButtonText; +} + + +DialogStatus::Status KDialogProxy::status() const +{ + return m_status; +} + +void KDialogProxy::open() +{ + m_dialog->show(); + m_status = DialogStatus::Open; + emit statusChanged(); +} + +void KDialogProxy::close() +{ + m_dialog->hide(); + m_status = DialogStatus::Closed; + emit statusChanged(); +} + +#include "kdialogproxy.moc" + diff --git a/declarativeimports/plasmacomponents/kdialogproxy.h b/declarativeimports/plasmacomponents/kdialogproxy.h new file mode 100644 index 000000000..19e4ffa8f --- /dev/null +++ b/declarativeimports/plasmacomponents/kdialogproxy.h @@ -0,0 +1,88 @@ +/* +* Copyright (C) 2011 by Marco MArtin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef KDIALOG_PROXY_H +#define KDIALOG_PROXY_H + +#include +#include +#include "kdialogproxy.h" +#include "enums.h" + +class QLabel; + +class KDialogProxy : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString titleText READ titleText WRITE setTitleText NOTIFY titleTextChanged) + Q_PROPERTY(QString titleIcon READ titleIcon WRITE setTitleIcon NOTIFY titleIconChanged) + Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged) + Q_PROPERTY(QString acceptButtonText READ acceptButtonText WRITE setAcceptButtonText NOTIFY acceptButtonTextChanged) + Q_PROPERTY(QString rejectButtonText READ rejectButtonText WRITE setRejectButtonText NOTIFY rejectButtonTextChanged) + Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged) + +public: + KDialogProxy(QObject *parent = 0); + ~KDialogProxy(); + + void setTitleText(const QString &text); + QString titleText() const; + + void setTitleIcon(const QString &icon); + QString titleIcon() const; + + void setMessage(const QString &message); + QString message() const; + + void setAcceptButtonText(const QString &text); + QString acceptButtonText() const; + + void setRejectButtonText(const QString &text); + QString rejectButtonText() const; + + void setStatus(DialogStatus::Status status); + DialogStatus::Status status() const; + + Q_INVOKABLE void open(); + Q_INVOKABLE void close(); + +Q_SIGNALS: + void titleTextChanged(); + void titleIconChanged(); + void messageChanged(); + void acceptButtonTextChanged(); + void rejectButtonTextChanged(); + void statusChanged(); + void accepted(); + void rejected(); + +private: + KDialog *m_dialog; + QLabel *m_label; + QString m_titleText; + QString m_titleIcon; + QString m_message; + QString m_acceptButtonText; + QString m_rejectButtonText; + DialogStatus::Status m_status; +}; + +#endif //KDIALOG_PROXY_H + diff --git a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index 0ee5a0a98..87c1cca0c 100644 --- a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -26,6 +26,7 @@ #include "enums.h" #include "qmenu.h" #include "qmenuitem.h" +#include "kdialogproxy.h" void PlasmaComponentsPlugin::registerTypes(const char *uri) @@ -37,6 +38,8 @@ void PlasmaComponentsPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 0, 1, "ContextMenu"); qmlRegisterType(uri, 0, 1, "MenuItem"); + qmlRegisterType(uri, 0, 1, "QueryDialog"); + qmlRegisterType(uri, 0, 1, "RangeModel"); qmlRegisterUncreatableType(uri, 0, 1, "DialogStatus", ""); From a5db2727dd95eb274fee9c789b494662007a6a18 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 3 Nov 2011 18:28:15 +0100 Subject: [PATCH 18/87] connect closeClicked as well to rejected --- declarativeimports/plasmacomponents/kdialogproxy.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/declarativeimports/plasmacomponents/kdialogproxy.cpp b/declarativeimports/plasmacomponents/kdialogproxy.cpp index 89b7aa4cf..9e98d35f2 100644 --- a/declarativeimports/plasmacomponents/kdialogproxy.cpp +++ b/declarativeimports/plasmacomponents/kdialogproxy.cpp @@ -34,6 +34,7 @@ KDialogProxy::KDialogProxy (QObject *parent) m_dialog->setButtons( KDialog::Ok | KDialog::Cancel); connect(m_dialog, SIGNAL(okClicked()), this, SIGNAL(accepted())); connect(m_dialog, SIGNAL(cancelClicked()), this, SIGNAL(rejected())); + connect(m_dialog, SIGNAL(closeClicked()), this, SIGNAL(rejected())); } KDialogProxy::~KDialogProxy() From 924d5fcf05928cfc9f44852a7166f290d96b2ba1 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 14:18:12 +0100 Subject: [PATCH 19/87] abstract the text field focus effect --- .../plasmacomponents/qml/TextArea.qml | 29 ++----- .../plasmacomponents/qml/TextField.qml | 33 ++------ .../plasmacomponents/qml/TextFieldFocus.qml | 79 +++++++++++++++++++ declarativeimports/test/gallery/Gallery.qml | 1 + 4 files changed, 92 insertions(+), 50 deletions(-) create mode 100644 declarativeimports/plasmacomponents/qml/TextFieldFocus.qml diff --git a/declarativeimports/plasmacomponents/qml/TextArea.qml b/declarativeimports/plasmacomponents/qml/TextArea.qml index 222e3ae3b..434e8bd8c 100644 --- a/declarativeimports/plasmacomponents/qml/TextArea.qml +++ b/declarativeimports/plasmacomponents/qml/TextArea.qml @@ -89,32 +89,13 @@ Item { opacity: enabled ? 1.0 : 0.5 - PlasmaCore.FrameSvgItem { + TextFieldFocus { id: hover - - anchors { - fill: base - leftMargin: -margins.left - topMargin: -margins.top - rightMargin: -margins.right - bottomMargin: -margins.bottom - } - imagePath: "widgets/lineedit" - prefix: { - if (textEdit.activeFocus) - return "focus"; - else - return "hover"; - } - - opacity: (mouseWatcher.containsMouse||textArea.activeFocus) ? 1 : 0 - Behavior on opacity { - NumberAnimation { - duration: 250 - easing.type: Easing.InOutQuad - } - } + z: 800 + state: textArea.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden") + anchors.fill: base } + MouseArea { id: mouseWatcher anchors.fill: hover diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml index 7d73978db..dced83630 100644 --- a/declarativeimports/plasmacomponents/qml/TextField.qml +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -90,6 +90,13 @@ Item { // disabled text fields opacity: enabled ? 1.0 : 0.5 + TextFieldFocus { + id: hover + z: 800 + state: textInput.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden") + anchors.fill: base + } + PlasmaCore.FrameSvgItem { id: base @@ -99,32 +106,6 @@ Item { prefix: "base" } - PlasmaCore.FrameSvgItem { - id: hover - - anchors { - fill: parent - leftMargin: -margins.left - topMargin: -margins.top - rightMargin: -margins.right - bottomMargin: -margins.bottom - } - imagePath: "widgets/lineedit" - prefix: { - if (textField.activeFocus) { - return "focus" - } else { - return "hover" - } - } - opacity: (mouseWatcher.containsMouse||textField.activeFocus) ? 1 : 0 - Behavior on opacity { - NumberAnimation { - duration: 250 - easing.type: Easing.InOutQuad - } - } - } MouseArea { id: mouseWatcher anchors.fill: hover diff --git a/declarativeimports/plasmacomponents/qml/TextFieldFocus.qml b/declarativeimports/plasmacomponents/qml/TextFieldFocus.qml new file mode 100644 index 000000000..0ca21229b --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/TextFieldFocus.qml @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 by Daker Fernandes Pinheiro + * Copyright (C) 2011 by Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: main + state: parent.state + + PlasmaCore.FrameSvgItem { + id: hover + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + opacity: 0 + imagePath: "widgets/lineedit" + prefix: "hover" + } + + states: [ + State { + name: "hover" + PropertyChanges { + target: hover + opacity: 1 + prefix: "hover" + } + }, + State { + name: "focus" + PropertyChanges { + target: hover + opacity: 1 + prefix: "focus" + } + }, + State { + name: "hidden" + PropertyChanges { + target: hover + opacity: 0 + prefix: "hover" + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: 250 + easing.type: Easing.OutQuad + } + } + ] +} diff --git a/declarativeimports/test/gallery/Gallery.qml b/declarativeimports/test/gallery/Gallery.qml index bae3ada49..d2b994974 100644 --- a/declarativeimports/test/gallery/Gallery.qml +++ b/declarativeimports/test/gallery/Gallery.qml @@ -103,6 +103,7 @@ Rectangle { flickableItem: page animated: true + orientation: Qt.Horizontal anchors { left: parent.left right: verticalScrollBar.left From c644d41709288cdc7464474036ba96d14c34588f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 14:29:05 +0100 Subject: [PATCH 20/87] use hint-focus-over-base to decide where to paint the focus panel --- .../plasmacomponents/qml/TextArea.qml | 1 - .../plasmacomponents/qml/TextField.qml | 1 - .../plasmacomponents/qml/TextFieldFocus.qml | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/TextArea.qml b/declarativeimports/plasmacomponents/qml/TextArea.qml index 434e8bd8c..65cde919b 100644 --- a/declarativeimports/plasmacomponents/qml/TextArea.qml +++ b/declarativeimports/plasmacomponents/qml/TextArea.qml @@ -91,7 +91,6 @@ Item { TextFieldFocus { id: hover - z: 800 state: textArea.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden") anchors.fill: base } diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml index dced83630..4611f7273 100644 --- a/declarativeimports/plasmacomponents/qml/TextField.qml +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -92,7 +92,6 @@ Item { TextFieldFocus { id: hover - z: 800 state: textInput.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden") anchors.fill: base } diff --git a/declarativeimports/plasmacomponents/qml/TextFieldFocus.qml b/declarativeimports/plasmacomponents/qml/TextFieldFocus.qml index 0ca21229b..3bc24ffcc 100644 --- a/declarativeimports/plasmacomponents/qml/TextFieldFocus.qml +++ b/declarativeimports/plasmacomponents/qml/TextFieldFocus.qml @@ -25,6 +25,25 @@ Item { id: main state: parent.state + PlasmaCore.Svg { + id: lineEditSvg + imagePath: "widgets/lineedit" + onRepaintNeeded: { + if (lineEditSvg.hasElement("hint-focus-over-base")) { + main.z = 800 + } else { + main.z = 0 + } + } + Component.onCompleted: { + if (lineEditSvg.hasElement("hint-focus-over-base")) { + main.z = 800 + } else { + main.z = 0 + } + } + } + PlasmaCore.FrameSvgItem { id: hover From 2e5afa765ba21ad84f66476b84464d58814e2af2 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 15:12:44 +0100 Subject: [PATCH 21/87] use roundshadow for sliders --- .../plasmacomponents/qml/RoundShadow.qml | 27 ++++--- .../plasmacomponents/qml/Slider.qml | 76 +++++-------------- 2 files changed, 36 insertions(+), 67 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/RoundShadow.qml b/declarativeimports/plasmacomponents/qml/RoundShadow.qml index fce6f7eb9..8c20a9d5a 100644 --- a/declarativeimports/plasmacomponents/qml/RoundShadow.qml +++ b/declarativeimports/plasmacomponents/qml/RoundShadow.qml @@ -24,13 +24,19 @@ import org.kde.plasma.core 0.1 as PlasmaCore Item { id: main state: parent.state + property alias imagePath: shadowSvg.imagePath + property string hoverElement: "hover" + property string focusElement: "focus" + property alias shadowElement: shadow.elementId + + PlasmaCore.Svg { + id: shadowSvg + imagePath: "widgets/actionbutton" + } PlasmaCore.SvgItem { id: hover - svg: PlasmaCore.Svg { - id: hoverSvg - imagePath: "widgets/actionbutton" - } + svg: shadowSvg elementId: "hover" anchors.fill: parent @@ -40,10 +46,7 @@ Item { PlasmaCore.SvgItem { id: shadow - svg: PlasmaCore.Svg { - id: shadowSvg - imagePath: "widgets/actionbutton" - } + svg: shadowSvg elementId: "shadow" anchors.fill: parent @@ -59,7 +62,7 @@ Item { PropertyChanges { target: hover opacity: 0 - elementId: "hover" + elementId: hoverElement } }, State { @@ -71,7 +74,7 @@ Item { PropertyChanges { target: hover opacity: 1 - elementId: "hover" + elementId: hoverElement } }, State { @@ -83,7 +86,7 @@ Item { PropertyChanges { target: hover opacity: 1 - elementId: "focus" + elementId: focusElement } }, State { @@ -95,7 +98,7 @@ Item { PropertyChanges { target: hover opacity: 0 - elementId: "hover" + elementId: hoverElement } } ] diff --git a/declarativeimports/plasmacomponents/qml/Slider.qml b/declarativeimports/plasmacomponents/qml/Slider.qml index 1458dc6ec..0c82ccbb2 100644 --- a/declarativeimports/plasmacomponents/qml/Slider.qml +++ b/declarativeimports/plasmacomponents/qml/Slider.qml @@ -40,7 +40,7 @@ Item { property bool updateValueWhileDragging: true property real handleSize: 22 - // Convinience API + // Convenience API property bool _isVertical: orientation == Qt.Vertical width: _isVertical ? 22 : 200 @@ -109,8 +109,8 @@ Item { value: 0 stepSize: 0.0 inverted: false - positionAtMinimum: 0 + handle.width / 2 - positionAtMaximum: contents.width - handle.width / 2 + positionAtMinimum: 0 + positionAtMaximum: contents.width - handle.width } PlasmaCore.Svg { @@ -134,51 +134,26 @@ Item { imagePath: "widgets/slider" prefix: "groove-highlight" height: groove.height - width: inverted ? groove.width - handle.x : fakeHandle.x + width: inverted ? groove.width - handle.x : fakeHandle.x + handle.width/2 x: inverted ? handle.x : 0 anchors.verticalCenter: parent.verticalCenter visible: range.position > 0 && slider.enabled } - PlasmaCore.SvgItem { - id: focus - - transform: Translate { x: - handle.width / 2 } - anchors { - fill: handle - margins: -1 // Hardcoded - } - opacity: slider.activeFocus ? 1 : 0 - svg: PlasmaCore.Svg { imagePath: "widgets/slider" } - elementId: "horizontal-slider-hover" - - Behavior on opacity { - PropertyAnimation { duration: 250 } - } - } - - PlasmaCore.SvgItem { - id: hover - - transform: Translate { x: - handle.width / 2 } - anchors { - fill: handle - margins: -2 // Hardcoded - } - opacity: 0 - svg: PlasmaCore.Svg { imagePath: "widgets/slider" } - elementId: "horizontal-slider-hover" - - Behavior on opacity { - PropertyAnimation { duration: 250 } - } + RoundShadow { + id: shadow + imagePath: "widgets/slider" + focusElement: "horizontal-slider-focus" + hoverElement: "horizontal-slider-hover" + shadowElement: "horizontal-slider-shadow" + state: slider.activeFocus ? "focus" : (mouseArea.containsMouse ? "hover" : "hidden") + anchors.fill: handle } PlasmaCore.SvgItem { id: handle - transform: Translate { x: - handle.width / 2 } x: fakeHandle.x anchors { verticalCenter: groove.verticalCenter @@ -203,7 +178,6 @@ Item { id: fakeHandle width: handle.width height: handle.height - transform: Translate { x: - handle.width / 2 } } MouseArea { @@ -219,33 +193,25 @@ Item { } hoverEnabled: true - onEntered: { - hover.opacity = 1; - } - onExited: { - if (!pressed) - hover.opacity = 0; - } onPressed: { // Clamp the value - var newX = Math.max(mouse.x, drag.minimumX); - newX = Math.min(newX, drag.maximumX); + var newX = Math.max(mouse.x, drag.minimumX) + newX = Math.min(newX, drag.maximumX) // Debounce the press: a press event inside the handler will not // change its position, the user needs to drag it. - if (Math.abs(newX - fakeHandle.x) > handle.width / 2) - range.position = newX; + if (Math.abs(newX - fakeHandle.x) > handle.width / 2) { + range.position = newX + } - slider.forceActiveFocus(); + slider.forceActiveFocus() } onReleased: { // If we don't update while dragging, this is the only // moment that the range is updated. - if (!slider.updateValueWhileDragging) - range.position = fakeHandle.x; - - if (!containsMouse) - hover.opacity = 0; + if (!slider.updateValueWhileDragging) { + range.position = fakeHandle.x + } } } } From 06bbb405c55d8bb9afd0e5bedf4048a62985d75c Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 7 Nov 2011 18:06:18 +0100 Subject: [PATCH 22/87] install tablet specific components in platformcomponents --- .../plasmacomponents/CMakeLists.txt | 22 ++++++ .../plasmacomponentsplugin.cpp | 4 +- .../platformcomponents/touch/ButtonShadow.qml | 74 +++++++++++++++++++ .../platformcomponents/touch/RoundShadow.qml | 65 ++++++++++++++++ .../platformcomponents/touch/qmldir | 38 ++++++++++ 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/qmldir diff --git a/declarativeimports/plasmacomponents/CMakeLists.txt b/declarativeimports/plasmacomponents/CMakeLists.txt index a8605950a..882bb3907 100644 --- a/declarativeimports/plasmacomponents/CMakeLists.txt +++ b/declarativeimports/plasmacomponents/CMakeLists.txt @@ -24,3 +24,25 @@ target_link_libraries(plasmacomponentsplugin ${QT_QTCORE_LIBRARY} ${QT_QTDECLARA install(TARGETS plasmacomponentsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/components) install(DIRECTORY qml/ DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/components) + + + +ADD_DEFINITIONS(-DTOUCH) + +set(plasmacomponentstouch_SRCS + plasmacomponentsplugin.cpp + qrangemodel.cpp + enums.cpp + qmenu.cpp + qmenuitem.cpp + kdialogproxy.cpp + ) + + + +add_library(plasmacomponentstouchplugin SHARED ${plasmacomponentstouch_SRCS}) +target_link_libraries(plasmacomponentstouchplugin ${QT_QTCORE_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDEUI_LIBRARY}) + +install(TARGETS plasmacomponentstouchplugin DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(DIRECTORY qml/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(DIRECTORY platformcomponents/touch/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) diff --git a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index 87c1cca0c..3e1d1fab6 100644 --- a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -20,6 +20,7 @@ #include "plasmacomponentsplugin.h" #include +#include #include "qrangemodel.h" @@ -28,7 +29,6 @@ #include "qmenuitem.h" #include "kdialogproxy.h" - void PlasmaComponentsPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.plasma.components")); @@ -38,7 +38,9 @@ void PlasmaComponentsPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 0, 1, "ContextMenu"); qmlRegisterType(uri, 0, 1, "MenuItem"); +#ifndef TOUCH qmlRegisterType(uri, 0, 1, "QueryDialog"); +#endif qmlRegisterType(uri, 0, 1, "RangeModel"); diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml new file mode 100644 index 000000000..9e55aaa7e --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 by Daker Fernandes Pinheiro + * Copyright (C) 2011 by Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: main + state: parent.state + + + PlasmaCore.FrameSvgItem { + id: shadow + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/button" + prefix: "shadow" + } + + states: [ + State { + name: "shadow" + PropertyChanges { + target: shadow + opacity: 1 + } + PropertyChanges { + target: hover + opacity: 0 + prefix: "hover" + } + }, + State { + name: "hidden" + PropertyChanges { + target: shadow + opacity: 0 + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: 250 + easing.type: Easing.OutQuad + } + } + ] +} diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml new file mode 100644 index 000000000..12b53f4a7 --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 by Daker Fernandes Pinheiro + * Copyright (C) 2011 by Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: main + state: parent.state + + PlasmaCore.SvgItem { + id: shadow + svg: PlasmaCore.Svg { + id: shadowSvg + imagePath: "widgets/actionbutton" + } + elementId: "shadow" + + anchors.fill: parent + } + + states: [ + State { + name: "shadow" + PropertyChanges { + target: shadow + opacity: 1 + } + }, + State { + name: "hidden" + PropertyChanges { + target: shadow + opacity: 0 + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: 250 + easing.type: Easing.OutQuad + } + } + ] +} diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir new file mode 100644 index 000000000..d8c28a1aa --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir @@ -0,0 +1,38 @@ +plugin plasmacomponentstouchplugin + +BusyIndicator 0.1 BusyIndicator.qml +Button 0.1 Button.qml +ButtonColumn 0.1 ButtonColumn.qml +ButtonGroup 0.1 ButtonGroup.js +ButtonRow 0.1 ButtonRow.qml +CheckBox 0.1 CheckBox.qml +FlashingLabel 0.1 FlashingLabel.qml +Frame 0.1 Frame.qml +Highlight 0.1 Highlight.qml +IconWidget 0.1 IconWidget.qml +Label 0.1 Label.qml +ProgressBar 0.1 ProgressBar.qml +PushButton 0.1 PushButton.qml +RadioButton 0.1 RadioButton.qml +ScrollBar 0.1 ScrollBar.qml +ScrollDecorator 0.1 ScrollDecorator.qml +Slider 0.1 Slider.qml +Switch 0.1 Switch.qml +TextArea 0.1 TextArea.qml +TextField 0.1 TextField.qml +ToolBar 0.1 ToolBar.qml +ToolButton 0.1 ToolButton.qml +ListItem 0.1 ListItem.qml + +CommonDialog 0.1 CommonDialog.qml +QueryDialog 0.1 QueryDialog.qml +SelectionDialog 0.1 SelectionDialog.qml +Window 0.1 Window.qml + +Page 0.1 Page.qml +PageStack 0.1 PageStack.qml + +TabBar 0.1 TabBar.qml +TabButton 0.1 TabButton.qml +TabGroup 0.1 TabGroup.qml +SectionScroller 0.1 SectionScroller.qml From 28f573d18fecc5615f18fb9a4e488191d3134064 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 7 Nov 2011 18:46:21 +0100 Subject: [PATCH 23/87] read the kind of components from plasmarc --- .../plasmacomponents/CMakeLists.txt | 18 ++---------------- .../plasmacomponentsplugin.cpp | 11 ++++++++--- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/declarativeimports/plasmacomponents/CMakeLists.txt b/declarativeimports/plasmacomponents/CMakeLists.txt index 882bb3907..c7e2b6f92 100644 --- a/declarativeimports/plasmacomponents/CMakeLists.txt +++ b/declarativeimports/plasmacomponents/CMakeLists.txt @@ -27,22 +27,8 @@ install(DIRECTORY qml/ DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/compone -ADD_DEFINITIONS(-DTOUCH) +#The platform specific stuff, overwrites a copy of the desktop one -set(plasmacomponentstouch_SRCS - plasmacomponentsplugin.cpp - qrangemodel.cpp - enums.cpp - qmenu.cpp - qmenuitem.cpp - kdialogproxy.cpp - ) - - - -add_library(plasmacomponentstouchplugin SHARED ${plasmacomponentstouch_SRCS}) -target_link_libraries(plasmacomponentstouchplugin ${QT_QTCORE_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDEUI_LIBRARY}) - -install(TARGETS plasmacomponentstouchplugin DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(TARGETS plasmacomponentsplugin DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) install(DIRECTORY qml/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) install(DIRECTORY platformcomponents/touch/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) diff --git a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index 3e1d1fab6..5dc904ab9 100644 --- a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -24,6 +24,8 @@ #include "qrangemodel.h" +#include + #include "enums.h" #include "qmenu.h" #include "qmenuitem.h" @@ -33,14 +35,17 @@ void PlasmaComponentsPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.plasma.components")); + KConfigGroup cg(KSharedConfig::openConfig("plasmarc"), "Plasma-components-platform"); + const QString componentsPlatform = cg.readEntry("name", "desktop"); qmlRegisterType(uri, 0, 1, "Menu"); qmlRegisterType(uri, 0, 1, "ContextMenu"); qmlRegisterType(uri, 0, 1, "MenuItem"); -#ifndef TOUCH - qmlRegisterType(uri, 0, 1, "QueryDialog"); -#endif + + if (componentsPlatform == "desktop") { + qmlRegisterType(uri, 0, 1, "QueryDialog"); + } qmlRegisterType(uri, 0, 1, "RangeModel"); From a62ce8814aadfca4adb882805c3cbfbc688c793e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 7 Nov 2011 19:13:38 +0100 Subject: [PATCH 24/87] add window and querydialog as touch specific --- .../touch}/QueryDialog.qml | 0 .../platformcomponents/touch/Window.qml | 56 +++++++++++++++++++ .../platformcomponents/touch/qmldir | 2 +- .../plasmacomponents/qml/qmldir | 1 - 4 files changed, 57 insertions(+), 2 deletions(-) rename declarativeimports/plasmacomponents/{qml => platformcomponents/touch}/QueryDialog.qml (100%) create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml diff --git a/declarativeimports/plasmacomponents/qml/QueryDialog.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/QueryDialog.qml similarity index 100% rename from declarativeimports/plasmacomponents/qml/QueryDialog.qml rename to declarativeimports/plasmacomponents/platformcomponents/touch/QueryDialog.qml diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml new file mode 100644 index 000000000..13d41b2aa --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 + +Item { + id: root + + property bool inPortrait: height > width + + width: 800 + height: 480 + + //FIXME: something from the plasma theme + Rectangle { + anchors.fill: parent + } + +} diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir index d8c28a1aa..97f3e7e60 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir @@ -1,4 +1,4 @@ -plugin plasmacomponentstouchplugin +plugin plasmacomponentsplugin BusyIndicator 0.1 BusyIndicator.qml Button 0.1 Button.qml diff --git a/declarativeimports/plasmacomponents/qml/qmldir b/declarativeimports/plasmacomponents/qml/qmldir index f0940f3ce..5c1d79dba 100644 --- a/declarativeimports/plasmacomponents/qml/qmldir +++ b/declarativeimports/plasmacomponents/qml/qmldir @@ -25,7 +25,6 @@ ToolButton 0.1 ToolButton.qml ListItem 0.1 ListItem.qml CommonDialog 0.1 CommonDialog.qml -QueryDialog 0.1 QueryDialog.qml SelectionDialog 0.1 SelectionDialog.qml Page 0.1 Page.qml From 24f527f3fedd853428fabb28c3b2f697bc51b2cf Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 15:24:10 +0100 Subject: [PATCH 25/87] sync the roundshadow element --- .../platformcomponents/touch/RoundShadow.qml | 46 +++++++++++++++++-- .../plasmacomponents/qml/RoundShadow.qml | 2 +- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml index 12b53f4a7..1ea1465ec 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/RoundShadow.qml @@ -24,13 +24,29 @@ import org.kde.plasma.core 0.1 as PlasmaCore Item { id: main state: parent.state + property alias imagePath: shadowSvg.imagePath + property string hoverElement: "hover" + property string focusElement: "focus" + property alias shadowElement: shadow.elementId + + PlasmaCore.Svg { + id: shadowSvg + imagePath: "widgets/actionbutton" + } + + PlasmaCore.SvgItem { + id: hover + svg: shadowSvg + elementId: "hover" + + anchors.fill: parent + + opacity: 0 + } PlasmaCore.SvgItem { id: shadow - svg: PlasmaCore.Svg { - id: shadowSvg - imagePath: "widgets/actionbutton" - } + svg: shadowSvg elementId: "shadow" anchors.fill: parent @@ -43,6 +59,23 @@ Item { target: shadow opacity: 1 } + PropertyChanges { + target: hover + opacity: 0 + elementId: hoverElement + } + }, + State { + name: "focus" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 1 + elementId: focusElement + } }, State { name: "hidden" @@ -50,6 +83,11 @@ Item { target: shadow opacity: 0 } + PropertyChanges { + target: hover + opacity: 0 + elementId: hoverElement + } } ] diff --git a/declarativeimports/plasmacomponents/qml/RoundShadow.qml b/declarativeimports/plasmacomponents/qml/RoundShadow.qml index 8c20a9d5a..f11e54de9 100644 --- a/declarativeimports/plasmacomponents/qml/RoundShadow.qml +++ b/declarativeimports/plasmacomponents/qml/RoundShadow.qml @@ -90,7 +90,7 @@ Item { } }, State { - name: "hover" + name: "hidden" PropertyChanges { target: shadow opacity: 0 From c498292a55b322c52e0b691c3dda241ce914f979 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 17:22:01 +0100 Subject: [PATCH 26/87] new name for the global config --- declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index 5dc904ab9..f4a6c5eb6 100644 --- a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -35,7 +35,7 @@ void PlasmaComponentsPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.plasma.components")); - KConfigGroup cg(KSharedConfig::openConfig("plasmarc"), "Plasma-components-platform"); + KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform"); const QString componentsPlatform = cg.readEntry("name", "desktop"); qmlRegisterType(uri, 0, 1, "Menu"); From 1d4f9a5c77f82b53f349873fbc0284ed3c23fb7d Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 18:19:25 +0100 Subject: [PATCH 27/87] fix shadow disabling --- .../platformcomponents/touch/ButtonShadow.qml | 5 ----- declarativeimports/plasmacomponents/qml/Button.qml | 14 ++++++++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml index 9e55aaa7e..040442bee 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml @@ -47,11 +47,6 @@ Item { target: shadow opacity: 1 } - PropertyChanges { - target: hover - opacity: 0 - prefix: "hover" - } }, State { name: "hidden" diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index 3bed4ab35..8d44164e8 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -41,15 +41,21 @@ Item { // disabled buttons opacity: enabled ? 1.0 : 0.5 - function pressButton() { - if(button.enabled) { + function pressButton() + { + if (button.enabled) { buttonContent.state = "pressed" + shadow.state = "hidden" } } - function releaseButton() { - if(button.enabled) { + function releaseButton() + { + if (button.enabled) { buttonContent.state = "normal" + if (!checked) { + shadow.state = "shadow" + } if (button.checkable) { button.checked = !button.checked; From 82bbcc139a3d8d3493cc130e7756f228087072ca Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 19:27:44 +0100 Subject: [PATCH 28/87] better logic for button pressed handling --- .../plasmacomponents/qml/Button.qml | 45 ++++++----- .../plasmacomponents/qml/ToolButton.qml | 74 +++++++++---------- 2 files changed, 58 insertions(+), 61 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index 8d44164e8..be87f67f5 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -41,39 +41,37 @@ Item { // disabled buttons opacity: enabled ? 1.0 : 0.5 - function pressButton() - { - if (button.enabled) { - buttonContent.state = "pressed" - shadow.state = "hidden" - } - } + QtObject { + id: internal + property bool userPressed: false - function releaseButton() - { - if (button.enabled) { - buttonContent.state = "normal" - if (!checked) { - shadow.state = "shadow" + function pressButton() + { + userPressed = true + } + + function releaseButton() + { + userPressed = false + if (!button.enabled) { + return } if (button.checkable) { - button.checked = !button.checked; + button.checked = !button.checked } - // TODO: "checked" state must have special graphics? - - button.clicked(); - button.forceActiveFocus(); + button.clicked() + button.forceActiveFocus() } } - Keys.onSpacePressed: pressButton() - Keys.onReturnPressed: pressButton() + Keys.onSpacePressed: internal.pressButton() + Keys.onReturnPressed: internal.pressButton() Keys.onReleased: { if (event.key == Qt.Key_Space || event.key == Qt.Key_Return) - releaseButton(); + internal.releaseButton(); } onActiveFocusChanged: { @@ -112,6 +110,7 @@ Item { Item { id: buttonContent + state: (internal.userPressed || checked) ? "pressed" : "normal" states: [ State { name: "normal" }, @@ -185,8 +184,8 @@ Item { anchors.fill: parent hoverEnabled: true - onPressed: pressButton() - onReleased: releaseButton() + onPressed: internal.pressButton() + onReleased: internal.releaseButton() onEntered: { shadow.state = "hover" } diff --git a/declarativeimports/plasmacomponents/qml/ToolButton.qml b/declarativeimports/plasmacomponents/qml/ToolButton.qml index 9d273bd5c..91c4d7125 100644 --- a/declarativeimports/plasmacomponents/qml/ToolButton.qml +++ b/declarativeimports/plasmacomponents/qml/ToolButton.qml @@ -39,27 +39,6 @@ Item { surface.opacity = 1 } - function pressButton() { - if (button.enabled) - surface.prefix = "pressed"; - } - - function releaseButton() { - if (!button.enabled) - return; - - if (button.checkable) - button.checked = !button.checked; - - // TODO: "checked" state must have special graphics? - if (button.checked) - surface.prefix = "pressed"; - else - surface.prefix = "normal"; - - button.clicked(); - button.forceActiveFocus(); - } implicitWidth: Math.max(50, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) implicitHeight: Math.max(20, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) @@ -68,12 +47,12 @@ Item { // disabled buttons opacity: enabled ? 1.0 : 0.5 - Keys.onSpacePressed: pressButton(); - Keys.onReturnPressed: pressButton(); + Keys.onSpacePressed: internal.pressButton() + Keys.onReturnPressed: internal.pressButton() Keys.onReleased: { if (event.key == Qt.Key_Space || event.key == Qt.Key_Return) - releaseButton(); + internal.releaseButton() } onActiveFocusChanged: { @@ -86,6 +65,31 @@ Item { } } + QtObject { + id: internal + property bool userPressed: false + + function pressButton() + { + userPressed = true + } + + function releaseButton() + { + userPressed = false + if (!button.enabled) { + return + } + + if (button.checkable) { + button.checked = !button.checked + } + + button.clicked() + button.forceActiveFocus() + } + } + ButtonShadow { id: shadow anchors.fill: parent @@ -97,8 +101,8 @@ Item { anchors.fill: parent imagePath: "widgets/button" - prefix: "normal" - opacity: 0 + prefix: (internal.userPressed || checked) ? "pressed" : "normal" + opacity: (internal.userPressed || checked || !flat || mouse.containsMouse) ? 1 : 0 Behavior on opacity { PropertyAnimation { duration: 250 } } @@ -153,23 +157,17 @@ Item { anchors.fill: parent hoverEnabled: true - onPressed: { - pressButton(); - } - onReleased: { - releaseButton(); - } + onPressed: internal.pressButton(); + + onReleased: internal.releaseButton(); + onEntered: { - if (flat) { - surface.opacity = 1 - } else { + if (!flat) { shadow.state = "hover" } } onExited: { - if (flat) { - surface.opacity = 0 - } else { + if (!flat) { if (button.activeFocus) { shadow.state = "focus" } else if (checked) { From 5a00c8ec010d3c883dd9aaefc978b82d5229339f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 20:34:39 +0100 Subject: [PATCH 29/87] better shadow state chooser --- .../plasmacomponents/qml/Button.qml | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index be87f67f5..72344b87a 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -45,6 +45,13 @@ Item { id: internal property bool userPressed: false + function belongsToButtonGroup() + { + return button.parent + && button.parent.hasOwnProperty("checkedButton") + && button.parent.exclusive + } + function pressButton() { userPressed = true @@ -57,7 +64,7 @@ Item { return } - if (button.checkable) { + if ((!belongsToButtonGroup() || !button.checked) && button.checkable) { button.checked = !button.checked } @@ -74,19 +81,20 @@ Item { internal.releaseButton(); } - onActiveFocusChanged: { - if (activeFocus) { - shadow.state = "focus" - } else if (checked) { - shadow.state = "hidden" - } else { - shadow.state = "shadow" - } - } - ButtonShadow { id: shadow anchors.fill: parent + state: { + if (internal.userPressed || checked) { + return "hidden" + } else if (mouse.containsMouse) { + return "hover" + } else if (button.activeFocus) { + return "focus" + } else { + return "shadow" + } + } } // The normal button state @@ -186,17 +194,5 @@ Item { hoverEnabled: true onPressed: internal.pressButton() onReleased: internal.releaseButton() - onEntered: { - shadow.state = "hover" - } - onExited: { - if (button.activeFocus) { - shadow.state = "focus" - } else if (checked) { - shadow.state = "hidden" - } else { - shadow.state = "shadow" - } - } } } \ No newline at end of file From 869afade065b869576416189c0c60ed8ac1157fa Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 20:48:33 +0100 Subject: [PATCH 30/87] different paint for flat toolbuttons in touchscreens --- .../platformcomponents/touch/ButtonShadow.qml | 2 +- declarativeimports/plasmacomponents/qml/Button.qml | 1 + declarativeimports/plasmacomponents/qml/ButtonShadow.qml | 1 + declarativeimports/plasmacomponents/qml/ToolButton.qml | 4 +++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml index 040442bee..09a0a5250 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ButtonShadow.qml @@ -24,7 +24,7 @@ import org.kde.plasma.core 0.1 as PlasmaCore Item { id: main state: parent.state - + property bool hasOverState: false PlasmaCore.FrameSvgItem { id: shadow diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index 72344b87a..234f7e720 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -1,6 +1,7 @@ /* * Copyright (C) 2011 by Daker Fernandes Pinheiro * Copyright (C) 2011 by Mark Gaiser +* Copyright (C) 2011 by Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as diff --git a/declarativeimports/plasmacomponents/qml/ButtonShadow.qml b/declarativeimports/plasmacomponents/qml/ButtonShadow.qml index dcf8d233e..4c65f907f 100644 --- a/declarativeimports/plasmacomponents/qml/ButtonShadow.qml +++ b/declarativeimports/plasmacomponents/qml/ButtonShadow.qml @@ -24,6 +24,7 @@ import org.kde.plasma.core 0.1 as PlasmaCore Item { id: main state: parent.state + property bool hasOverState: true PlasmaCore.FrameSvgItem { id: hover diff --git a/declarativeimports/plasmacomponents/qml/ToolButton.qml b/declarativeimports/plasmacomponents/qml/ToolButton.qml index 91c4d7125..f135e6047 100644 --- a/declarativeimports/plasmacomponents/qml/ToolButton.qml +++ b/declarativeimports/plasmacomponents/qml/ToolButton.qml @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright (C) 2011 by Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -102,7 +103,8 @@ Item { anchors.fill: parent imagePath: "widgets/button" prefix: (internal.userPressed || checked) ? "pressed" : "normal" - opacity: (internal.userPressed || checked || !flat || mouse.containsMouse) ? 1 : 0 + //internal: if there is no hover status, don't paint on mouse over in touchscreens + opacity: (internal.userPressed || checked || !flat || (shadow.hasOverState && mouse.containsMouse)) ? 1 : 0 Behavior on opacity { PropertyAnimation { duration: 250 } } From b51d5b1cd9b71611084b0cf642dbf1bfd5e11096 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 20:54:13 +0100 Subject: [PATCH 31/87] text selectable by mouse --- declarativeimports/plasmacomponents/qml/TextArea.qml | 1 + declarativeimports/plasmacomponents/qml/TextField.qml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/declarativeimports/plasmacomponents/qml/TextArea.qml b/declarativeimports/plasmacomponents/qml/TextArea.qml index 65cde919b..f4ccddacc 100644 --- a/declarativeimports/plasmacomponents/qml/TextArea.qml +++ b/declarativeimports/plasmacomponents/qml/TextArea.qml @@ -151,6 +151,7 @@ Item { font.weight: theme.defaultFont.weight font.wordSpacing: theme.defaultFont.wordSpacing color: theme.viewTextColor + selectByMouse: true onCursorPositionChanged: { if (cursorRectangle.x < flickArea.contentX) { diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml index 4611f7273..ed644f126 100644 --- a/declarativeimports/plasmacomponents/qml/TextField.qml +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -137,10 +137,12 @@ Item { anchors { left: parent.left right: parent.right + verticalCenter: parent.verticalCenter // TODO: see what is the correct policy for margins leftMargin: 2 * base.margins.left rightMargin: 2 * base.margins.right } + selectByMouse: true y: (height - font.pixelSize) * 0.4 // XXX: verticalCenter anchor is not centering the text height: Math.min(2 * font.pixelSize, parent.height) color: theme.textColor From 2a79834ceb6b85f6114b038c45c88f8ff9515da7 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 20:57:34 +0100 Subject: [PATCH 32/87] standard signals altough unused --- .../platformcomponents/touch/Window.qml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml index 13d41b2aa..2f436a932 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/Window.qml @@ -38,19 +38,23 @@ ** ****************************************************************************/ -import QtQuick 1.1 +import QtQuick 1.0 Item { id: root property bool inPortrait: height > width + signal orientationChangeAboutToStart + signal orientationChangeStarted + signal orientationChangeFinished width: 800 height: 480 - //FIXME: something from the plasma theme - Rectangle { - anchors.fill: parent + Connections { + target: root + onInPortraitChanged: { + root.orientationChangeFinished() + } } - } From a6d785ffc7e705bcdb993255cc0f77c7fb8c427c Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 21:10:30 +0100 Subject: [PATCH 33/87] add ToolBarLayout --- .../platformcomponents/touch/qmldir | 1 + .../plasmacomponents/qml/ToolBarLayout.qml | 311 ++++++++++++++++++ .../plasmacomponents/qml/qmldir | 1 + 3 files changed, 313 insertions(+) create mode 100644 declarativeimports/plasmacomponents/qml/ToolBarLayout.qml diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir index 97f3e7e60..b3dde581a 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir @@ -28,6 +28,7 @@ CommonDialog 0.1 CommonDialog.qml QueryDialog 0.1 QueryDialog.qml SelectionDialog 0.1 SelectionDialog.qml Window 0.1 Window.qml +ToolBarLayout 0.1 ToolBarLayout.qml Page 0.1 Page.qml PageStack 0.1 PageStack.qml diff --git a/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml b/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml new file mode 100644 index 000000000..85e13d926 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// ToolBarLayout is a container for items on a toolbar that automatically +// implements an appropriate layout for its children. + +import QtQuick 1.1 +import "." 0.1 + +Item { + id: root + + implicitWidth: parent.width + implicitHeight: parent.height + + visible: false + + Connections { + target: privateStyle + onLayoutParametersChanged: internal.layoutChildren() + } + Connections { + target: screen + onCurrentOrientationChanged: internal.layoutChildren() + } + + QtObject { + id: internal + objectName: "internal" + + property bool portrait: screen.width < screen.height + + // These are the dynamic layout parameters used by the toolbar layout. + property real defaultHeightToolBar: portrait ? + privateStyle.toolBarHeightPortrait : privateStyle.toolBarHeightLandscape + property real defaultHeightToolButton: privateStyle.toolBarHeightLandscape + property real outerMarginHorizontal: portrait ? + 0 : (2 * platformStyle.paddingLarge) + property real outerMarginButtonRowLong: portrait ? + platformStyle.paddingLarge : (3 * platformStyle.paddingLarge) + property real innerSpacingTextButtonSingle: portrait ? + platformStyle.paddingMedium + (3 * platformStyle.paddingLarge) : (3 * platformStyle.paddingLarge) + property real innerSpacingTextButtonDouble: portrait ? + platformStyle.paddingSmall : (3 * platformStyle.paddingLarge) + property real innerSpacingButtonRowTwoChildren: portrait ? + platformStyle.paddingMedium : (3 * platformStyle.paddingLarge) + property real innerSpacingButtonRowLong: portrait ? + platformStyle.paddingMedium : platformStyle.paddingLarge + property real centerSpacingTextButtonDouble: platformStyle.paddingLarge + + function isIconButton(item) { + return item.hasOwnProperty("iconSource") + && item.hasOwnProperty("text") + && item.text == "" + } + + function isTextToolButton(item) { + // ToolButton has both iconSource and flat property, + // Button only has iconSource + return (item.hasOwnProperty("iconSource") + && item.iconSource == "" + && item.hasOwnProperty("flat")) + } + + function isButtonRow(item) { + return item.hasOwnProperty("checkedButton") + } + + function buttonWidth(child) { + if ((isTextToolButton(child)) || !(child.hasOwnProperty("implicitWidth"))) { + // ImplicitWidth for the ToolButton returns wrong value right after + // orientation change, and also we want to override its own + // layout width calculation, so use the actual width + return child.width + } + return child.implicitWidth + } + + function centerOffset(outerLength, innerLength) { + // calculate the offset of the leading edge of a centered child item + return Math.floor((outerLength - innerLength) / 2.0) + } + + function widthTextButtonSingle(leftMargin, innerSpacing) { + // calculate the remaining width for a centered item + var outerContents = leftMargin + innerSpacing + return root.width - (outerContents * 2) + } + + function widthTextButtonDouble(leftMargin, innerSpacing, centerSpacing) { + // calculate the space available when there are two items with a center + // margin, and share it between the two + var outerContents = leftMargin + innerSpacing + return Math.round((root.width - (outerContents * 2) - centerSpacing) / 2.0) + } + + function widthButtonRowLong(leftButton, rightButton, itemMargin, innerSpacing, outerMargin) { + // calculate the width of a long button row, which is used in the case that there are more + // than three icons. If either left or right button is present, allocate the itemMargin to + // ensure that there is sufficient space; otherwise we can use the special + // outerMargin value + var leftContents = leftButton ? itemMargin + innerSpacing : outerMargin + var rightContents = rightButton ? itemMargin + innerSpacing : outerMargin + return root.width - leftContents - rightContents + } + + function layoutChildren() { + var numChildren = children.length + if (parent == null || root.width == 0 || numChildren == 0) + return + + for (var i = 0; i < numChildren; ++i) { + // make sure all the children have correct parent, height, and y + children[i].parent = root + if (isButtonRow(children[i])) { + var buttonRow = children[i] + // ButtonRow frame height is always tool bar's height in + // landscape, regardless of the current orientation, so we need + // to override the heights of the buttons within (because it's a + // Row, so its height is based on its children) + for (var j = 0; j < buttonRow.children.length; ++j) { + buttonRow.children[j].implicitHeight = defaultHeightToolButton + } + } + // child's vertical center always goes to middle of the toolbar + var childHeight = children[i].hasOwnProperty("implicitHeight") ? + children[i].implicitHeight : children[i].height + children[i].y = root.y + centerOffset(root.implicitHeight, childHeight) + } + + // detect whether we have left and or right items. we need to lay out + // the remaining children (that are not left or right items) whether they + // are tool buttons, text buttons or a button row + var leftItem = isIconButton(children[0]) ? + children[0] : undefined + var rightItem = isIconButton(children[numChildren-1]) ? + children[numChildren-1] : undefined + var childrenRemaining = numChildren - (leftItem != undefined ? 1 : 0) - (rightItem != undefined ? 1 : 0) + var firstRemainingIndex = leftItem != undefined ? 1 : 0 + var lastRemainingIndex = rightItem != undefined ? (numChildren - 2) : (numChildren - 1) + + // precalculate the margins for the left and right items, we will work + // out child sizes assuming they are present + var leftMargin = outerMarginHorizontal + defaultHeightToolBar + var rightMargin = root.width - leftMargin + + // In the case of a lone remaining chlld, or in the case of 2 text + // buttons, we need to override the width + var overrideChildWidth = 0 + for (var p = firstRemainingIndex; p <= lastRemainingIndex; p++) { + var child = children[p] + overrideChildWidth = buttonWidth(child) + + // If necessary, we calculate and override the width first before we + // can calculate the x positions + if ((isTextToolButton(child) && childrenRemaining == 1) + || (isButtonRow(child) && child.children.length == 1)) { + // we treat a button row with a single item like a single tool button, + // but in landscape, calculate size as if there were two buttons + overrideChildWidth = portrait ? + widthTextButtonSingle(leftMargin, innerSpacingTextButtonSingle) : + widthTextButtonDouble(leftMargin, innerSpacingTextButtonDouble, innerSpacingTextButtonDouble) + + } else if (isTextToolButton(child) && childrenRemaining == 2) { + // special case of margins for two text buttons + overrideChildWidth = widthTextButtonDouble( + leftMargin, innerSpacingTextButtonDouble, centerSpacingTextButtonDouble) + + } else if (isButtonRow(child) && ((child.children.length == 2) + || (child.children.length > 2 && leftItem != undefined && rightItem != undefined))) { + // there are special margins if the button row has two children, + // or if it has more than two children and there is a left and + // a right item + overrideChildWidth = widthTextButtonSingle( + leftMargin, innerSpacingButtonRowTwoChildren) + + } else if (isButtonRow(child) && child.children.length > 2) { + // the long button row has special margins, which are used on + // either side if the side icon button is missing on that side. If the item is present, + // the leftMargin can be used on either side to leave space for either icon button + overrideChildWidth = widthButtonRowLong( + leftItem != undefined, + rightItem != undefined, + leftMargin, + innerSpacingButtonRowLong, + outerMarginButtonRowLong) + } + + child.width = overrideChildWidth + } + + if (numChildren == 1) { + var loneChild = children[0] + var loneChildWidth = buttonWidth(loneChild) + if (isButtonRow(loneChild)) { + loneChildWidth = overrideChildWidth + } + if (isIconButton(loneChild)) + loneChild.x = outerMarginHorizontal + else + loneChild.x = centerOffset(root.width, loneChildWidth) + return + } + + // we can easily calculate the positions of the left and right items, + // but if they are missing then correct the margins + if (leftItem != undefined){ + leftItem.x = outerMarginHorizontal + } else { + leftMargin = 0 + } + if (rightItem != undefined){ + rightItem.x = root.width - defaultHeightToolBar - outerMarginHorizontal + } else { + rightMargin = root.width + } + + if (!childrenRemaining) + return; + + if (childrenRemaining == 1) { + var loneChild = children[firstRemainingIndex] + var loneChildWidth = buttonWidth(loneChild) + if (isButtonRow(loneChild)) { + // ButtonRow should have the override width (but it won't have + // been updated yet) + loneChildWidth = overrideChildWidth + } + // lone child is always centered, unless it's a long button row on + // one side only + if (isButtonRow(loneChild) && loneChild.children.length >= 3 + && ((leftItem == undefined) != (rightItem == undefined))) { + loneChild.x = (leftItem != undefined) ? + (leftMargin + innerSpacingButtonRowLong) : outerMarginButtonRowLong + } else { + loneChild.x = centerOffset(root.width, loneChildWidth) + } + } else if (childrenRemaining == 2 && isTextToolButton(children[firstRemainingIndex])) { + // text buttons are distributed around the center with a center spacing + var midPoint = Math.floor(root.width / 2.0) + var halfSpacing = Math.round(platformStyle.paddingLarge / 2.0) + children[firstRemainingIndex].x = midPoint - halfSpacing - buttonWidth(children[firstRemainingIndex]) + children[firstRemainingIndex + 1].x = midPoint + halfSpacing + } else { + // icon buttons are deployed evenly in the remaining space, + // but we need to ensure that the spacings are integer values, + // and share the rounding error to ensure that they are centered + var remainingSpace = rightMargin - leftMargin + var spacingNotRounded = remainingSpace + for (var p = 0; p < childrenRemaining; p++) { + var nextChild = children[leftItem != undefined ? p + 1 : p] + spacingNotRounded -= buttonWidth(nextChild) + } + spacingNotRounded /= (childrenRemaining + 1) + var spacing = Math.floor(spacingNotRounded) + var totalRoundingError = (spacingNotRounded - spacing) * (childrenRemaining + 1) + var curPos = leftMargin + Math.floor(totalRoundingError / 2.0) + + for (var p = 0; p < childrenRemaining; p++) { + var nextChild = children[leftItem != undefined ? p + 1 : p] + curPos += spacing + nextChild.x = curPos + curPos += buttonWidth(nextChild) + } + } + } + } + + Component.onCompleted: internal.layoutChildren() + onParentChanged: internal.layoutChildren() + onChildrenChanged: internal.layoutChildren() + onImplicitWidthChanged: internal.layoutChildren() + onImplicitHeightChanged: internal.layoutChildren() +} diff --git a/declarativeimports/plasmacomponents/qml/qmldir b/declarativeimports/plasmacomponents/qml/qmldir index 5c1d79dba..ae95b5634 100644 --- a/declarativeimports/plasmacomponents/qml/qmldir +++ b/declarativeimports/plasmacomponents/qml/qmldir @@ -26,6 +26,7 @@ ListItem 0.1 ListItem.qml CommonDialog 0.1 CommonDialog.qml SelectionDialog 0.1 SelectionDialog.qml +ToolBarLayout 0.1 ToolBarLayout.qml Page 0.1 Page.qml PageStack 0.1 PageStack.qml From b3597331f738a5963c681c83d81e06672876b291 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 23:00:38 +0100 Subject: [PATCH 34/87] touch specific Menu and MenuItem --- .../plasmacomponentsplugin.cpp | 9 +- .../platformcomponents/touch/Menu.qml | 109 +++++++++++++++++ .../platformcomponents/touch/MenuItem.qml | 113 ++++++++++++++++++ .../platformcomponents/touch/qmldir | 3 + 4 files changed, 229 insertions(+), 5 deletions(-) create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/MenuItem.qml diff --git a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index f4a6c5eb6..ccca36ac7 100644 --- a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -38,13 +38,12 @@ void PlasmaComponentsPlugin::registerTypes(const char *uri) KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform"); const QString componentsPlatform = cg.readEntry("name", "desktop"); - qmlRegisterType(uri, 0, 1, "Menu"); - qmlRegisterType(uri, 0, 1, "ContextMenu"); - qmlRegisterType(uri, 0, 1, "MenuItem"); - - if (componentsPlatform == "desktop") { qmlRegisterType(uri, 0, 1, "QueryDialog"); + + qmlRegisterType(uri, 0, 1, "Menu"); + qmlRegisterType(uri, 0, 1, "ContextMenu"); + qmlRegisterType(uri, 0, 1, "MenuItem"); } qmlRegisterType(uri, 0, 1, "RangeModel"); diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml new file mode 100644 index 000000000..b60c7c037 --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml @@ -0,0 +1,109 @@ +/* +* Copyright (C) 2011 by Marco Martin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore +import "." 0.1 + +Item { + id: root + + default property alias content: visualModel.children + property Item visualParent + property int status: DialogStatus.Closed + + function open() + { + var parent = root.visualParent ? root.visualParent : root.parent + var pos = dialog.popupPosition(parent, Qt.alignCenter) + dialog.x = pos.x + dialog.y = pos.y + + dialog.visible = true + dialog.focus = true + } + + function close() + { + dialog.visible = false + } + + visible: false + + PlasmaCore.Dialog { + id: dialog + visible: false + windowFlags: Qt.Popup + onVisibleChanged: { + if (visible) { + status = DialogStatus.Open + } else { + status = DialogStatus.Closed + } + } + + mainItem: Item { + id: contentItem + + width: theme.defaultFont.mSize.width * 12 + height: Math.min(listView.contentHeight, theme.defaultFont.mSize.height * 25) + + + ListView { + id: listView + anchors.fill: parent + + currentIndex : -1 + clip: true + + model: VisualItemModel { + id: visualModel + onChildrenChanged: { + for (var i = 0; i < children.length; ++i) { + if (children[i].clicked != undefined) + children[i].clicked.connect(root.close) + } + } + } + } + + ScrollBar { + id: scrollBar + flickableItem: listView + visible: listView.contentHeight > contentItem.height + //platformInverted: root.platformInverted + anchors { top: listView.top; right: listView.right } + } + } + } + + + onStatusChanged: { + if (status == DialogStatus.Opening) { + if (listView.currentItem != null) { + listView.currentItem.focus = false + } + listView.currentIndex = -1 + listView.positionViewAtIndex(0, ListView.Beginning) + } + else if (status == DialogStatus.Open) { + listView.focus = true + } + } +} diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/MenuItem.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/MenuItem.qml new file mode 100644 index 000000000..9ef171d5c --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/MenuItem.qml @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: root + + property alias text: textArea.text + + signal clicked + + property int implicitWidth: textArea.paintedWidth + 6 + width: parent.width + height: textArea.paintedHeight + 6 + + Label { + id: textArea + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + } + + + MouseArea { + id: mouseArea + + property bool canceled: false + + anchors.fill: parent + + onPressed: { + canceled = false + } + onClicked: { + if (!canceled) + root.clicked() + } + onExited: canceled = true + } + + Keys.onPressed: { + event.accepted = true + switch (event.key) { + case Qt.Key_Select: + case Qt.Key_Enter: + case Qt.Key_Return: { + if (!event.isAutoRepeat) { + root.clicked() + } + break + } + + case Qt.Key_Up: { + if (ListView.view != null) + ListView.view.decrementCurrentIndex() + else + event.accepted = false + break + } + + case Qt.Key_Down: { + if (ListView.view != null) + ListView.view.incrementCurrentIndex() + else + event.accepted = false + break + } + default: { + event.accepted = false + break + } + } + } +} diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir index b3dde581a..27cf61792 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir @@ -29,6 +29,9 @@ QueryDialog 0.1 QueryDialog.qml SelectionDialog 0.1 SelectionDialog.qml Window 0.1 Window.qml ToolBarLayout 0.1 ToolBarLayout.qml +Menu 0.1 Menu.qml +ContextMenu 0.1 Menu.qml +MenuItem 0.1 MenuItem.qml Page 0.1 Page.qml PageStack 0.1 PageStack.qml From c0de261ccc07803bc85e99bc0794b63027b3eeca Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 8 Nov 2011 23:07:42 +0100 Subject: [PATCH 35/87] support visualParent property --- declarativeimports/plasmacomponents/qmenu.cpp | 23 ++++++++++++++++++- declarativeimports/plasmacomponents/qmenu.h | 8 +++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qmenu.cpp b/declarativeimports/plasmacomponents/qmenu.cpp index 36d6e18da..db613ee7b 100644 --- a/declarativeimports/plasmacomponents/qmenu.cpp +++ b/declarativeimports/plasmacomponents/qmenu.cpp @@ -24,6 +24,7 @@ #include #include #include +#include QMenuProxy::QMenuProxy (QObject *parent) : QObject(parent), @@ -57,6 +58,21 @@ DialogStatus::Status QMenuProxy::status() const return m_status; } +QDeclarativeItem *QMenuProxy::visualParent() const +{ + return m_visualParent.data(); +} + +void QMenuProxy::setVisualParent(QDeclarativeItem *parent) +{ + if (m_visualParent.data() == parent) { + return; + } + + m_visualParent = parent; + emit visualParentChanged(); +} + void QMenuProxy::showMenu(int x, int y) { m_menu->clear(); @@ -79,7 +95,12 @@ void QMenuProxy::open() } m_menu->updateGeometry(); - QGraphicsObject *parentItem = qobject_cast(parent()); + QGraphicsObject *parentItem; + if (m_visualParent) { + parentItem = qobject_cast(parent()); + } else { + parentItem = m_visualParent.data(); + } if (!parentItem || !parentItem->scene()) { showMenu(0, 0); diff --git a/declarativeimports/plasmacomponents/qmenu.h b/declarativeimports/plasmacomponents/qmenu.h index 83c15a61f..0f503efaf 100644 --- a/declarativeimports/plasmacomponents/qmenu.h +++ b/declarativeimports/plasmacomponents/qmenu.h @@ -26,12 +26,15 @@ #include "qmenuitem.h" #include "enums.h" +class QDeclarativeItem; + class QMenuProxy : public QObject { Q_OBJECT Q_PROPERTY(QDeclarativeListProperty items READ items CONSTANT) Q_CLASSINFO("DefaultProperty", "items") + Q_PROPERTY(QDeclarativeItem *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged()) Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged) public: @@ -43,17 +46,22 @@ public: QMenuItem *action(int) const; DialogStatus::Status status() const; + QDeclarativeItem *visualParent() const; + void setVisualParent(QDeclarativeItem *parent); + void showMenu(int x, int y); Q_INVOKABLE void open(); Q_INVOKABLE void close(); Q_SIGNALS: void statusChanged(); + void visualParentChanged(); private: QList m_items; QMenu *m_menu; DialogStatus::Status m_status; + QWeakPointer m_visualParent; }; #endif //QMENU_PROXY_H From 6a19c2da5bc215c732f60e304c43ab24e1488d7e Mon Sep 17 00:00:00 2001 From: Aaron Seigo Date: Wed, 9 Nov 2011 12:56:49 +0100 Subject: [PATCH 36/87] make it easy to generate hashes for plasma packages --- tools/plasmapkg/main.cpp | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/plasmapkg/main.cpp b/tools/plasmapkg/main.cpp index b4241eceb..dbfd1568a 100644 --- a/tools/plasmapkg/main.cpp +++ b/tools/plasmapkg/main.cpp @@ -39,7 +39,7 @@ #include static const char description[] = I18N_NOOP("Install, list, remove Plasma packages"); -static const char version[] = "0.1"; +static const char version[] = "0.2"; void output(const QString &msg) { @@ -180,6 +180,8 @@ int main(int argc, char **argv) KCmdLineArgs::init( argc, argv, &aboutData ); KCmdLineOptions options; + options.add("h"); + options.add("hash ", ki18nc("Do not translate ", "Generate a SHA1 hash for the package at ")); options.add("g"); options.add("global", ki18n("For install or remove, operates on packages installed for all users.")); options.add("t"); @@ -206,6 +208,26 @@ int main(int argc, char **argv) KApplication app; KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if (args->isSet("hash")) { + const QString path = args->getOption("hash"); + Plasma::PackageStructure::Ptr structure(new Plasma::PackageStructure); + Plasma::Package package(path, structure); + const QString hash = package.contentsHash(); + if (hash.isEmpty()) { + output(i18n("Failed to generate a Package hash for %1", path)); + exit(1); + } + + output(i18n("SHA1 hash for Package at %1: '%2'", path, hash)); + exit(0); + } + + if (args->isSet("list-types")) { + listTypes(); + exit(0); + } + QString type = args->getOption("type"); QString packageRoot = type; QString servicePrefix; @@ -214,11 +236,6 @@ int main(int argc, char **argv) QString package; QString packageFile; - if (args->isSet("list-types")) { - listTypes(); - exit(0); - } - if (args->isSet("remove")) { package = args->getOption("remove"); } else if (args->isSet("upgrade")) { From 8cccd7c834fe02ee48b68bc3e3c7db9e4b4617b5 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 14:21:54 +0100 Subject: [PATCH 37/87] scrollbar rewrite no binding loops no rotation transformations actual scrollbar is a loaded component: will be shared with scrolldecorator --- .../plasmacomponents/qml/ScrollBar.qml | 499 +++++++++--------- 1 file changed, 252 insertions(+), 247 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index 9a5b637c0..f1588d5cc 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright 2011 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -26,22 +27,20 @@ Item { // Common API property Flickable flickableItem: null - property bool interactive + property int orientation: Qt.Vertical + property bool interactive: true // Plasma API - property int orientation: Qt.Vertical property bool animated: true property bool inverted: false property bool updateValueWhileDragging: true property alias stepSize: range.stepSize - property alias pressed: mouseArea.pressed + //property alias pressed: mouseArea.pressed property real scrollButtonInterval: 50 // Convinience API property bool _isVertical: orientation == Qt.Vertical property bool _showButtons: stepSize != 0 - property bool _inverted: _isVertical ? - !scrollbar.inverted : scrollbar.inverted implicitWidth: _isVertical ? 22 : 200 implicitHeight: _isVertical ? 200 : 22 @@ -49,7 +48,7 @@ Item { // disabled scroll bars opacity: enabled ? 1.0 : 0.5 - visible: flickableItem && handle.width < contents.width + visible: flickableItem && internalLoader.handleEnabled anchors { right: flickableItem.right @@ -58,300 +57,306 @@ Item { bottom: flickableItem.bottom } - function incrementValue(increment) { - if (!flickableItem) - return; - - if (_isVertical) { - flickableItem.contentY = Math.min(flickableItem.contentHeight, - flickableItem.contentY + increment); - } else { - flickableItem.contentX = Math.min(flickableItem.contentWidth, - flickableItem.contentX + increment); - } - } - Keys.onUpPressed: { if (!enabled || !_isVertical) return; - if (_inverted) - incrementValue(-stepSize); + if (inverted) + internalLoader.incrementValue(-stepSize); else - incrementValue(stepSize); + internalLoader.incrementValue(stepSize); } Keys.onDownPressed: { if (!enabled || !_isVertical) return; - if (_inverted) - incrementValue(stepSize); + if (inverted) + internalLoader.incrementValue(stepSize); else - incrementValue(-stepSize); + internalLoader.incrementValue(-stepSize); } Keys.onLeftPressed: { if (!enabled || _isVertical) return; - if (_inverted) - incrementValue(stepSize); + if (inverted) + internalLoader.incrementValue(stepSize); else - incrementValue(-stepSize); + internalLoader.incrementValue(-stepSize); } Keys.onRightPressed: { if (!enabled || _isVertical) return; - if (_inverted) - incrementValue(-stepSize); + if (inverted) + internalLoader.incrementValue(-stepSize); else - incrementValue(stepSize); + internalLoader.incrementValue(stepSize); } + Loader { + id: internalLoader + anchors.fill: parent + //property bool handleEnabled: _isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width + property bool handleEnabled: _isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width - Item { + function incrementValue(increment) + { + if (!flickableItem) + return; - width: _isVertical ? scrollbar.height : scrollbar.width - height: _isVertical ? scrollbar.width : scrollbar.height - rotation: _isVertical ? -90 : 0 - - anchors.centerIn: parent - PlasmaCore.Svg { - id: scrollbarSvg - imagePath: "widgets/scrollbar" + if (_isVertical) { + flickableItem.contentY = Math.max(0, Math.min(flickableItem.contentHeight, + flickableItem.contentY + increment)) + } else { + flickableItem.contentX = Math.max(0, Math.min(flickableItem.contentWidth, + flickableItem.contentX + increment)) + } } - PlasmaCore.SvgItem { - id: leftButton + RangeModel { + id: range - anchors { - left: parent.left - verticalCenter: parent.verticalCenter - } - height: 18 - width: _showButtons ? 18 : 0 - svg: scrollbarSvg - elementId: { - if (leftMousArea.pressed) - return "sunken-arrow-left"; + minimumValue: 0 + maximumValue: { + var diff; + if (_isVertical) { + diff = flickableItem.contentHeight - flickableItem.height + } else { + diff = flickableItem.contentWidth - flickableItem.width + } - if (scrollbar.activeFocus || leftMousArea.containsMouse) - return "mouseover-arrow-left"; - else - return "arrow-left"; + return Math.max(0, diff) } - MouseArea { - id: leftMousArea + stepSize: 10 + inverted: scrollbar.inverted + positionAtMinimum: 0 + positionAtMaximum: { + if (_isVertical) { + internalLoader.item.contents.height - internalLoader.item.handle.height + } else { + internalLoader.item.contents.width - internalLoader.item.handle.width + } + } + value: _isVertical ? flickableItem.contentY : flickableItem.contentX + onValueChanged: { + if (flickableItem.moving) { + return + } - anchors.fill: parent - enabled: scrollbar.enabled - Timer { - id: leftTimer - interval: scrollbar.scrollButtonInterval; - running: parent.pressed - repeat: true - onTriggered: { - scrollbar.forceActiveFocus(); - if (_inverted) - incrementValue(stepSize); - else - incrementValue(-stepSize); - } + if (_isVertical) { + flickableItem.contentY = value + } else { + flickableItem.contentX = value + } + } + + position: _isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x + + onPositionChanged: { + if (internalLoader.item.mouseArea.pressed) { + return + } + + if (_isVertical) { + internalLoader.item.handle.y = position + } else { + internalLoader.item.handle.x = position } } } - PlasmaCore.SvgItem { - id: rightButton - - anchors { - right: parent.right - verticalCenter: parent.verticalCenter - } - height: 18 - width: _showButtons ? 18 : 0 - svg: scrollbarSvg - elementId: { - if (rightMousArea.pressed) - return "sunken-arrow-right"; - - if (scrollbar.activeFocus || rightMousArea.containsMouse) - return "mouseover-arrow-right"; - else - return "arrow-right"; - } - - MouseArea { - id: rightMousArea - - anchors.fill: parent - enabled: scrollbar.enabled - Timer { - id: rightTimer - interval: scrollbar.scrollButtonInterval; - running: parent.pressed; - repeat: true - onTriggered: { - scrollbar.forceActiveFocus(); - if (_inverted) - incrementValue(-stepSize); - else - incrementValue(stepSize); - } - } - } - } - - Item { - id: contents - - anchors { - left: leftButton.right - top: parent.top - bottom: parent.bottom - right: rightButton.left - } - - RangeModel { - id: range - - minimumValue: 0 - maximumValue: { - var diff; - if (_isVertical) - diff = flickableItem.contentHeight - flickableItem.height; - else - diff = flickableItem.contentWidth - flickableItem.width; - - return Math.max(0, diff); - } - stepSize: 10 - inverted: _inverted - positionAtMinimum: 0 + handle.width / 2 - positionAtMaximum: contents.width - handle.width / 2 - value: _isVertical ? flickableItem.contentY : flickableItem.contentX - onValueChanged: { - if (flickableItem.flicking) - return; - - if (_isVertical) - flickableItem.contentY = value; - else - flickableItem.contentX = value; - } - position: handle.x - onPositionChanged: { handle.x = position; } - } - + sourceComponent: Component { PlasmaCore.FrameSvgItem { - id: groove - + id: background anchors.fill: parent - imagePath: "widgets/scrollbar" - prefix: "background-horizontal" - } + imagePath:"widgets/scrollbar" + prefix: _isVertical ? "background-vertical" : "background-horizontal" - PlasmaCore.FrameSvgItem { - id: handle + property Item handle: handle - transform: Translate { x: - handle.width / 2 } - x: fakeHandle.x - anchors.verticalCenter: groove.verticalCenter - width: { - var ratio; - if (_isVertical) - ratio = flickableItem.visibleArea.heightRatio; - else - ratio = flickableItem.visibleArea.widthRatio; + property Item contents: contents + Item { + id: contents + anchors { + fill: parent + leftMargin: _isVertical || stepSize <= 0 ? 0 : leftButton.width + rightMargin: _isVertical || stepSize <= 0 ? 0 : rightButton.width + topMargin: _isVertical && stepSize > 0 ? leftButton.height : 0 + bottomMargin: _isVertical && stepSize > 0 ? rightButton.height : 0 + } - return ratio * parent.width; - } - height: parent.height - margins.top // TODO: check mergin - imagePath: "widgets/scrollbar" - prefix: { - if (scrollbar.pressed) - return "sunken-slider"; + PlasmaCore.FrameSvgItem { + id: handle + imagePath:"widgets/scrollbar" + prefix: { + if (mouseArea.pressed) { + return "sunken-slider" + } - if (scrollbar.activeFocus || mouseArea.containsMouse) - return "mouseover-slider"; - else - return "slider"; + if (scrollbar.activeFocus || mouseArea.containsMouse) { + return "mouseover-slider" + } else { + return "slider" + } + } + + property int length: _isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width + + width: _isVertical ? parent.width : length + height: _isVertical ? length : parent.height + } } - Behavior on x { - id: behavior - enabled: !mouseArea.drag.active && scrollbar.animated && - !flickableItem.flicking + PlasmaCore.Svg { + id: scrollbarSvg + imagePath: "widgets/scrollbar" + } - PropertyAnimation { - duration: behavior.enabled ? 150 : 0 - easing.type: Easing.OutSine + PlasmaCore.SvgItem { + id: leftButton + visible: stepSize > 0 + + anchors { + left: _isVertical ? undefined : parent.left + verticalCenter: _isVertical ? undefined : parent.verticalCenter + top: _isVertical ? 0 : undefined + horizontalCenter: _isVertical ? parent.horizontalCenter : undefined + } + height: 18 + width: _showButtons ? 18 : 0 + svg: scrollbarSvg + elementId: { + if (leftMouseArea.pressed) { + return _isVertical ? "sunken-arrow-up" : "sunken-arrow-left" + } + + if (scrollbar.activeFocus || leftMouseArea.containsMouse) { + return _isVertical ? "mouseover-arrow-up" : "mouseover-arrow-left" + } else { + return _isVertical ? "mouseover-arrow-up" : "arrow-left" + } + } + + MouseArea { + id: leftMouseArea + + anchors.fill: parent + enabled: scrollbar.enabled + Timer { + id: leftTimer + interval: scrollbar.scrollButtonInterval; + running: parent.pressed + repeat: true + onTriggered: { + scrollbar.forceActiveFocus() + if (inverted) { + internalLoader.incrementValue(stepSize); + } else { + internalLoader.incrementValue(-stepSize); + } + } + } + } + } + + PlasmaCore.SvgItem { + id: rightButton + visible: stepSize > 0 + + anchors { + right: _isVertical ? undefined : parent.right + verticalCenter: _isVertical ? undefined : parent.verticalCenter + bottom: _isVertical ? parent.bottom : undefined + horizontalCenter: _isVertical ? parent.horizontalCenter : undefined + } + height: 18 + width: _showButtons ? 18 : 0 + svg: scrollbarSvg + elementId: { + if (leftMouseArea.pressed) { + return _isVertical ? "sunken-arrow-down" : "sunken-arrow-right" + } + + if (scrollbar.activeFocus || leftMouseArea.containsMouse) { + return _isVertical ? "mouseover-arrow-down" : "mouseover-arrow-right" + } else { + return _isVertical ? "mouseover-arrow-down" : "arrow-right" + } + } + + MouseArea { + id: rightMouseArea + + anchors.fill: parent + enabled: scrollbar.enabled + Timer { + id: rightTimer + interval: scrollbar.scrollButtonInterval; + running: parent.pressed; + repeat: true + onTriggered: { + scrollbar.forceActiveFocus(); + if (inverted) + internalLoader.incrementValue(-stepSize); + else + internalLoader.incrementValue(stepSize); + } + } + } + } + + property MouseArea mouseArea: mouseArea + MouseArea { + id: mouseArea + + anchors.fill: contents + enabled: scrollbar.enabled + hoverEnabled: true + drag { + target: handle + axis: _isVertical ? Drag.YAxis : Drag.XAxis + minimumX: range.positionAtMinimum + maximumX: range.positionAtMaximum + minimumY: range.positionAtMinimum + maximumY: range.positionAtMaximum + } + + onPressed: { + if (_isVertical) { + // Clamp the value + var newY = Math.max(mouse.y, drag.minimumY); + newY = Math.min(newY, drag.maximumY); + + // Debounce the press: a press event inside the handler will not + // change its position, the user needs to drag it. + if (newY > handle.y + handle.height) { + handle.y = mouse.y - handle.height + } else if (newY < handle.y) { + handle.y = mouse.y + } + } else { + // Clamp the value + var newX = Math.max(mouse.x, drag.minimumX); + newX = Math.min(newX, drag.maximumX); + + // Debounce the press: a press event inside the handler will not + // change its position, the user needs to drag it. + if (newX > handle.x + handle.width) { + handle.x = mouse.x - handle.width + } else if (newX < handle.x) { + handle.x = mouse.x + } + } + + scrollbar.forceActiveFocus(); } } } - - Item { - id: fakeHandle - width: handle.width - height: handle.height - transform: Translate { x: - handle.width / 2 } - } - - MouseArea { - id: mouseArea - - anchors.fill: parent - enabled: scrollbar.enabled - drag { - target: fakeHandle - axis: Drag.XAxis - minimumX: range.positionAtMinimum - maximumX: range.positionAtMaximum - } - - onPressed: { - // Clamp the value - var newX = Math.max(mouse.x, drag.minimumX); - newX = Math.min(newX, drag.maximumX); - - // Debounce the press: a press event inside the handler will not - // change its position, the user needs to drag it. - if (Math.abs(newX - fakeHandle.x) > handle.width / 2) - range.position = newX; - - scrollbar.forceActiveFocus(); - } - onReleased: { - // If we don't update while dragging, this is the only - // moment that the range is updated. - if (!scrollbar.updateValueWhileDragging) - range.position = fakeHandle.x; - } - } - } - - // Range position normally follow fakeHandle, except when - // 'updateValueWhileDragging' is false. In this case it will only follow - // if the user is not pressing the handle. - Binding { - when: updateValueWhileDragging || !mouseArea.pressed - target: range - property: "position" - value: fakeHandle.x - } - - // During the drag, we simply ignore position set from the range, this - // means that setting a value while dragging will not "interrupt" the - // dragging activity. - Binding { - when: !mouseArea.drag.active - target: fakeHandle - property: "x" - value: range.position } } } From 04eb4f327550437342d4c50b183d179c527019f2 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 14:34:53 +0100 Subject: [PATCH 38/87] move the scrollbar delegate to own file --- .../plasmacomponents/qml/ScrollBar.qml | 210 +---------------- .../qml/ScrollBarDelegate.qml | 211 ++++++++++++++++++ 2 files changed, 222 insertions(+), 199 deletions(-) create mode 100644 declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index f1588d5cc..05adb98ed 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 by Daker Fernandes Pinheiro -* Copyright 2011 Marco Martin +* Copyright (C) 2011 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -31,9 +31,8 @@ Item { property bool interactive: true // Plasma API - property bool animated: true property bool inverted: false - property bool updateValueWhileDragging: true + property bool animated: true property alias stepSize: range.stepSize //property alias pressed: mouseArea.pressed property real scrollButtonInterval: 50 @@ -58,27 +57,27 @@ Item { } Keys.onUpPressed: { - if (!enabled || !_isVertical) + if (!interactive || !enabled || !_isVertical) return; if (inverted) - internalLoader.incrementValue(-stepSize); - else internalLoader.incrementValue(stepSize); + else + internalLoader.incrementValue(-stepSize); } Keys.onDownPressed: { - if (!enabled || !_isVertical) + if (!interactive || !enabled || !_isVertical) return; if (inverted) - internalLoader.incrementValue(stepSize); - else internalLoader.incrementValue(-stepSize); + else + internalLoader.incrementValue(stepSize); } Keys.onLeftPressed: { - if (!enabled || _isVertical) + if (!interactive || !enabled || _isVertical) return; if (inverted) @@ -88,7 +87,7 @@ Item { } Keys.onRightPressed: { - if (!enabled || _isVertical) + if (!interactive || !enabled || _isVertical) return; if (inverted) @@ -170,193 +169,6 @@ Item { } } - sourceComponent: Component { - PlasmaCore.FrameSvgItem { - id: background - anchors.fill: parent - imagePath:"widgets/scrollbar" - prefix: _isVertical ? "background-vertical" : "background-horizontal" - - property Item handle: handle - - property Item contents: contents - Item { - id: contents - anchors { - fill: parent - leftMargin: _isVertical || stepSize <= 0 ? 0 : leftButton.width - rightMargin: _isVertical || stepSize <= 0 ? 0 : rightButton.width - topMargin: _isVertical && stepSize > 0 ? leftButton.height : 0 - bottomMargin: _isVertical && stepSize > 0 ? rightButton.height : 0 - } - - PlasmaCore.FrameSvgItem { - id: handle - imagePath:"widgets/scrollbar" - prefix: { - if (mouseArea.pressed) { - return "sunken-slider" - } - - if (scrollbar.activeFocus || mouseArea.containsMouse) { - return "mouseover-slider" - } else { - return "slider" - } - } - - property int length: _isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width - - width: _isVertical ? parent.width : length - height: _isVertical ? length : parent.height - } - } - - PlasmaCore.Svg { - id: scrollbarSvg - imagePath: "widgets/scrollbar" - } - - PlasmaCore.SvgItem { - id: leftButton - visible: stepSize > 0 - - anchors { - left: _isVertical ? undefined : parent.left - verticalCenter: _isVertical ? undefined : parent.verticalCenter - top: _isVertical ? 0 : undefined - horizontalCenter: _isVertical ? parent.horizontalCenter : undefined - } - height: 18 - width: _showButtons ? 18 : 0 - svg: scrollbarSvg - elementId: { - if (leftMouseArea.pressed) { - return _isVertical ? "sunken-arrow-up" : "sunken-arrow-left" - } - - if (scrollbar.activeFocus || leftMouseArea.containsMouse) { - return _isVertical ? "mouseover-arrow-up" : "mouseover-arrow-left" - } else { - return _isVertical ? "mouseover-arrow-up" : "arrow-left" - } - } - - MouseArea { - id: leftMouseArea - - anchors.fill: parent - enabled: scrollbar.enabled - Timer { - id: leftTimer - interval: scrollbar.scrollButtonInterval; - running: parent.pressed - repeat: true - onTriggered: { - scrollbar.forceActiveFocus() - if (inverted) { - internalLoader.incrementValue(stepSize); - } else { - internalLoader.incrementValue(-stepSize); - } - } - } - } - } - - PlasmaCore.SvgItem { - id: rightButton - visible: stepSize > 0 - - anchors { - right: _isVertical ? undefined : parent.right - verticalCenter: _isVertical ? undefined : parent.verticalCenter - bottom: _isVertical ? parent.bottom : undefined - horizontalCenter: _isVertical ? parent.horizontalCenter : undefined - } - height: 18 - width: _showButtons ? 18 : 0 - svg: scrollbarSvg - elementId: { - if (leftMouseArea.pressed) { - return _isVertical ? "sunken-arrow-down" : "sunken-arrow-right" - } - - if (scrollbar.activeFocus || leftMouseArea.containsMouse) { - return _isVertical ? "mouseover-arrow-down" : "mouseover-arrow-right" - } else { - return _isVertical ? "mouseover-arrow-down" : "arrow-right" - } - } - - MouseArea { - id: rightMouseArea - - anchors.fill: parent - enabled: scrollbar.enabled - Timer { - id: rightTimer - interval: scrollbar.scrollButtonInterval; - running: parent.pressed; - repeat: true - onTriggered: { - scrollbar.forceActiveFocus(); - if (inverted) - internalLoader.incrementValue(-stepSize); - else - internalLoader.incrementValue(stepSize); - } - } - } - } - - property MouseArea mouseArea: mouseArea - MouseArea { - id: mouseArea - - anchors.fill: contents - enabled: scrollbar.enabled - hoverEnabled: true - drag { - target: handle - axis: _isVertical ? Drag.YAxis : Drag.XAxis - minimumX: range.positionAtMinimum - maximumX: range.positionAtMaximum - minimumY: range.positionAtMinimum - maximumY: range.positionAtMaximum - } - - onPressed: { - if (_isVertical) { - // Clamp the value - var newY = Math.max(mouse.y, drag.minimumY); - newY = Math.min(newY, drag.maximumY); - - // Debounce the press: a press event inside the handler will not - // change its position, the user needs to drag it. - if (newY > handle.y + handle.height) { - handle.y = mouse.y - handle.height - } else if (newY < handle.y) { - handle.y = mouse.y - } - } else { - // Clamp the value - var newX = Math.max(mouse.x, drag.minimumX); - newX = Math.min(newX, drag.maximumX); - - // Debounce the press: a press event inside the handler will not - // change its position, the user needs to drag it. - if (newX > handle.x + handle.width) { - handle.x = mouse.x - handle.width - } else if (newX < handle.x) { - handle.x = mouse.x - } - } - - scrollbar.forceActiveFocus(); - } - } - } - } + source: "ScrollBarDelegate.qml" } } diff --git a/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml new file mode 100644 index 000000000..0934e63dc --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml @@ -0,0 +1,211 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright (C) 2011 Marco Martin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore + + +PlasmaCore.FrameSvgItem { + id: background + anchors.fill: parent + imagePath:"widgets/scrollbar" + prefix: _isVertical ? "background-vertical" : "background-horizontal" + + property Item handle: handle + + property Item contents: contents + Item { + id: contents + anchors { + fill: parent + leftMargin: _isVertical || stepSize <= 0 ? 0 : leftButton.width + rightMargin: _isVertical || stepSize <= 0 ? 0 : rightButton.width + topMargin: _isVertical && stepSize > 0 ? leftButton.height : 0 + bottomMargin: _isVertical && stepSize > 0 ? rightButton.height : 0 + } + + PlasmaCore.FrameSvgItem { + id: handle + imagePath:"widgets/scrollbar" + prefix: { + if (mouseArea.pressed) { + return "sunken-slider" + } + + if (scrollbar.activeFocus || mouseArea.containsMouse) { + return "mouseover-slider" + } else { + return "slider" + } + } + + property int length: _isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width + + width: _isVertical ? parent.width : length + height: _isVertical ? length : parent.height + } + } + + PlasmaCore.Svg { + id: scrollbarSvg + imagePath: "widgets/scrollbar" + } + + PlasmaCore.SvgItem { + id: leftButton + visible: stepSize > 0 + + anchors { + left: _isVertical ? undefined : parent.left + verticalCenter: _isVertical ? undefined : parent.verticalCenter + top: _isVertical ? 0 : undefined + horizontalCenter: _isVertical ? parent.horizontalCenter : undefined + } + height: 18 + width: _showButtons ? 18 : 0 + svg: scrollbarSvg + elementId: { + if (leftMouseArea.pressed) { + return _isVertical ? "sunken-arrow-up" : "sunken-arrow-left" + } + + if (scrollbar.activeFocus || leftMouseArea.containsMouse) { + return _isVertical ? "mouseover-arrow-up" : "mouseover-arrow-left" + } else { + return _isVertical ? "mouseover-arrow-up" : "arrow-left" + } + } + + MouseArea { + id: leftMouseArea + + anchors.fill: parent + enabled: scrollbar.enabled + Timer { + id: leftTimer + interval: scrollbar.scrollButtonInterval; + running: parent.pressed + repeat: true + onTriggered: { + scrollbar.forceActiveFocus() + if (inverted) { + internalLoader.incrementValue(stepSize); + } else { + internalLoader.incrementValue(-stepSize); + } + } + } + } + } + + PlasmaCore.SvgItem { + id: rightButton + visible: stepSize > 0 + + anchors { + right: _isVertical ? undefined : parent.right + verticalCenter: _isVertical ? undefined : parent.verticalCenter + bottom: _isVertical ? parent.bottom : undefined + horizontalCenter: _isVertical ? parent.horizontalCenter : undefined + } + height: 18 + width: _showButtons ? 18 : 0 + svg: scrollbarSvg + elementId: { + if (leftMouseArea.pressed) { + return _isVertical ? "sunken-arrow-down" : "sunken-arrow-right" + } + + if (scrollbar.activeFocus || leftMouseArea.containsMouse) { + return _isVertical ? "mouseover-arrow-down" : "mouseover-arrow-right" + } else { + return _isVertical ? "mouseover-arrow-down" : "arrow-right" + } + } + + MouseArea { + id: rightMouseArea + + anchors.fill: parent + enabled: scrollbar.enabled + Timer { + id: rightTimer + interval: scrollbar.scrollButtonInterval; + running: parent.pressed; + repeat: true + onTriggered: { + scrollbar.forceActiveFocus(); + if (inverted) + internalLoader.incrementValue(-stepSize); + else + internalLoader.incrementValue(stepSize); + } + } + } + } + + property MouseArea mouseArea: mouseArea + MouseArea { + id: mouseArea + + anchors.fill: contents + enabled: scrollbar.enabled + hoverEnabled: true + drag { + target: handle + axis: _isVertical ? Drag.YAxis : Drag.XAxis + minimumX: range.positionAtMinimum + maximumX: range.positionAtMaximum + minimumY: range.positionAtMinimum + maximumY: range.positionAtMaximum + } + + onPressed: { + if (_isVertical) { + // Clamp the value + var newY = Math.max(mouse.y, drag.minimumY); + newY = Math.min(newY, drag.maximumY); + + // Debounce the press: a press event inside the handler will not + // change its position, the user needs to drag it. + if (newY > handle.y + handle.height) { + handle.y = mouse.y - handle.height + } else if (newY < handle.y) { + handle.y = mouse.y + } + } else { + // Clamp the value + var newX = Math.max(mouse.x, drag.minimumX); + newX = Math.min(newX, drag.maximumX); + + // Debounce the press: a press event inside the handler will not + // change its position, the user needs to drag it. + if (newX > handle.x + handle.width) { + handle.x = mouse.x - handle.width + } else if (newX < handle.x) { + handle.x = mouse.x + } + } + + scrollbar.forceActiveFocus(); + } + } +} + From ab10ea082bf1f764e7e84d6d995c7f0218362bf0 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 15:03:29 +0100 Subject: [PATCH 39/87] use a scroll decorator delegate when not interactive --- .../plasmacomponents/qml/ScrollBar.qml | 8 +- .../qml/ScrollDecoratorDelegate.qml | 80 +++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index 05adb98ed..366432b07 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -41,8 +41,8 @@ Item { property bool _isVertical: orientation == Qt.Vertical property bool _showButtons: stepSize != 0 - implicitWidth: _isVertical ? 22 : 200 - implicitHeight: _isVertical ? 200 : 22 + implicitWidth: _isVertical ? (interactive ? 22 : 12) : 200 + implicitHeight: _isVertical ? 200 : (interactive ? 22 : 12) // TODO: needs to define if there will be specific graphics for // disabled scroll bars opacity: enabled ? 1.0 : 0.5 @@ -157,7 +157,7 @@ Item { position: _isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x onPositionChanged: { - if (internalLoader.item.mouseArea.pressed) { + if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) { return } @@ -169,6 +169,6 @@ Item { } } - source: "ScrollBarDelegate.qml" + source: interactive ? "ScrollBarDelegate.qml" : "ScrollDecoratorDelegate.qml" } } diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml new file mode 100644 index 000000000..7e6f03ff2 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml @@ -0,0 +1,80 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright (C) 2011 Marco Martin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore + + +PlasmaCore.FrameSvgItem { + id: background + anchors.fill: parent + imagePath:"widgets/scrollbar" + prefix: _isVertical ? "background-vertical" : "background-horizontal" + + opacity: 0 + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.OutQuad + } + } + + property Item handle: handle + + property Item contents: contents + Item { + id: contents + anchors.fill: parent + + PlasmaCore.FrameSvgItem { + id: handle + imagePath:"widgets/scrollbar" + prefix: "slider" + + property int length: _isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width + + width: _isVertical ? parent.width : length + height: _isVertical ? length : parent.height + } + } + + property MouseArea mouseArea: null + + Connections { + target: flickableItem + onMovingChanged: { + if (flickableItem.moving) { + background.opacity = 1 + } else { + opacityTimer.restart() + } + } + } + Timer { + id: opacityTimer + interval: 500 + repeat: false + running: false + onTriggered: { + background.opacity = 0 + } + } +} + From cd710f265814931eba09599a0e3dc197d7d854e7 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 15:07:11 +0100 Subject: [PATCH 40/87] ScrollDecorator in a non interactive scrollbar --- .../plasmacomponents/qml/ScrollDecorator.qml | 97 +------------------ 1 file changed, 4 insertions(+), 93 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml b/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml index 74d555cb8..b0fe83bae 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml @@ -1,5 +1,5 @@ /* -* Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright (C) 2011 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -17,97 +17,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import QtQuick 1.1 -import org.kde.plasma.core 0.1 as PlasmaCore +import QtQuick 1.0 -Item { - id: scrollDecorator - - // Common API - property Flickable flickableItem - - // Plasma API - property int orientation: Qt.Vertical - property bool inverted: false - - // Convinience API - property bool _isVertical: orientation == Qt.Vertical - property bool _inverted: _isVertical ? - !scrollDecorator.inverted : scrollDecorator.inverted - property alias _value: range.value - - implicitWidth: _isVertical ? 16 : 200 - implicitHeight: _isVertical ? 200 : 16 - - visible: flickableItem && handle.width < contents.width - - anchors { - right: flickableItem.right - left: (orientation == Qt.Vertical) ? undefined : flickableItem.left - top: (orientation == Qt.Vertical) ? flickableItem.top : undefined - bottom: flickableItem.bottom - } - - Item { - width: _isVertical ? scrollDecorator.height : scrollDecorator.width - height: _isVertical ? scrollDecorator.width : scrollDecorator.height - rotation: _isVertical ? -90 : 0 - - anchors.centerIn: parent - - PlasmaCore.FrameSvgItem { - id: contents - imagePath: "widgets/scrollbar" - prefix: "background-horizontal" - - anchors.fill: parent - opacity: flickableItem && (flickableItem.flicking || flickableItem.moving) ? 1 : 0 - Behavior on opacity { - NumberAnimation { - duration: 250 - easing.type: Easing.OutQuad - } - } - - RangeModel { - id: range - - minimumValue: 0 - maximumValue: { - var diff; - if (_isVertical) - diff = flickableItem.contentHeight - flickableItem.height; - else - diff = flickableItem.contentWidth - flickableItem.width; - - return Math.max(0, diff); - } - stepSize: 0.0 - inverted: _inverted - positionAtMinimum: 0 + handle.width / 2 - positionAtMaximum: contents.width - handle.width / 2 - value: _isVertical ? flickableItem.contentY : flickableItem.contentX - } - - PlasmaCore.FrameSvgItem { - id: handle - - x: range.position - transform: Translate { x: - handle.width / 2 } - anchors.verticalCenter: parent.verticalCenter - width: { - var ratio; - if (_isVertical) - ratio = flickableItem.visibleArea.heightRatio; - else - ratio = flickableItem.visibleArea.widthRatio; - - return ratio * parent.width; - } - height: parent.height - margins.top // TODO: check mergin - imagePath: "widgets/scrollbar" - prefix: "slider" - } - } - } +ScrollBar { + interactive: false } \ No newline at end of file From 526b19f6ec4701711d156043ed06e15fd958d670 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 15:11:22 +0100 Subject: [PATCH 41/87] move keyboard interaction in the delegate --- .../plasmacomponents/qml/ScrollBar.qml | 40 ---------------- .../qml/ScrollBarDelegate.qml | 46 +++++++++++++++++-- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index 366432b07..8e894e9a9 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -56,46 +56,6 @@ Item { bottom: flickableItem.bottom } - Keys.onUpPressed: { - if (!interactive || !enabled || !_isVertical) - return; - - if (inverted) - internalLoader.incrementValue(stepSize); - else - internalLoader.incrementValue(-stepSize); - } - - Keys.onDownPressed: { - if (!interactive || !enabled || !_isVertical) - return; - - if (inverted) - internalLoader.incrementValue(-stepSize); - else - internalLoader.incrementValue(stepSize); - } - - Keys.onLeftPressed: { - if (!interactive || !enabled || _isVertical) - return; - - if (inverted) - internalLoader.incrementValue(stepSize); - else - internalLoader.incrementValue(-stepSize); - } - - Keys.onRightPressed: { - if (!interactive || !enabled || _isVertical) - return; - - if (inverted) - internalLoader.incrementValue(-stepSize); - else - internalLoader.incrementValue(stepSize); - } - Loader { id: internalLoader anchors.fill: parent diff --git a/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml index 0934e63dc..9323841e4 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml @@ -28,6 +28,46 @@ PlasmaCore.FrameSvgItem { imagePath:"widgets/scrollbar" prefix: _isVertical ? "background-vertical" : "background-horizontal" + Keys.onUpPressed: { + if (!enabled || !_isVertical) + return; + + if (inverted) + internalLoader.incrementValue(stepSize); + else + internalLoader.incrementValue(-stepSize); + } + + Keys.onDownPressed: { + if (!enabled || !_isVertical) + return; + + if (inverted) + internalLoader.incrementValue(-stepSize); + else + internalLoader.incrementValue(stepSize); + } + + Keys.onLeftPressed: { + if (!enabled || _isVertical) + return; + + if (inverted) + internalLoader.incrementValue(stepSize); + else + internalLoader.incrementValue(-stepSize); + } + + Keys.onRightPressed: { + if (!enabled || _isVertical) + return; + + if (inverted) + internalLoader.incrementValue(-stepSize); + else + internalLoader.incrementValue(stepSize); + } + property Item handle: handle property Item contents: contents @@ -104,7 +144,7 @@ PlasmaCore.FrameSvgItem { running: parent.pressed repeat: true onTriggered: { - scrollbar.forceActiveFocus() + background.forceActiveFocus() if (inverted) { internalLoader.incrementValue(stepSize); } else { @@ -151,7 +191,7 @@ PlasmaCore.FrameSvgItem { running: parent.pressed; repeat: true onTriggered: { - scrollbar.forceActiveFocus(); + background.forceActiveFocus(); if (inverted) internalLoader.incrementValue(-stepSize); else @@ -204,7 +244,7 @@ PlasmaCore.FrameSvgItem { } } - scrollbar.forceActiveFocus(); + background.forceActiveFocus(); } } } From 7ae1ce52d13c72373aa50dd0b29a9a668e2d197e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 15:18:40 +0100 Subject: [PATCH 42/87] by default Scrollbar is not interactive on touch --- .../platformcomponents/touch/ScrollBar.qml | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml new file mode 100644 index 000000000..e30b22238 --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml @@ -0,0 +1,134 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright (C) 2011 Marco Martin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore + +// TODO: add support mouse wheel and key events +Item { + id: scrollbar + + // Common API + property Flickable flickableItem: null + property int orientation: Qt.Vertical + property bool interactive: false + + // Plasma API + property bool inverted: false + property bool animated: true + property alias stepSize: range.stepSize + //property alias pressed: mouseArea.pressed + property real scrollButtonInterval: 50 + + // Convinience API + property bool _isVertical: orientation == Qt.Vertical + property bool _showButtons: stepSize != 0 + + implicitWidth: _isVertical ? (interactive ? 22 : 12) : 200 + implicitHeight: _isVertical ? 200 : (interactive ? 22 : 12) + // TODO: needs to define if there will be specific graphics for + // disabled scroll bars + opacity: enabled ? 1.0 : 0.5 + + visible: flickableItem && internalLoader.handleEnabled + + anchors { + right: flickableItem.right + left: (orientation == Qt.Vertical) ? undefined : flickableItem.left + top: (orientation == Qt.Vertical) ? flickableItem.top : undefined + bottom: flickableItem.bottom + } + + Loader { + id: internalLoader + anchors.fill: parent + //property bool handleEnabled: _isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width + property bool handleEnabled: _isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width + + function incrementValue(increment) + { + if (!flickableItem) + return; + + if (_isVertical) { + flickableItem.contentY = Math.max(0, Math.min(flickableItem.contentHeight, + flickableItem.contentY + increment)) + } else { + flickableItem.contentX = Math.max(0, Math.min(flickableItem.contentWidth, + flickableItem.contentX + increment)) + } + } + + RangeModel { + id: range + + minimumValue: 0 + maximumValue: { + var diff; + if (_isVertical) { + diff = flickableItem.contentHeight - flickableItem.height + } else { + diff = flickableItem.contentWidth - flickableItem.width + } + + return Math.max(0, diff) + } + + stepSize: 10 + inverted: scrollbar.inverted + positionAtMinimum: 0 + positionAtMaximum: { + if (_isVertical) { + internalLoader.item.contents.height - internalLoader.item.handle.height + } else { + internalLoader.item.contents.width - internalLoader.item.handle.width + } + } + value: _isVertical ? flickableItem.contentY : flickableItem.contentX + onValueChanged: { + if (flickableItem.moving) { + return + } + + if (_isVertical) { + flickableItem.contentY = value + } else { + flickableItem.contentX = value + } + } + + position: _isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x + + onPositionChanged: { + if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) { + return + } + + if (_isVertical) { + internalLoader.item.handle.y = position + } else { + internalLoader.item.handle.x = position + } + } + } + + source: interactive ? "ScrollBarDelegate.qml" : "ScrollDecoratorDelegate.qml" + } +} From 2465d24bb16f6809948878407e12eed45eeb75f5 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 15:28:21 +0100 Subject: [PATCH 43/87] ScrollDecorator only on Touchscreens just as a compatibility layer for porting --- .../platformcomponents/touch/ScrollBar.qml | 10 ++++++++-- .../touch}/ScrollDecorator.qml | 6 +++++- declarativeimports/plasmacomponents/qml/ScrollBar.qml | 8 +++++++- declarativeimports/plasmacomponents/qml/qmldir | 1 - declarativeimports/test/gallery/Scrollers.qml | 4 ++-- 5 files changed, 22 insertions(+), 7 deletions(-) rename declarativeimports/plasmacomponents/{qml => platformcomponents/touch}/ScrollDecorator.qml (87%) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml index e30b22238..01831d088 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml @@ -21,14 +21,20 @@ import QtQuick 1.1 import org.kde.plasma.core 0.1 as PlasmaCore -// TODO: add support mouse wheel and key events + +/** + * A generic ScrollBar/ScrollDecorator component: + * Qlways prefer this to ScrollDecorator that is not available on desktop. + * By default, this component will look and behave like a scroll decorator on touchscreens + */ +// TODO: add support mouse wheel events Item { id: scrollbar // Common API property Flickable flickableItem: null property int orientation: Qt.Vertical - property bool interactive: false + property bool interactive: true // Plasma API property bool inverted: false diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollDecorator.qml similarity index 87% rename from declarativeimports/plasmacomponents/qml/ScrollDecorator.qml rename to declarativeimports/plasmacomponents/platformcomponents/touch/ScrollDecorator.qml index b0fe83bae..b3b11eb7a 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollDecorator.qml @@ -19,6 +19,10 @@ import QtQuick 1.0 +/** + * Just provided for compatibility + * Use ScrollBar instead. will behave like a ScrollDecorator on touchscreens + */ ScrollBar { interactive: false -} \ No newline at end of file +} diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index 8e894e9a9..01831d088 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -21,7 +21,13 @@ import QtQuick 1.1 import org.kde.plasma.core 0.1 as PlasmaCore -// TODO: add support mouse wheel and key events + +/** + * A generic ScrollBar/ScrollDecorator component: + * Qlways prefer this to ScrollDecorator that is not available on desktop. + * By default, this component will look and behave like a scroll decorator on touchscreens + */ +// TODO: add support mouse wheel events Item { id: scrollbar diff --git a/declarativeimports/plasmacomponents/qml/qmldir b/declarativeimports/plasmacomponents/qml/qmldir index ae95b5634..33220fa2e 100644 --- a/declarativeimports/plasmacomponents/qml/qmldir +++ b/declarativeimports/plasmacomponents/qml/qmldir @@ -15,7 +15,6 @@ ProgressBar 0.1 ProgressBar.qml PushButton 0.1 PushButton.qml RadioButton 0.1 RadioButton.qml ScrollBar 0.1 ScrollBar.qml -ScrollDecorator 0.1 ScrollDecorator.qml Slider 0.1 Slider.qml Switch 0.1 Switch.qml TextArea 0.1 TextArea.qml diff --git a/declarativeimports/test/gallery/Scrollers.qml b/declarativeimports/test/gallery/Scrollers.qml index dea2d8c81..da1c93918 100644 --- a/declarativeimports/test/gallery/Scrollers.qml +++ b/declarativeimports/test/gallery/Scrollers.qml @@ -102,7 +102,7 @@ Column { } // Scroll Decorators - PlasmaComponents.ScrollDecorator { + PlasmaComponents.ScrollBar { orientation: Qt.Vertical flickableItem: scrollArea inverted: true @@ -118,7 +118,7 @@ Column { text: "inverted" } } - PlasmaComponents.ScrollDecorator { + PlasmaComponents.ScrollBar { orientation: Qt.Horizontal flickableItem: scrollArea anchors { From 4dd35da40008207816613cb3af87d8ec3263d3f1 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 15:31:03 +0100 Subject: [PATCH 44/87] stop the opacity timer when needed --- .../plasmacomponents/qml/ScrollDecoratorDelegate.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml index 7e6f03ff2..635f31de9 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml @@ -61,6 +61,7 @@ PlasmaCore.FrameSvgItem { target: flickableItem onMovingChanged: { if (flickableItem.moving) { + opacityTimer.running = false background.opacity = 1 } else { opacityTimer.restart() From 9cc6656fb68ebf52aa88c70dc8e6b724bda6df1f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 16:10:36 +0100 Subject: [PATCH 45/87] redo way simpler ToolBarLayout --- .../plasmacomponents/qml/ToolBarLayout.qml | 325 +++--------------- 1 file changed, 40 insertions(+), 285 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml b/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml index 85e13d926..be51e2bff 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml @@ -1,42 +1,22 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Components project. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ +/* +* Copyright (C) 2011 by Marco Martin +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License as +* published by the Free Software Foundation; either version 2, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + // ToolBarLayout is a container for items on a toolbar that automatically // implements an appropriate layout for its children. @@ -44,268 +24,43 @@ import QtQuick 1.1 import "." 0.1 -Item { - id: root - implicitWidth: parent.width - implicitHeight: parent.height +Row { + id: root visible: false - Connections { - target: privateStyle - onLayoutParametersChanged: internal.layoutChildren() - } - Connections { - target: screen - onCurrentOrientationChanged: internal.layoutChildren() + Item { + id: spacer + width: 10 + height: 10 } QtObject { id: internal - objectName: "internal" - - property bool portrait: screen.width < screen.height - - // These are the dynamic layout parameters used by the toolbar layout. - property real defaultHeightToolBar: portrait ? - privateStyle.toolBarHeightPortrait : privateStyle.toolBarHeightLandscape - property real defaultHeightToolButton: privateStyle.toolBarHeightLandscape - property real outerMarginHorizontal: portrait ? - 0 : (2 * platformStyle.paddingLarge) - property real outerMarginButtonRowLong: portrait ? - platformStyle.paddingLarge : (3 * platformStyle.paddingLarge) - property real innerSpacingTextButtonSingle: portrait ? - platformStyle.paddingMedium + (3 * platformStyle.paddingLarge) : (3 * platformStyle.paddingLarge) - property real innerSpacingTextButtonDouble: portrait ? - platformStyle.paddingSmall : (3 * platformStyle.paddingLarge) - property real innerSpacingButtonRowTwoChildren: portrait ? - platformStyle.paddingMedium : (3 * platformStyle.paddingLarge) - property real innerSpacingButtonRowLong: portrait ? - platformStyle.paddingMedium : platformStyle.paddingLarge - property real centerSpacingTextButtonDouble: platformStyle.paddingLarge - - function isIconButton(item) { - return item.hasOwnProperty("iconSource") - && item.hasOwnProperty("text") - && item.text == "" - } - - function isTextToolButton(item) { - // ToolButton has both iconSource and flat property, - // Button only has iconSource - return (item.hasOwnProperty("iconSource") - && item.iconSource == "" - && item.hasOwnProperty("flat")) - } - - function isButtonRow(item) { - return item.hasOwnProperty("checkedButton") - } - - function buttonWidth(child) { - if ((isTextToolButton(child)) || !(child.hasOwnProperty("implicitWidth"))) { - // ImplicitWidth for the ToolButton returns wrong value right after - // orientation change, and also we want to override its own - // layout width calculation, so use the actual width - return child.width - } - return child.implicitWidth - } - - function centerOffset(outerLength, innerLength) { - // calculate the offset of the leading edge of a centered child item - return Math.floor((outerLength - innerLength) / 2.0) - } - - function widthTextButtonSingle(leftMargin, innerSpacing) { - // calculate the remaining width for a centered item - var outerContents = leftMargin + innerSpacing - return root.width - (outerContents * 2) - } - - function widthTextButtonDouble(leftMargin, innerSpacing, centerSpacing) { - // calculate the space available when there are two items with a center - // margin, and share it between the two - var outerContents = leftMargin + innerSpacing - return Math.round((root.width - (outerContents * 2) - centerSpacing) / 2.0) - } - - function widthButtonRowLong(leftButton, rightButton, itemMargin, innerSpacing, outerMargin) { - // calculate the width of a long button row, which is used in the case that there are more - // than three icons. If either left or right button is present, allocate the itemMargin to - // ensure that there is sufficient space; otherwise we can use the special - // outerMargin value - var leftContents = leftButton ? itemMargin + innerSpacing : outerMargin - var rightContents = rightButton ? itemMargin + innerSpacing : outerMargin - return root.width - leftContents - rightContents - } - - function layoutChildren() { - var numChildren = children.length - if (parent == null || root.width == 0 || numChildren == 0) - return - - for (var i = 0; i < numChildren; ++i) { - // make sure all the children have correct parent, height, and y - children[i].parent = root - if (isButtonRow(children[i])) { - var buttonRow = children[i] - // ButtonRow frame height is always tool bar's height in - // landscape, regardless of the current orientation, so we need - // to override the heights of the buttons within (because it's a - // Row, so its height is based on its children) - for (var j = 0; j < buttonRow.children.length; ++j) { - buttonRow.children[j].implicitHeight = defaultHeightToolButton - } - } - // child's vertical center always goes to middle of the toolbar - var childHeight = children[i].hasOwnProperty("implicitHeight") ? - children[i].implicitHeight : children[i].height - children[i].y = root.y + centerOffset(root.implicitHeight, childHeight) - } - - // detect whether we have left and or right items. we need to lay out - // the remaining children (that are not left or right items) whether they - // are tool buttons, text buttons or a button row - var leftItem = isIconButton(children[0]) ? - children[0] : undefined - var rightItem = isIconButton(children[numChildren-1]) ? - children[numChildren-1] : undefined - var childrenRemaining = numChildren - (leftItem != undefined ? 1 : 0) - (rightItem != undefined ? 1 : 0) - var firstRemainingIndex = leftItem != undefined ? 1 : 0 - var lastRemainingIndex = rightItem != undefined ? (numChildren - 2) : (numChildren - 1) - - // precalculate the margins for the left and right items, we will work - // out child sizes assuming they are present - var leftMargin = outerMarginHorizontal + defaultHeightToolBar - var rightMargin = root.width - leftMargin - - // In the case of a lone remaining chlld, or in the case of 2 text - // buttons, we need to override the width - var overrideChildWidth = 0 - for (var p = firstRemainingIndex; p <= lastRemainingIndex; p++) { - var child = children[p] - overrideChildWidth = buttonWidth(child) - - // If necessary, we calculate and override the width first before we - // can calculate the x positions - if ((isTextToolButton(child) && childrenRemaining == 1) - || (isButtonRow(child) && child.children.length == 1)) { - // we treat a button row with a single item like a single tool button, - // but in landscape, calculate size as if there were two buttons - overrideChildWidth = portrait ? - widthTextButtonSingle(leftMargin, innerSpacingTextButtonSingle) : - widthTextButtonDouble(leftMargin, innerSpacingTextButtonDouble, innerSpacingTextButtonDouble) - - } else if (isTextToolButton(child) && childrenRemaining == 2) { - // special case of margins for two text buttons - overrideChildWidth = widthTextButtonDouble( - leftMargin, innerSpacingTextButtonDouble, centerSpacingTextButtonDouble) - - } else if (isButtonRow(child) && ((child.children.length == 2) - || (child.children.length > 2 && leftItem != undefined && rightItem != undefined))) { - // there are special margins if the button row has two children, - // or if it has more than two children and there is a left and - // a right item - overrideChildWidth = widthTextButtonSingle( - leftMargin, innerSpacingButtonRowTwoChildren) - - } else if (isButtonRow(child) && child.children.length > 2) { - // the long button row has special margins, which are used on - // either side if the side icon button is missing on that side. If the item is present, - // the leftMargin can be used on either side to leave space for either icon button - overrideChildWidth = widthButtonRowLong( - leftItem != undefined, - rightItem != undefined, - leftMargin, - innerSpacingButtonRowLong, - outerMarginButtonRowLong) - } - - child.width = overrideChildWidth - } - - if (numChildren == 1) { - var loneChild = children[0] - var loneChildWidth = buttonWidth(loneChild) - if (isButtonRow(loneChild)) { - loneChildWidth = overrideChildWidth - } - if (isIconButton(loneChild)) - loneChild.x = outerMarginHorizontal - else - loneChild.x = centerOffset(root.width, loneChildWidth) + property bool layouting: false + function layoutChildren() + { + var numChildren = root.children.length + if (layouting || parent == null || + root.width == 0 || numChildren < 2) { return } - // we can easily calculate the positions of the left and right items, - // but if they are missing then correct the margins - if (leftItem != undefined){ - leftItem.x = outerMarginHorizontal - } else { - leftMargin = 0 - } - if (rightItem != undefined){ - rightItem.x = root.width - defaultHeightToolBar - outerMarginHorizontal - } else { - rightMargin = root.width - } + layouting = true + spacer.parent = null - if (!childrenRemaining) - return; + spacer.width = root.parent.width - root.childrenRect.width - if (childrenRemaining == 1) { - var loneChild = children[firstRemainingIndex] - var loneChildWidth = buttonWidth(loneChild) - if (isButtonRow(loneChild)) { - // ButtonRow should have the override width (but it won't have - // been updated yet) - loneChildWidth = overrideChildWidth - } - // lone child is always centered, unless it's a long button row on - // one side only - if (isButtonRow(loneChild) && loneChild.children.length >= 3 - && ((leftItem == undefined) != (rightItem == undefined))) { - loneChild.x = (leftItem != undefined) ? - (leftMargin + innerSpacingButtonRowLong) : outerMarginButtonRowLong - } else { - loneChild.x = centerOffset(root.width, loneChildWidth) - } - } else if (childrenRemaining == 2 && isTextToolButton(children[firstRemainingIndex])) { - // text buttons are distributed around the center with a center spacing - var midPoint = Math.floor(root.width / 2.0) - var halfSpacing = Math.round(platformStyle.paddingLarge / 2.0) - children[firstRemainingIndex].x = midPoint - halfSpacing - buttonWidth(children[firstRemainingIndex]) - children[firstRemainingIndex + 1].x = midPoint + halfSpacing - } else { - // icon buttons are deployed evenly in the remaining space, - // but we need to ensure that the spacings are integer values, - // and share the rounding error to ensure that they are centered - var remainingSpace = rightMargin - leftMargin - var spacingNotRounded = remainingSpace - for (var p = 0; p < childrenRemaining; p++) { - var nextChild = children[leftItem != undefined ? p + 1 : p] - spacingNotRounded -= buttonWidth(nextChild) - } - spacingNotRounded /= (childrenRemaining + 1) - var spacing = Math.floor(spacingNotRounded) - var totalRoundingError = (spacingNotRounded - spacing) * (childrenRemaining + 1) - var curPos = leftMargin + Math.floor(totalRoundingError / 2.0) - - for (var p = 0; p < childrenRemaining; p++) { - var nextChild = children[leftItem != undefined ? p + 1 : p] - curPos += spacing - nextChild.x = curPos - curPos += buttonWidth(nextChild) - } - } + var last = root.children[numChildren-2] + last.parent = null + spacer.parent = root + last.parent = root + layouting = false } } Component.onCompleted: internal.layoutChildren() - onParentChanged: internal.layoutChildren() onChildrenChanged: internal.layoutChildren() - onImplicitWidthChanged: internal.layoutChildren() - onImplicitHeightChanged: internal.layoutChildren() + onWidthChanged: internal.layoutChildren() } From 0e64e6cda90660466e5e6cdb74652154f812f6cb Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 16:11:25 +0100 Subject: [PATCH 46/87] non interactive --- .../plasmacomponents/platformcomponents/touch/ScrollBar.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml index 01831d088..2650c15ac 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml @@ -34,7 +34,7 @@ Item { // Common API property Flickable flickableItem: null property int orientation: Qt.Vertical - property bool interactive: true + property bool interactive: false // Plasma API property bool inverted: false From 39f1e26a582ea20362d4dbece2586fd2938be9f9 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 16:20:52 +0100 Subject: [PATCH 47/87] remove all references to screen --- .../plasmacomponents/qml/Page.qml | 45 +------------------ 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/Page.qml b/declarativeimports/plasmacomponents/qml/Page.qml index e3abcf743..03bf145bc 100644 --- a/declarativeimports/plasmacomponents/qml/Page.qml +++ b/declarativeimports/plasmacomponents/qml/Page.qml @@ -64,18 +64,8 @@ Item { width: visible && parent ? parent.width : internal.previousWidth height: visible && parent ? parent.height : internal.previousHeight - onWidthChanged: internal.previousWidth = visible ? width : internal.previousWidth - onHeightChanged: internal.previousHeight = visible ? height : internal.previousHeight - - onStatusChanged: { - if (status == PageStatus.Activating) - internal.orientationLockCheck(); - } - - onOrientationLockChanged: { - if (status == PageStatus.Activating || status == PageStatus.Active) - internal.orientationLockCheck(); - } + onWidthChanged: internal.previousWidth = (visible ? width : internal.previousWidth) + onHeightChanged: internal.previousHeight = (visible ? height : internal.previousHeight) // This is needed to make a parentless Page component visible in the Designer of QtCreator. // It's done here instead of binding the visible property because binding it to a script @@ -88,36 +78,5 @@ Item { id: internal property int previousWidth: 0 property int previousHeight: 0 - - function isScreenInPortrait() { - return screen.currentOrientation == Screen.Portrait || screen.currentOrientation == Screen.PortraitInverted; - } - - function isScreenInLandscape() { - return screen.currentOrientation == Screen.Landscape || screen.currentOrientation == Screen.LandscapeInverted; - } - - function orientationLockCheck() { - switch (orientationLock) { - case PageOrientation.Automatic: - screen.allowedOrientations = Screen.Default - break - case PageOrientation.LockPortrait: - screen.allowedOrientations = Screen.Portrait - break - case PageOrientation.LockLandscape: - screen.allowedOrientations = Screen.Landscape - break - case PageOrientation.LockPrevious: - screen.allowedOrientations = screen.currentOrientation - break - case PageOrientation.Manual: - default: - // Do nothing - // In manual mode it is expected that orientation is set - // explicitly to "screen.allowedOrientations" by the user. - break - } - } } } From 7cb7c0e276015b51528f7641685fe7b26985653f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 16:53:58 +0100 Subject: [PATCH 48/87] on desktop, sectionscroller looks like a scrollbar --- .../platformcomponents/touch/ScrollBar.qml | 2 +- .../touch/SectionScroller.qml | 238 ++++++++++++++++++ .../plasmacomponents/qml/ScrollBar.qml | 2 +- .../qml/ScrollBarDelegate.qml | 2 +- .../plasmacomponents/qml/SectionScroller.qml | 95 +------ 5 files changed, 252 insertions(+), 87 deletions(-) create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml index 2650c15ac..964013890 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml @@ -40,7 +40,7 @@ Item { property bool inverted: false property bool animated: true property alias stepSize: range.stepSize - //property alias pressed: mouseArea.pressed + property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false property real scrollButtonInterval: 50 // Convinience API diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml new file mode 100644 index 000000000..d93042c3b --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 +import "SectionScroller.js" as Sections +import org.kde.plasma.core 0.1 as PlasmaCore + +/** + * It's similar to a ScrollBar or a ScrollDecorator. + * It's interactive and works on ListViews that have section.property set, + * so its contents are categorized. + * An indicator will say to what category the user scrolled to. + * + * Useful for things like address books or things sorted by date. + * Don't use with models too big (thousands of items) because implies + * loading all the items to memory, as well loses precision. + */ +Item { + id: root + + /** + * The listview this scroll indicator will work on + */ + property ListView listView + + onListViewChanged: { + if (listView && listView.model) + internal.initDirtyObserver(); + } + + Connections { + target: listView + onModelChanged: { + if (listView && listView.model) { + internal.initDirtyObserver() + } + } + onMovementStarted: root.opacity = 1 + onMovementEnded: { + if (!dragArea.pressed) { + fadeTimer.restart() + } + } + } + + width: 48 + opacity: 0 + Behavior on opacity { + NumberAnimation { + duration: 250 + } + } + + anchors { + right: listView.right + top: listView.top + bottom: listView.bottom + } + + Timer { + id: fadeTimer + interval: 4000 + repeat: false + running: false + onTriggered: { + root.opacity = 0 + } + } + + RangeModel { + id: range + + minimumValue: 0 + maximumValue: Math.max(0, listView.contentHeight - listView.height) + stepSize: 0 + //inverted: true + positionAtMinimum: handle.height / 2 + positionAtMaximum: root.height - handle.height - handle.height / 2 + value: listView.contentY + onValueChanged: { + if (listView.moving) { + return + } else { + listView.contentY = value + } + } + //position: handle.y + onPositionChanged: { + if (!dragArea.pressed) { + handle.y = position + } + } + } + + Rectangle { + anchors.fill: parent + color: Qt.rgba(0,0,0,0.3) + } + + Rectangle { + id: handle + width: 6 + height: 6 + color: theme.textColor + opacity: 0.7 + anchors.horizontalCenter: parent.horizontalCenter + border { + width: 1 + color: theme.backgroundColor + } + onYChanged: { + if (dragArea.pressed) { + range.position = y + } + sectionLabel.text = Sections.closestSection(y/listView.height) + } + Behavior on y { + NumberAnimation { + duration: 150 + } + } + } + PlasmaCore.FrameSvgItem { + imagePath: "widgets/tooltip" + width: childrenRect.width + margins.left + margins.right + height: childrenRect.height + margins.top + margins.bottom + Label { + id: sectionLabel + font.pointSize: theme.defaultFont.pointSize*3 + x: parent.margins.left + y: parent.margins.top + } + y: Math.min(root.height-height, Math.max(0, handle.y - height/2)) + anchors { + //verticalCenter: handle.verticalCenter + right: parent.left + } + opacity: dragArea.pressed?1:0 + Behavior on opacity { + NumberAnimation { + duration: 250 + } + } + } + /*Repeater { + id: sectionsRepeater + delegate: Label { + anchors.horizontalCenter: parent.horizontalCenter + text: Sections._sections[modelData] + y: Sections._sectionData[modelData].index*(listView.height/listView.model.count) + } + }*/ + MouseArea { + id: dragArea + anchors.fill: parent + enabled: scrollbar.enabled + drag { + target: handle + axis: Drag.YAxis + minimumY: range.positionAtMinimum + maximumY: range.positionAtMaximum + } + onPressed: { + mouse.accepted = true + handle.y = mouse.y + } + onReleased: fadeTimer.restart() + + } + + QtObject { + id: internal + + function initDirtyObserver() { + Sections.initSectionData(listView); + function dirtyObserver() { + if (!internal.modelDirty) { + internal.modelDirty = true; + dirtyTimer.running = true; + } + } + + if (listView.model.countChanged) + listView.model.countChanged.connect(dirtyObserver); + + if (listView.model.itemsChanged) + listView.model.itemsChanged.connect(dirtyObserver); + + if (listView.model.itemsInserted) + listView.model.itemsInserted.connect(dirtyObserver); + + if (listView.model.itemsMoved) + listView.model.itemsMoved.connect(dirtyObserver); + + if (listView.model.itemsRemoved) + listView.model.itemsRemoved.connect(dirtyObserver); + + sectionsRepeater.model = Sections._sections.length + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index 01831d088..edd82aa15 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -40,7 +40,7 @@ Item { property bool inverted: false property bool animated: true property alias stepSize: range.stepSize - //property alias pressed: mouseArea.pressed + property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false property real scrollButtonInterval: 50 // Convinience API diff --git a/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml index 9323841e4..69eaaf329 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml @@ -115,7 +115,7 @@ PlasmaCore.FrameSvgItem { anchors { left: _isVertical ? undefined : parent.left verticalCenter: _isVertical ? undefined : parent.verticalCenter - top: _isVertical ? 0 : undefined + top: _isVertical ? parent.top : undefined horizontalCenter: _isVertical ? parent.horizontalCenter : undefined } height: 18 diff --git a/declarativeimports/plasmacomponents/qml/SectionScroller.qml b/declarativeimports/plasmacomponents/qml/SectionScroller.qml index d93042c3b..6ae7067a1 100644 --- a/declarativeimports/plasmacomponents/qml/SectionScroller.qml +++ b/declarativeimports/plasmacomponents/qml/SectionScroller.qml @@ -72,16 +72,9 @@ Item { internal.initDirtyObserver() } } - onMovementStarted: root.opacity = 1 - onMovementEnded: { - if (!dragArea.pressed) { - fadeTimer.restart() - } - } } - width: 48 - opacity: 0 + width: 22 Behavior on opacity { NumberAnimation { duration: 250 @@ -94,15 +87,6 @@ Item { bottom: listView.bottom } - Timer { - id: fadeTimer - interval: 4000 - repeat: false - running: false - onTriggered: { - root.opacity = 0 - } - } RangeModel { id: range @@ -111,51 +95,18 @@ Item { maximumValue: Math.max(0, listView.contentHeight - listView.height) stepSize: 0 //inverted: true - positionAtMinimum: handle.height / 2 - positionAtMaximum: root.height - handle.height - handle.height / 2 + positionAtMinimum: root.width*2 + positionAtMaximum: root.height - root.width*2 value: listView.contentY - onValueChanged: { - if (listView.moving) { - return - } else { - listView.contentY = value - } - } - //position: handle.y - onPositionChanged: { - if (!dragArea.pressed) { - handle.y = position - } - } + onPositionChanged: sectionLabel.text = Sections.closestSection(position/listView.height) + } - Rectangle { + ScrollBar { + id: scrollBar + flickableItem: listView anchors.fill: parent - color: Qt.rgba(0,0,0,0.3) - } - - Rectangle { - id: handle - width: 6 - height: 6 - color: theme.textColor - opacity: 0.7 - anchors.horizontalCenter: parent.horizontalCenter - border { - width: 1 - color: theme.backgroundColor - } - onYChanged: { - if (dragArea.pressed) { - range.position = y - } - sectionLabel.text = Sections.closestSection(y/listView.height) - } - Behavior on y { - NumberAnimation { - duration: 150 - } - } + interactive: true } PlasmaCore.FrameSvgItem { imagePath: "widgets/tooltip" @@ -167,43 +118,19 @@ Item { x: parent.margins.left y: parent.margins.top } - y: Math.min(root.height-height, Math.max(0, handle.y - height/2)) + y: Math.min(root.height-height-scrollBar.width, Math.max(scrollBar.width, range.position - height/2)) anchors { //verticalCenter: handle.verticalCenter right: parent.left } - opacity: dragArea.pressed?1:0 + opacity: sectionLabel.text && scrollBar.pressed?1:0 Behavior on opacity { NumberAnimation { duration: 250 } } } - /*Repeater { - id: sectionsRepeater - delegate: Label { - anchors.horizontalCenter: parent.horizontalCenter - text: Sections._sections[modelData] - y: Sections._sectionData[modelData].index*(listView.height/listView.model.count) - } - }*/ - MouseArea { - id: dragArea - anchors.fill: parent - enabled: scrollbar.enabled - drag { - target: handle - axis: Drag.YAxis - minimumY: range.positionAtMinimum - maximumY: range.positionAtMaximum - } - onPressed: { - mouse.accepted = true - handle.y = mouse.y - } - onReleased: fadeTimer.restart() - } QtObject { id: internal From a4cc8972bb8093676b0a02078999731e5ce63776 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 17:05:21 +0100 Subject: [PATCH 49/87] internal api is internal --- .../platformcomponents/touch/ScrollBar.qml | 27 ++++----- .../plasmacomponents/qml/ScrollBar.qml | 27 ++++----- .../qml/ScrollBarDelegate.qml | 60 +++++++++---------- .../qml/ScrollDecoratorDelegate.qml | 8 +-- .../plasmacomponents/qml/SelectionDialog.qml | 2 +- 5 files changed, 59 insertions(+), 65 deletions(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml index 964013890..fa9e879fa 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml @@ -43,12 +43,8 @@ Item { property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false property real scrollButtonInterval: 50 - // Convinience API - property bool _isVertical: orientation == Qt.Vertical - property bool _showButtons: stepSize != 0 - - implicitWidth: _isVertical ? (interactive ? 22 : 12) : 200 - implicitHeight: _isVertical ? 200 : (interactive ? 22 : 12) + implicitWidth: internalLoader.isVertical ? (interactive ? 22 : 12) : 200 + implicitHeight: internalLoader.isVertical ? 200 : (interactive ? 22 : 12) // TODO: needs to define if there will be specific graphics for // disabled scroll bars opacity: enabled ? 1.0 : 0.5 @@ -65,15 +61,16 @@ Item { Loader { id: internalLoader anchors.fill: parent - //property bool handleEnabled: _isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width - property bool handleEnabled: _isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width + //property bool handleEnabled: internalLoader.isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width + property bool handleEnabled: internalLoader.isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width + property bool isVertical: orientation == Qt.Vertical function incrementValue(increment) { if (!flickableItem) return; - if (_isVertical) { + if (internalLoader.isVertical) { flickableItem.contentY = Math.max(0, Math.min(flickableItem.contentHeight, flickableItem.contentY + increment)) } else { @@ -88,7 +85,7 @@ Item { minimumValue: 0 maximumValue: { var diff; - if (_isVertical) { + if (internalLoader.isVertical) { diff = flickableItem.contentHeight - flickableItem.height } else { diff = flickableItem.contentWidth - flickableItem.width @@ -101,33 +98,33 @@ Item { inverted: scrollbar.inverted positionAtMinimum: 0 positionAtMaximum: { - if (_isVertical) { + if (internalLoader.isVertical) { internalLoader.item.contents.height - internalLoader.item.handle.height } else { internalLoader.item.contents.width - internalLoader.item.handle.width } } - value: _isVertical ? flickableItem.contentY : flickableItem.contentX + value: internalLoader.isVertical ? flickableItem.contentY : flickableItem.contentX onValueChanged: { if (flickableItem.moving) { return } - if (_isVertical) { + if (internalLoader.isVertical) { flickableItem.contentY = value } else { flickableItem.contentX = value } } - position: _isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x + position: internalLoader.isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x onPositionChanged: { if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) { return } - if (_isVertical) { + if (internalLoader.isVertical) { internalLoader.item.handle.y = position } else { internalLoader.item.handle.x = position diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index edd82aa15..bb756b920 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -43,12 +43,8 @@ Item { property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false property real scrollButtonInterval: 50 - // Convinience API - property bool _isVertical: orientation == Qt.Vertical - property bool _showButtons: stepSize != 0 - - implicitWidth: _isVertical ? (interactive ? 22 : 12) : 200 - implicitHeight: _isVertical ? 200 : (interactive ? 22 : 12) + implicitWidth: internalLoader.isVertical ? (interactive ? 22 : 12) : 200 + implicitHeight: internalLoader.isVertical ? 200 : (interactive ? 22 : 12) // TODO: needs to define if there will be specific graphics for // disabled scroll bars opacity: enabled ? 1.0 : 0.5 @@ -65,15 +61,16 @@ Item { Loader { id: internalLoader anchors.fill: parent - //property bool handleEnabled: _isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width - property bool handleEnabled: _isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width + //property bool handleEnabled: internalLoader.isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width + property bool handleEnabled: internalLoader.isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width + property bool isVertical: orientation == Qt.Vertical function incrementValue(increment) { if (!flickableItem) return; - if (_isVertical) { + if (internalLoader.isVertical) { flickableItem.contentY = Math.max(0, Math.min(flickableItem.contentHeight, flickableItem.contentY + increment)) } else { @@ -88,7 +85,7 @@ Item { minimumValue: 0 maximumValue: { var diff; - if (_isVertical) { + if (internalLoader.isVertical) { diff = flickableItem.contentHeight - flickableItem.height } else { diff = flickableItem.contentWidth - flickableItem.width @@ -101,33 +98,33 @@ Item { inverted: scrollbar.inverted positionAtMinimum: 0 positionAtMaximum: { - if (_isVertical) { + if (internalLoader.isVertical) { internalLoader.item.contents.height - internalLoader.item.handle.height } else { internalLoader.item.contents.width - internalLoader.item.handle.width } } - value: _isVertical ? flickableItem.contentY : flickableItem.contentX + value: internalLoader.isVertical ? flickableItem.contentY : flickableItem.contentX onValueChanged: { if (flickableItem.moving) { return } - if (_isVertical) { + if (internalLoader.isVertical) { flickableItem.contentY = value } else { flickableItem.contentX = value } } - position: _isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x + position: internalLoader.isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x onPositionChanged: { if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) { return } - if (_isVertical) { + if (internalLoader.isVertical) { internalLoader.item.handle.y = position } else { internalLoader.item.handle.x = position diff --git a/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml index 69eaaf329..15ee7aa68 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml @@ -26,10 +26,10 @@ PlasmaCore.FrameSvgItem { id: background anchors.fill: parent imagePath:"widgets/scrollbar" - prefix: _isVertical ? "background-vertical" : "background-horizontal" + prefix: internalLoader.isVertical ? "background-vertical" : "background-horizontal" Keys.onUpPressed: { - if (!enabled || !_isVertical) + if (!enabled || !internalLoader.isVertical) return; if (inverted) @@ -39,7 +39,7 @@ PlasmaCore.FrameSvgItem { } Keys.onDownPressed: { - if (!enabled || !_isVertical) + if (!enabled || !internalLoader.isVertical) return; if (inverted) @@ -49,7 +49,7 @@ PlasmaCore.FrameSvgItem { } Keys.onLeftPressed: { - if (!enabled || _isVertical) + if (!enabled || internalLoader.isVertical) return; if (inverted) @@ -59,7 +59,7 @@ PlasmaCore.FrameSvgItem { } Keys.onRightPressed: { - if (!enabled || _isVertical) + if (!enabled || internalLoader.isVertical) return; if (inverted) @@ -75,10 +75,10 @@ PlasmaCore.FrameSvgItem { id: contents anchors { fill: parent - leftMargin: _isVertical || stepSize <= 0 ? 0 : leftButton.width - rightMargin: _isVertical || stepSize <= 0 ? 0 : rightButton.width - topMargin: _isVertical && stepSize > 0 ? leftButton.height : 0 - bottomMargin: _isVertical && stepSize > 0 ? rightButton.height : 0 + leftMargin: internalLoader.isVertical || stepSize <= 0 ? 0 : leftButton.width + rightMargin: internalLoader.isVertical || stepSize <= 0 ? 0 : rightButton.width + topMargin: internalLoader.isVertical && stepSize > 0 ? leftButton.height : 0 + bottomMargin: internalLoader.isVertical && stepSize > 0 ? rightButton.height : 0 } PlasmaCore.FrameSvgItem { @@ -96,10 +96,10 @@ PlasmaCore.FrameSvgItem { } } - property int length: _isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width + property int length: internalLoader.isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width - width: _isVertical ? parent.width : length - height: _isVertical ? length : parent.height + width: internalLoader.isVertical ? parent.width : length + height: internalLoader.isVertical ? length : parent.height } } @@ -113,23 +113,23 @@ PlasmaCore.FrameSvgItem { visible: stepSize > 0 anchors { - left: _isVertical ? undefined : parent.left - verticalCenter: _isVertical ? undefined : parent.verticalCenter - top: _isVertical ? parent.top : undefined - horizontalCenter: _isVertical ? parent.horizontalCenter : undefined + left: internalLoader.isVertical ? undefined : parent.left + verticalCenter: internalLoader.isVertical ? undefined : parent.verticalCenter + top: internalLoader.isVertical ? parent.top : undefined + horizontalCenter: internalLoader.isVertical ? parent.horizontalCenter : undefined } + width: 18 height: 18 - width: _showButtons ? 18 : 0 svg: scrollbarSvg elementId: { if (leftMouseArea.pressed) { - return _isVertical ? "sunken-arrow-up" : "sunken-arrow-left" + return internalLoader.isVertical ? "sunken-arrow-up" : "sunken-arrow-left" } if (scrollbar.activeFocus || leftMouseArea.containsMouse) { - return _isVertical ? "mouseover-arrow-up" : "mouseover-arrow-left" + return internalLoader.isVertical ? "mouseover-arrow-up" : "mouseover-arrow-left" } else { - return _isVertical ? "mouseover-arrow-up" : "arrow-left" + return internalLoader.isVertical ? "mouseover-arrow-up" : "arrow-left" } } @@ -160,23 +160,23 @@ PlasmaCore.FrameSvgItem { visible: stepSize > 0 anchors { - right: _isVertical ? undefined : parent.right - verticalCenter: _isVertical ? undefined : parent.verticalCenter - bottom: _isVertical ? parent.bottom : undefined - horizontalCenter: _isVertical ? parent.horizontalCenter : undefined + right: internalLoader.isVertical ? undefined : parent.right + verticalCenter: internalLoader.isVertical ? undefined : parent.verticalCenter + bottom: internalLoader.isVertical ? parent.bottom : undefined + horizontalCenter: internalLoader.isVertical ? parent.horizontalCenter : undefined } + width: 18 height: 18 - width: _showButtons ? 18 : 0 svg: scrollbarSvg elementId: { if (leftMouseArea.pressed) { - return _isVertical ? "sunken-arrow-down" : "sunken-arrow-right" + return internalLoader.isVertical ? "sunken-arrow-down" : "sunken-arrow-right" } if (scrollbar.activeFocus || leftMouseArea.containsMouse) { - return _isVertical ? "mouseover-arrow-down" : "mouseover-arrow-right" + return internalLoader.isVertical ? "mouseover-arrow-down" : "mouseover-arrow-right" } else { - return _isVertical ? "mouseover-arrow-down" : "arrow-right" + return internalLoader.isVertical ? "mouseover-arrow-down" : "arrow-right" } } @@ -210,7 +210,7 @@ PlasmaCore.FrameSvgItem { hoverEnabled: true drag { target: handle - axis: _isVertical ? Drag.YAxis : Drag.XAxis + axis: internalLoader.isVertical ? Drag.YAxis : Drag.XAxis minimumX: range.positionAtMinimum maximumX: range.positionAtMaximum minimumY: range.positionAtMinimum @@ -218,7 +218,7 @@ PlasmaCore.FrameSvgItem { } onPressed: { - if (_isVertical) { + if (internalLoader.isVertical) { // Clamp the value var newY = Math.max(mouse.y, drag.minimumY); newY = Math.min(newY, drag.maximumY); diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml index 635f31de9..0532c56a9 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml @@ -26,7 +26,7 @@ PlasmaCore.FrameSvgItem { id: background anchors.fill: parent imagePath:"widgets/scrollbar" - prefix: _isVertical ? "background-vertical" : "background-horizontal" + prefix: internalLoader.isVertical ? "background-vertical" : "background-horizontal" opacity: 0 Behavior on opacity { @@ -48,10 +48,10 @@ PlasmaCore.FrameSvgItem { imagePath:"widgets/scrollbar" prefix: "slider" - property int length: _isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width + property int length: internalLoader.isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width - width: _isVertical ? parent.width : length - height: _isVertical ? length : parent.height + width: internalLoader.isVertical ? parent.width : length + height: internalLoader.isVertical ? length : parent.height } } diff --git a/declarativeimports/plasmacomponents/qml/SelectionDialog.qml b/declarativeimports/plasmacomponents/qml/SelectionDialog.qml index 60f3349a6..8c493b76f 100644 --- a/declarativeimports/plasmacomponents/qml/SelectionDialog.qml +++ b/declarativeimports/plasmacomponents/qml/SelectionDialog.qml @@ -78,7 +78,7 @@ CommonDialog { content: Item { id: contentItem - width: theme.defaultFont.mSize.width * 80 + width: theme.defaultFont.mSize.width * 40 height: theme.defaultFont.mSize.height * 12 Item { From d457e071c05c9cbe53746ec18df6d34d5d1c0f6d Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 17:09:20 +0100 Subject: [PATCH 50/87] remove the hack of fontmetrictext --- .../plasmacomponents/qml/CheckBox.qml | 21 +++---------------- .../plasmacomponents/qml/RadioButton.qml | 19 ++--------------- .../plasmacomponents/qml/Switch.qml | 8 +------ 3 files changed, 6 insertions(+), 42 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/CheckBox.qml b/declarativeimports/plasmacomponents/qml/CheckBox.qml index 2a5b933dd..331f8891e 100644 --- a/declarativeimports/plasmacomponents/qml/CheckBox.qml +++ b/declarativeimports/plasmacomponents/qml/CheckBox.qml @@ -25,24 +25,9 @@ DualStateButton { view: PlasmaCore.FrameSvgItem { imagePath: "widgets/button" prefix: "normal" - width: fontMetricText.height + margins.left - height: fontMetricText.height + margins.top - //FIXME: an hack to have font metrics: can we have a proper binding? - Text { - id: fontMetricText - text: "M" - visible: false - font.capitalization: theme.defaultFont.capitalization - font.family: theme.defaultFont.family - font.italic: theme.defaultFont.italic - font.letterSpacing: theme.defaultFont.letterSpacing - font.pointSize: theme.defaultFont.pointSize - font.strikeout: theme.defaultFont.strikeout - font.underline: theme.defaultFont.underline - font.weight: theme.defaultFont.weight - font.wordSpacing: theme.defaultFont.wordSpacing - color: theme.textColor - } + width: theme.defaultFont.mSize.height + margins.left + height: theme.defaultFont.mSize.height + margins.top + PlasmaCore.SvgItem { svg: PlasmaCore.Svg { id: checkmarkSvg diff --git a/declarativeimports/plasmacomponents/qml/RadioButton.qml b/declarativeimports/plasmacomponents/qml/RadioButton.qml index cc609d7c5..2bac0e457 100644 --- a/declarativeimports/plasmacomponents/qml/RadioButton.qml +++ b/declarativeimports/plasmacomponents/qml/RadioButton.qml @@ -30,24 +30,9 @@ DualStateButton { imagePath: "widgets/actionbutton" } elementId: "normal" - width: fontMetricText.height + 6 + width: theme.defaultFont.mSize.height + 6 height: width - //FIXME: an hack to have font metrics: can we have a proper binding? - Text { - id: fontMetricText - text: "M" - visible: false - font.capitalization: theme.defaultFont.capitalization - font.family: theme.defaultFont.family - font.italic: theme.defaultFont.italic - font.letterSpacing: theme.defaultFont.letterSpacing - font.pointSize: theme.defaultFont.pointSize - font.strikeout: theme.defaultFont.strikeout - font.underline: theme.defaultFont.underline - font.weight: theme.defaultFont.weight - font.wordSpacing: theme.defaultFont.wordSpacing - color: theme.textColor - } + PlasmaCore.SvgItem { svg: PlasmaCore.Svg { id: checkmarkSvg diff --git a/declarativeimports/plasmacomponents/qml/Switch.qml b/declarativeimports/plasmacomponents/qml/Switch.qml index 6d997f538..5b1d48f07 100644 --- a/declarativeimports/plasmacomponents/qml/Switch.qml +++ b/declarativeimports/plasmacomponents/qml/Switch.qml @@ -27,13 +27,7 @@ DualStateButton { imagePath: "widgets/slider" prefix: "groove" width: height * 2 - height: fontMetricText.height + margins.top - //FIXME: an hack to have font metrics: can we have a proper binding? - Text { - id: fontMetricText - text: "M" - visible: false - } + height: theme.defaultFont.mSize.height + margins.top PlasmaCore.FrameSvgItem { id: highlight From 10da04882cf67245419173c9f73c08c7555e151d Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 17:12:13 +0100 Subject: [PATCH 51/87] remove the animated property --- .../plasmacomponents/platformcomponents/touch/ScrollBar.qml | 1 - declarativeimports/plasmacomponents/qml/ScrollBar.qml | 1 - declarativeimports/test/gallery/Gallery.qml | 2 -- declarativeimports/test/gallery/Scrollers.qml | 1 - declarativeimports/test/gallery/Sliders.qml | 2 -- 5 files changed, 7 deletions(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml index fa9e879fa..ccb8ac494 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ScrollBar.qml @@ -38,7 +38,6 @@ Item { // Plasma API property bool inverted: false - property bool animated: true property alias stepSize: range.stepSize property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false property real scrollButtonInterval: 50 diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index bb756b920..4ba61bed1 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -38,7 +38,6 @@ Item { // Plasma API property bool inverted: false - property bool animated: true property alias stepSize: range.stepSize property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false property real scrollButtonInterval: 50 diff --git a/declarativeimports/test/gallery/Gallery.qml b/declarativeimports/test/gallery/Gallery.qml index d2b994974..68e2e9e65 100644 --- a/declarativeimports/test/gallery/Gallery.qml +++ b/declarativeimports/test/gallery/Gallery.qml @@ -102,7 +102,6 @@ Rectangle { stepSize: 30 flickableItem: page - animated: true orientation: Qt.Horizontal anchors { left: parent.left @@ -118,7 +117,6 @@ Rectangle { orientation: Qt.Vertical flickableItem: page - animated: true anchors { top: toolBar.bottom right: parent.right diff --git a/declarativeimports/test/gallery/Scrollers.qml b/declarativeimports/test/gallery/Scrollers.qml index da1c93918..0fae6bf2a 100644 --- a/declarativeimports/test/gallery/Scrollers.qml +++ b/declarativeimports/test/gallery/Scrollers.qml @@ -52,7 +52,6 @@ Column { id: scrollBar orientation: Qt.Vertical flickableItem: scrollList - animated: true stepSize: 40 scrollButtonInterval: 50 anchors { diff --git a/declarativeimports/test/gallery/Sliders.qml b/declarativeimports/test/gallery/Sliders.qml index a87c53a2b..4e1da8ec9 100644 --- a/declarativeimports/test/gallery/Sliders.qml +++ b/declarativeimports/test/gallery/Sliders.qml @@ -49,7 +49,6 @@ Column { minimumValue: 0 maximumValue: 255 stepSize: 10 - animated: true Keys.onTabPressed: greenSlider.forceActiveFocus() } @@ -77,7 +76,6 @@ Column { minimumValue: 0 maximumValue: 255 stepSize: 10 - animated: true Keys.onTabPressed: redSlider.forceActiveFocus() } From dd3b76b9afaf380c86aa241f94632fb88fb5b4a3 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 17:49:10 +0100 Subject: [PATCH 52/87] style --- declarativeimports/plasmacomponents/qml/Button.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index 234f7e720..1c389e09e 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -86,7 +86,7 @@ Item { id: shadow anchors.fill: parent state: { - if (internal.userPressed || checked) { + if (internal.userPressed || checked) { return "hidden" } else if (mouse.containsMouse) { return "hover" From c3285d091ab974b0c50498329eb6bfde37a3d1c8 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 19:33:34 +0100 Subject: [PATCH 53/87] no mouseover on text fields with touchscreens --- .../touch/TextFieldFocus.qml | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 declarativeimports/plasmacomponents/platformcomponents/touch/TextFieldFocus.qml diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/TextFieldFocus.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/TextFieldFocus.qml new file mode 100644 index 000000000..a8b031c13 --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/TextFieldFocus.qml @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011 by Daker Fernandes Pinheiro + * Copyright (C) 2011 by Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: main + state: parent.state + + PlasmaCore.Svg { + id: lineEditSvg + imagePath: "widgets/lineedit" + onRepaintNeeded: { + if (lineEditSvg.hasElement("hint-focus-over-base")) { + main.z = 800 + } else { + main.z = 0 + } + } + Component.onCompleted: { + if (lineEditSvg.hasElement("hint-focus-over-base")) { + main.z = 800 + } else { + main.z = 0 + } + } + } + + PlasmaCore.FrameSvgItem { + id: hover + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + opacity: 0 + imagePath: "widgets/lineedit" + prefix: "hover" + } + + states: [ + State { + name: "focus" + PropertyChanges { + target: hover + opacity: 1 + prefix: "focus" + } + }, + State { + name: "hidden" + PropertyChanges { + target: hover + opacity: 0 + prefix: "hover" + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: 250 + easing.type: Easing.OutQuad + } + } + ] +} From 7331d06c7bfd962405307df1882e5a08671a57f9 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 20:09:36 +0100 Subject: [PATCH 54/87] put the framesvg in an inner element also move the boders of the framesvg outside --- .../plasmacomponents/qml/ToolBar.qml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 5674b5f50..85d03bc41 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -20,12 +20,10 @@ import QtQuick 1.1 import org.kde.plasma.core 0.1 as PlasmaCore -PlasmaCore.FrameSvgItem { +Item{ id: toolBar - imagePath: "widgets/frame" - prefix: "raised" width: parent.width - height: 48 + margins.top + margins.bottom + height: 48 + frameSvg.margins.top + frameSvg.margins.bottom // The current set of tools; null if none. property Item tools @@ -109,6 +107,19 @@ PlasmaCore.FrameSvgItem { oldContainer.opacity = 0 } + PlasmaCore.FrameSvgItem { + id: frameSvg + imagePath: "widgets/frame" + prefix: "raised" + anchors { + fill: parent + leftMargin: -margins.left + rightMargin: -margins.right + topMargin: toolBar.y <= 0 ? -margins.top : 0 + bottomMargin: toolBar.y >= toolBar.parent.height - toolBar.height ? -margins.bottom : 0 + } + } + Item { anchors { fill: parent From 74c4c37d247ab98df71217f455197b746355a299 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 20:19:29 +0100 Subject: [PATCH 55/87] ghter animation effect --- declarativeimports/plasmacomponents/qml/ToolBar.qml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 85d03bc41..5b30329f8 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -66,20 +66,20 @@ Item{ switch (transition) { case "push": containerA.animationsEnabled = true - oldContainer.x = -oldContainer.width + oldContainer.x = -oldContainer.width/2 containerA.animationsEnabled = false - newContainer.x = newContainer.width + newContainer.x = newContainer.width/2 newContainer.y = 0 containerA.animationsEnabled = true newContainer.x = 0 break case "pop": containerA.animationsEnabled = true - oldContainer.x = oldContainer.width + oldContainer.x = oldContainer.width/2 containerA.animationsEnabled = false - newContainer.x = -newContainer.width + newContainer.x = -newContainer.width/2 newContainer.y = 0 containerA.animationsEnabled = true newContainer.x = 0 @@ -98,7 +98,7 @@ Item{ default: containerA.animationsEnabled = false containerA.animationsEnabled = false - oldContainer.x = -oldContainer.width + oldContainer.x = -oldContainer.width/2 newContainer.x = 0 break } From 1d67eef64f29cd13341bdcd71560f0beb9ce1c24 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 20:25:09 +0100 Subject: [PATCH 56/87] layout adjustment (fixme, discover why this is needed) --- declarativeimports/plasmacomponents/qml/ToolBarLayout.qml | 2 +- declarativeimports/test/gallery/Gallery.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml b/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml index be51e2bff..47bf2e9f2 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBarLayout.qml @@ -50,7 +50,7 @@ Row { layouting = true spacer.parent = null - spacer.width = root.parent.width - root.childrenRect.width + spacer.width = root.parent.width - root.childrenRect.width -10 var last = root.children[numChildren-2] last.parent = null diff --git a/declarativeimports/test/gallery/Gallery.qml b/declarativeimports/test/gallery/Gallery.qml index 68e2e9e65..f1f536d60 100644 --- a/declarativeimports/test/gallery/Gallery.qml +++ b/declarativeimports/test/gallery/Gallery.qml @@ -47,7 +47,7 @@ Rectangle { text: "button on first toolbar" } } - Row { + PlasmaComponents.ToolBarLayout { id: toolbarB visible: false spacing: 5 From 824415d08ef2a2919d4dac13c7bc2b027bbecd4e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 20:48:23 +0100 Subject: [PATCH 57/87] for some reason the PageStack type doesn't work --- declarativeimports/plasmacomponents/qml/Page.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/Page.qml b/declarativeimports/plasmacomponents/qml/Page.qml index 03bf145bc..f9496ab38 100644 --- a/declarativeimports/plasmacomponents/qml/Page.qml +++ b/declarativeimports/plasmacomponents/qml/Page.qml @@ -52,7 +52,7 @@ Item { // PageStatus.Deactivating - the page is transitioning into becoming inactive property int status: PageStatus.Inactive - property PageStack pageStack + property Item pageStack // Defines orientation lock for a page property int orientationLock: PageOrientation.Automatic From 5e6b5c18292db24389b0f0f4eff2416409e0bfd6 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 20:55:13 +0100 Subject: [PATCH 58/87] clip contents --- declarativeimports/plasmacomponents/qml/ToolBar.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 5b30329f8..d942571a9 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -121,6 +121,7 @@ Item{ } Item { + clip: true anchors { fill: parent leftMargin: parent.margins.left From b9f9153c4a11146c8f587095c701f4f87262c952 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 21:32:45 +0100 Subject: [PATCH 59/87] new gallery based on PageStack --- declarativeimports/test/gallery/Busy.qml | 109 +-- declarativeimports/test/gallery/Buttons.qml | 130 ++-- .../test/gallery/CheckableButtons.qml | 168 ++--- declarativeimports/test/gallery/Gallery.qml | 114 ++-- declarativeimports/test/gallery/Misc.qml | 636 ++++++++++++++++++ declarativeimports/test/gallery/Scrollers.qml | 218 +++--- declarativeimports/test/gallery/Sliders.qml | 205 +++--- declarativeimports/test/gallery/Texts.qml | 153 +++-- 8 files changed, 1243 insertions(+), 490 deletions(-) create mode 100644 declarativeimports/test/gallery/Misc.qml diff --git a/declarativeimports/test/gallery/Busy.qml b/declarativeimports/test/gallery/Busy.qml index 8e77db1ec..55ffe20f5 100644 --- a/declarativeimports/test/gallery/Busy.qml +++ b/declarativeimports/test/gallery/Busy.qml @@ -20,59 +20,76 @@ import QtQuick 1.0 import org.kde.plasma.components 0.1 as PlasmaComponents -Column { - spacing: 20 +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height - Text { - font.pixelSize: 20 - text: "Busy Indicator" - } - - PlasmaComponents.BusyIndicator { } - - PlasmaComponents.BusyIndicator { running: true } - - Text { - font.pixelSize: 20 - text: "Progress Bar" - } - - Text { text: "Horizontal" } - - PlasmaComponents.ProgressBar { - value: 0.3 - } - - PlasmaComponents.ProgressBar { - indeterminate: true - } - - PlasmaComponents.ProgressBar { - minimumValue: 0 - maximumValue: 100 - value: 30 - } - - Text { text: "Vertical" } - Row { - spacing: 20 + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + text: "ToolButton" + } PlasmaComponents.ProgressBar { value: 0.3 - orientation: Qt.Vertical - width: 20 - height: 100 } - PlasmaComponents.ProgressBar { - value: 0.4 - orientation: Qt.Vertical - width: 20 - height: 120 + PlasmaComponents.TextField { + text: "Busy widgets" } + } + Column { + spacing: 20 + + Text { + font.pixelSize: 20 + text: "Busy Indicator" + } + + PlasmaComponents.BusyIndicator { } + + PlasmaComponents.BusyIndicator { running: true } + + Text { + font.pixelSize: 20 + text: "Progress Bar" + } + + Text { text: "Horizontal" } + + PlasmaComponents.ProgressBar { + value: 0.3 + } + PlasmaComponents.ProgressBar { - orientation: Qt.Vertical - width: 20 - height: 100 indeterminate: true } + + PlasmaComponents.ProgressBar { + minimumValue: 0 + maximumValue: 100 + value: 30 + } + + Text { text: "Vertical" } + Row { + spacing: 20 + PlasmaComponents.ProgressBar { + value: 0.3 + orientation: Qt.Vertical + width: 20 + height: 100 + } + PlasmaComponents.ProgressBar { + value: 0.4 + orientation: Qt.Vertical + width: 20 + height: 120 + } + PlasmaComponents.ProgressBar { + orientation: Qt.Vertical + width: 20 + height: 100 + indeterminate: true + } + } } } diff --git a/declarativeimports/test/gallery/Buttons.qml b/declarativeimports/test/gallery/Buttons.qml index b1d9ecf7b..39dd2c6d9 100644 --- a/declarativeimports/test/gallery/Buttons.qml +++ b/declarativeimports/test/gallery/Buttons.qml @@ -20,80 +20,94 @@ import QtQuick 1.0 import org.kde.plasma.components 0.1 as PlasmaComponents -Column { - spacing: 20 - - Text { - font.pixelSize: 20 - text: "Buttons" +PlasmaComponents.Page { + height: childrenRect.height + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.Button { + text: "Button" + } + PlasmaComponents.Button { + text: "toolbar of the Buttons page" + } + PlasmaComponents.TextField {} } - PlasmaComponents.Button { - id: bt1 - width: 140 - height: 30 - text: "Button" + Column { + spacing: 20 - onClicked: { - console.log("Clicked"); + Text { + font.pixelSize: 20 + text: "Buttons" } - Keys.onTabPressed: bt2.forceActiveFocus(); - } + PlasmaComponents.Button { + id: bt1 + width: 140 + height: 30 + text: "Button" - PlasmaComponents.Button { - id: bt2 - width: 140 - height: 30 - text: "Checkable Button" - checkable: true + onClicked: { + console.log("Clicked"); + } - onCheckedChanged: { - if (checked) - console.log("Button Checked"); - else - console.log("Button Unchecked"); + Keys.onTabPressed: bt2.forceActiveFocus(); } - Keys.onTabPressed: bt3.forceActiveFocus(); - } + PlasmaComponents.Button { + id: bt2 + width: 140 + height: 30 + text: "Checkable Button" + checkable: true - PlasmaComponents.Button { - id: bt3 - width: 140 - height: 30 - text: "Different Font" - font { - pixelSize: 20 - family: "Helvetica" + onCheckedChanged: { + if (checked) + console.log("Button Checked"); + else + console.log("Button Unchecked"); + } + + Keys.onTabPressed: bt3.forceActiveFocus(); } - Keys.onTabPressed: bt4.forceActiveFocus(); - } + PlasmaComponents.Button { + id: bt3 + width: 140 + height: 30 + text: "Different Font" + font { + pixelSize: 20 + family: "Helvetica" + } - PlasmaComponents.Button { - id: bt4 - width: 140 - height: 30 - text: "Icon Button" - iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png" + Keys.onTabPressed: bt4.forceActiveFocus(); + } - Keys.onTabPressed: bt5.forceActiveFocus(); - } + PlasmaComponents.Button { + id: bt4 + width: 140 + height: 30 + text: "Icon Button" + iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png" - PlasmaComponents.Button { - id: bt5 - width: 140 - height: 30 - iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png" + Keys.onTabPressed: bt5.forceActiveFocus(); + } - Keys.onTabPressed: bt1.forceActiveFocus(); - } + PlasmaComponents.Button { + id: bt5 + width: 140 + height: 30 + iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png" - PlasmaComponents.Button { - width: 140 - height: 30 - text: "Disabled Button" - enabled: false + Keys.onTabPressed: bt1.forceActiveFocus(); + } + + PlasmaComponents.Button { + width: 140 + height: 30 + text: "Disabled Button" + enabled: false + } } } diff --git a/declarativeimports/test/gallery/CheckableButtons.qml b/declarativeimports/test/gallery/CheckableButtons.qml index fee6032b4..66223760f 100644 --- a/declarativeimports/test/gallery/CheckableButtons.qml +++ b/declarativeimports/test/gallery/CheckableButtons.qml @@ -20,88 +20,106 @@ import QtQuick 1.0 import org.kde.plasma.components 0.1 as PlasmaComponents -Column { - spacing: 20 - Text { - font.pixelSize: 20 - text: "Check Box" - } +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height - PlasmaComponents.CheckBox { - width: 140 - height: 30 - text: "Check Box 1" - - onCheckedChanged: { - if (checked) - console.log("CheckBox checked"); - else - console.log("CheckBox unchecked"); + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + text: "ToolButton" } - onClicked: { - console.log("CheckBox clicked"); + PlasmaComponents.CheckBox { + text: "Checkbox in the toolbar" + } + PlasmaComponents.TextField { + text: "hello" } } - - PlasmaComponents.CheckBox { - height: 30 - text: "Disabled" - enabled: false - } - - PlasmaComponents.CheckBox { - height: 30 - text: "" - } - - PlasmaComponents.CheckBox { - height: 30 - text: "A loooooooooooooong text" - } - - Text { - font.pixelSize: 20 - text: "Radio Button" - } - - PlasmaComponents.RadioButton { - width: 140 - height: 30 - text: "RadioButton" - - onCheckedChanged: { - if (checked) - console.log("RadioButton Checked"); - else - console.log("RadioButton Unchecked"); - } - } - - PlasmaComponents.Switch { } - - Text { - font.pixelSize: 20 - text: "Button Row" - } - - PlasmaComponents.ButtonRow { + Column { spacing: 20 - PlasmaComponents.RadioButton { text: "A" } - PlasmaComponents.RadioButton { text: "B" } - PlasmaComponents.RadioButton { text: "C" } - } - Text { - font.pixelSize: 20 - text: "Button Column" - } + Text { + font.pixelSize: 20 + text: "Check Box" + } - PlasmaComponents.ButtonColumn { - spacing: 20 - PlasmaComponents.RadioButton { text: "Alice" } - PlasmaComponents.RadioButton { text: "Bob" } - PlasmaComponents.RadioButton { text: "Charles" } - } + PlasmaComponents.CheckBox { + width: 140 + height: 30 + text: "Check Box 1" + onCheckedChanged: { + if (checked) + console.log("CheckBox checked"); + else + console.log("CheckBox unchecked"); + } + onClicked: { + console.log("CheckBox clicked"); + } + } + + PlasmaComponents.CheckBox { + height: 30 + text: "Disabled" + enabled: false + } + + PlasmaComponents.CheckBox { + height: 30 + text: "" + } + + PlasmaComponents.CheckBox { + height: 30 + text: "A loooooooooooooong text" + } + + Text { + font.pixelSize: 20 + text: "Radio Button" + } + + PlasmaComponents.RadioButton { + width: 140 + height: 30 + text: "RadioButton" + + onCheckedChanged: { + if (checked) + console.log("RadioButton Checked"); + else + console.log("RadioButton Unchecked"); + } + } + + PlasmaComponents.Switch { } + + Text { + font.pixelSize: 20 + text: "Button Row" + } + + PlasmaComponents.ButtonRow { + spacing: 20 + PlasmaComponents.RadioButton { text: "A" } + PlasmaComponents.RadioButton { text: "B" } + PlasmaComponents.RadioButton { text: "C" } + } + + Text { + font.pixelSize: 20 + text: "Button Column" + } + + PlasmaComponents.ButtonColumn { + spacing: 20 + PlasmaComponents.RadioButton { text: "Alice" } + PlasmaComponents.RadioButton { text: "Bob" } + PlasmaComponents.RadioButton { text: "Charles" } + } + + } } diff --git a/declarativeimports/test/gallery/Gallery.qml b/declarativeimports/test/gallery/Gallery.qml index f1f536d60..515b3db4b 100644 --- a/declarativeimports/test/gallery/Gallery.qml +++ b/declarativeimports/test/gallery/Gallery.qml @@ -18,14 +18,14 @@ */ import QtQuick 1.0 -import org.kde.plasma.components 0.1 as PlasmaComponents +import org.kde.plasma.components 0.1 Rectangle { width: 1000 height: 800 color: "lightgrey" - PlasmaComponents.ToolBar { + ToolBar { id: toolBar z: 10 anchors { @@ -33,70 +33,82 @@ Rectangle { left: parent.left right: parent.right } - tools: toolbarA } - Row { - id: toolbarA - visible: false - spacing: 5 - PlasmaComponents.ToolButton { - text: "Switch toolbar" - onClicked: toolBar.setTools(toolbarB, "push") + + + ListView { + id: pageSelector + width: 200 + anchors { + top: toolBar.bottom + bottom: parent.bottom } - PlasmaComponents.ToolButton { - text: "button on first toolbar" + model: ListModel { + id: pagesModel + ListElement { + page: "Buttons.qml" + title: "Buttons" + } + ListElement { + page: "CheckableButtons.qml" + title: "Checkable buttons" + } + ListElement { + page: "Busy.qml" + title: "Busy indicators" + } + ListElement { + page: "Sliders.qml" + title: "Sliders" + } + ListElement { + page: "Scrollers.qml" + title: "Scrollers" + } + ListElement { + page: "Texts.qml" + title: "Text elements" + } + ListElement { + page: "Misc.qml" + title: "Misc stuff" + } + } + delegate: ListItem { + enabled: true + Column { + Label { + text: title + } + } + onClicked: pageStack.replace(Qt.createComponent(page)) } } - PlasmaComponents.ToolBarLayout { - id: toolbarB - visible: false - spacing: 5 - PlasmaComponents.ToolButton { - text: "Switch toolbar" - onClicked: toolBar.setTools(toolbarA, "pop") - } - PlasmaComponents.ToolButton { - flat: false - text: "button on second toolbar" - } - PlasmaComponents.TextField {} - } + + Flickable { id: page anchors { top: toolBar.bottom - left: parent.left + left: pageSelector.right right: parent.right bottom: parent.bottom } - contentWidth: 2200 - contentHeight: 1000 + contentWidth: pageStack.currentPage.implicitWidth + contentHeight: pageStack.currentPage.implicitHeight - Row { - x: 30 - anchors { - top: parent.top - bottom: parent.bottom - margins: 20 - } - spacing: 30 - - Buttons{ } - - CheckableButtons { } - - Busy { } - - Sliders { } - - Scrollers { } - - Texts { } + PageStack { + id: pageStack + toolBar: toolBar + width: page.width + height: currentPage.implicitHeight + initialPage: Qt.createComponent("Buttons.qml") } + } - PlasmaComponents.ScrollBar { + ScrollBar { id: horizontalScrollBar stepSize: 30 @@ -110,7 +122,7 @@ Rectangle { } } - PlasmaComponents.ScrollBar { + ScrollBar { id: verticalScrollBar stepSize: 30 diff --git a/declarativeimports/test/gallery/Misc.qml b/declarativeimports/test/gallery/Misc.qml new file mode 100644 index 000000000..aebdd733f --- /dev/null +++ b/declarativeimports/test/gallery/Misc.qml @@ -0,0 +1,636 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 +import org.kde.plasma.components 0.1 + + +Column { + id: column + + // for demonstration and testing purposes each component needs to + // set its inverted state explicitly + property bool childrenInverted: false + property bool windowInverted: false + + spacing: 14 + + Label { + anchors.horizontalCenter: parent.horizontalCenter + text: "Qt Components " + (enabled ? "(enabled)" : "(disabled)") + } + + Button { + anchors.horizontalCenter: parent.horizontalCenter + text: "Push me" + width: parent.width - parent.spacing + } + + TextField { + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "TextField" + width: parent.width - parent.spacing + } + + TextField { + id: clearable + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "Clearable TextField" + text: "Clearable TextField" + width: parent.width - parent.spacing + + Image { + id: clearText + anchors { top: parent.top; right: parent.right; margins: 6 } + fillMode: Image.PreserveAspectFit + smooth: true; visible: parent.text + source: "qrc:close_stop.svg" + height: parent.height - 6 + width: parent.height - 6 + + MouseArea { + id: clear + anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter } + height: clearable.height; width: clearable.height + onClicked: clearable.text = "" + } + } + } + + TextField { + id: customOperation + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "Custom operation" + width: parent.width - parent.spacing + + Image { + id: addText + anchors { top: parent.top; right: parent.right } + smooth: true + fillMode: Image.PreserveAspectFit + source: "qrc:ok.svg" + height: parent.height; width: parent.height + scale: LayoutMirroring.enabled ? -1 : 1 + + MouseArea { + id: add + anchors.fill: parent + onClicked: textSelection.open() + } + + SelectionDialog { + id: textSelection + titleText: "Preset Texts" + selectedIndex: -1 + model: ListModel { + ListElement { name: "Lorem ipsum." } + ListElement { name: "Lorem ipsum dolor sit amet." } + ListElement { name: "Lorem ipsum dolor sit amet ipsum." } + } + + onAccepted: { + customOperation.text = textSelection.model.get(textSelection.selectedIndex).name + customOperation.forceActiveFocus() + } + + onRejected: selectedIndex = -1 + } + } + } + + TextArea { + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "This is a\n multiline control." + width: parent.width - parent.spacing; height: 280 + } + + Slider { + anchors.horizontalCenter: parent.horizontalCenter + value: 50 + } + + ButtonRow { + anchors.horizontalCenter: parent.horizontalCenter + spacing: parent.spacing + + exclusive: true + + RadioButton { + } + + RadioButton { + } + } + + Row { + anchors.horizontalCenter: parent.horizontalCenter + spacing: parent.spacing + + CheckBox { + } + + CheckBox { + checked: true + } + } + + Switch { + anchors.horizontalCenter: parent.horizontalCenter + } + + ProgressBar { + anchors.horizontalCenter: parent.horizontalCenter + + Timer { + running: true + repeat: true + interval: 25 + onTriggered: parent.value = (parent.value + 1) % 1.1 + } + } + + ProgressBar { + anchors.horizontalCenter: parent.horizontalCenter + indeterminate: true + } + + Component { + id: dialogComponent + CommonDialog { + id: dialog + titleText: "CommonDialog" + buttonTexts: ["Ok", "Cancel"] + + content: Text { + text: "This is the content" + font { bold: true; pixelSize: 16 } + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + } + + Button { + property CommonDialog dialog + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + text: "CommonDialog" + onClicked: { + if (!dialog) + dialog = dialogComponent.createObject(column) + dialog.open() + } + } + + Component { + id: singleSelectionDialogComponent + SelectionDialog { + titleText: "Select background color" + selectedIndex: 1 + + model: ListModel { + id: colorModel + + ListElement { name: "Red" } + ListElement { name: "Blue" } + ListElement { name: "Green" } + ListElement { name: "Yellow" } + ListElement { name: "Black" } + ListElement { name: "White" } + ListElement { name: "Grey" } + ListElement { name: "Orange" } + ListElement { name: "Pink" } + } + + onAccepted: { selectionDialogButton.parent.color = colorModel.get(selectedIndex).name } + } + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + height: selectionDialogButton.height + width: parent.width - parent.spacing + radius: 10 + + Button { + id: selectionDialogButton + property SelectionDialog singleSelectionDialog + anchors.centerIn: parent + text: "Selection Dialog" + onClicked: { + if (!singleSelectionDialog) + singleSelectionDialog = singleSelectionDialogComponent.createObject(column) + singleSelectionDialog.open() + } + } + } + + Button { + property QueryDialog queryDialog + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + text: "QueryDialog" + onClicked: { + if (!queryDialog) + queryDialog = queryDialogComponent.createObject(column) + queryDialog.open() + } + } + + Component { + id: queryDialogComponent + QueryDialog { + titleText: "Query Dialog" + // Arabic character in the beginning to test right-to-left UI alignment + message: (LayoutMirroring.enabled ? "\u062a" : "") + "Lorem ipsum dolor sit amet, consectetur adipisici elit," + + "sed eiusmod tempor incidunt ut labore et dolore magna aliqua." + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris" + + "nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit" + + "in voluptate velit esse cillum dolore eu fugiat nulla pariatur." + + "Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui" + + "officia deserunt mollit anim id est laborum." + + acceptButtonText: "Ok" + rejectButtonText: "Cancel" + + titleIcon: "kmail" + } + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + height: contentMenuButton.height + width: parent.width - parent.spacing + radius: 10 + + Button { + id: contentMenuButton + property ContextMenu contextMenu + anchors.horizontalCenter: parent.horizontalCenter + text: "ContextMenu" + onClicked: { + if (!contextMenu) + contextMenu = contextMenuComponent.createObject(contentMenuButton) + contextMenu.open() + } + } + } + + Component { + id: contextMenuComponent + ContextMenu { + MenuItem { + text: "White" + onClicked: contentMenuButton.parent.color = "White" + } + MenuItem { + text: "Red" + onClicked: contentMenuButton.parent.color = "Red" + } + MenuItem { + text: "LightBlue" + onClicked: contentMenuButton.parent.color = "LightBlue" + } + MenuItem { + text: "LightGreen" + onClicked: contentMenuButton.parent.color = "LightGreen" + } + } + } + + ListView { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing; height: 120 + clip: true + delegate: listDelegate + model: listModel + header: listHeading + } + + ListModel { + id: listModel + + ListElement { + titleText: "Title" + subTitleText: "SubTitle" + } + ListElement { + titleText: "Title2" + subTitleText: "SubTitle" + } + ListElement { + titleText: "Title3" + subTitleText: "SubTitle" + } + } + + Component { + id: listHeading + Label { + text: "Heading" + } + } + + Component { + id: listDelegate + ListItem { + id: listItem + Column { + + Label { + text: titleText + } + Label { + text: subTitleText + } + } + } + } + + Label { + property SelectionDialog selectionDialog + text: { + if (selectionDialog) { + if (selectionDialog.selectedIndex >= 0) + return selectionDialog.model.get(selectionDialog.selectedIndex).name + } + return "Three" + } + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + + MouseArea { + anchors.fill: parent + onClicked: { + if (!selectionDialog) + selectionDialog = selectionDialogComponent.createObject(column) + selectionDialog.open() + } + } + + Component { + id: selectionDialogComponent + SelectionDialog { + titleText: "Select" + selectedIndex: 2 + model: ListModel { + ListElement { name: "One" } + ListElement { name: "Two" } + ListElement { name: "Three" } + ListElement { name: "Four" } + ListElement { name: "Five" } + ListElement { name: "Six" } + ListElement { name: "Seven" } + ListElement { name: "Eight" } + ListElement { name: "Nine" } + } + } + } + } + + + TabBar { + //width: parent.width - parent.spacing + //height: 50 + anchors.horizontalCenter: parent.horizontalCenter + TabButton { tab: tab1content; text: "1"; iconSource: "qrc:close_stop.svg"} + TabButton { tab: tab2content; text: "2"; iconSource: "konqueror"} + TabButton { tab: tab3content; text: "3"} + } + + TabGroup { + height: 100 + width: parent.width - parent.spacing + Button { id: tab1content; text: "tab1" } + Text { + id: tab2content + text: "tab2" + horizontalAlignment: "AlignHCenter" + verticalAlignment: "AlignVCenter" + } + Page { + id: tab3content + width: 50 + height: 32 + CheckBox { anchors.fill: parent; text: "tab3"} + } + } + + ToolButton { + id: toolButton + text: "ToolButton" + iconSource: "konqueror" + } + + ToolButton { + id: toolButton2 + flat: true + iconSource: "qrc:ok.svg" + } + + ToolButton { + id: toolButton3 + text: "ToolButton" + iconSource: "qrc:close_stop.svg" + } + + Row { + spacing: 5 + + BusyIndicator { + id: busyInd1 + width: 20 + height: 20 + running: true + } + + BusyIndicator { + // default width/height is 40 + id: busyInd2 + running: true + } + + BusyIndicator { + id: busyInd3 + width: 60 + height: 60 + running: true + } + + Button { + text: "Toggle" + onClicked: { + busyInd1.running = !busyInd1.running + busyInd2.running = !busyInd2.running + busyInd3.running = !busyInd3.running + } + } + } + + Button { + property CommonDialog sectionScroll + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - parent.spacing + text: "SectionScroller" + iconSource: "konqueror" + onClicked: { + if (!sectionScroll) + sectionScroll = sectionScrollComponent.createObject(column) + sectionScroll.open() + } + } + + Component { + id: sectionScrollComponent + CommonDialog { + id: sectionScroll + titleText: "Section Scroller" + buttonTexts: ["Close"] + onButtonClicked: close() + + content: Rectangle { + color: Qr.rgba(1,1,1,0.8) + width: parent.width + implicitHeight: 300 + + ListModel { + id: testModel + ListElement { name: "A Cat 1"; alphabet: "A" } + ListElement { name: "A Cat 2"; alphabet: "A" } + ListElement { name: "Boo 1"; alphabet: "B" } + ListElement { name: "Boo 2"; alphabet: "B" } + ListElement { name: "Cat 1"; alphabet: "C" } + ListElement { name: "Cat 2"; alphabet: "C" } + ListElement { name: "Dog 1"; alphabet: "D" } + ListElement { name: "Dog 2"; alphabet: "D" } + ListElement { name: "Dog 3"; alphabet: "D" } + ListElement { name: "Dog 4"; alphabet: "D" } + ListElement { name: "Dog 5"; alphabet: "D" } + ListElement { name: "Dog 6"; alphabet: "D" } + ListElement { name: "Dog 7"; alphabet: "D" } + ListElement { name: "Dog 8"; alphabet: "D" } + ListElement { name: "Dog 9"; alphabet: "D" } + ListElement { name: "Dog 10"; alphabet: "D" } + ListElement { name: "Dog 11"; alphabet: "D" } + ListElement { name: "Dog 12"; alphabet: "D" } + ListElement { name: "Elephant 1"; alphabet: "E" } + ListElement { name: "Elephant 2"; alphabet: "E" } + ListElement { name: "FElephant 1"; alphabet: "F" } + ListElement { name: "FElephant 2"; alphabet: "F" } + ListElement { name: "Guinea pig"; alphabet: "G" } + ListElement { name: "Goose"; alphabet: "G" } + ListElement { name: "Horse"; alphabet: "H" } + ListElement { name: "Horse"; alphabet: "H" } + ListElement { name: "Parrot"; alphabet: "P" } + ListElement { name: "Parrot"; alphabet: "P" } + } + + ListView { + id: list + anchors.fill: parent + clip: true + cacheBuffer: contentHeight + delegate: ListItem { + Label { + anchors { + top: parent.top; topMargin: 4 + left: parent.left; leftMargin: 4 + } + text: name + " (index " + index + ")" + horizontalAlignment: Text.AlignLeft + } + } + + model: testModel + section.property: "alphabet" + section.criteria: ViewSection.FullString + section.delegate: ListItem { + sectionDelegate: true + Label { + anchors { + top: parent.top; topMargin: 4 + left: parent.left; leftMargin: 4 + } + text: section + horizontalAlignment: Text.AlignLeft + font { bold: true; } + } + } + } + + SectionScroller { + id: sectionScroller + listView: list + } + } + } + } + + ButtonRow { + id: buttonRow1 + width: parent.width - parent.spacing + exclusive: true + checkedButton: b2 + + Button { text: "b1" } + Button { text: "b2" } + Button { text: "b3" } + } + + ButtonRow { + id: buttonRow2 + width: parent.width - parent.spacing + exclusive: true + + ToolButton { text: "tb1" } + ToolButton { text: "tb2" } + } + + ButtonColumn { + id: buttonColumn + width: parent.width - parent.spacing + exclusive: true + + Button { text: "b4" } + Button { text: "b5" } + Button { text: "b6" } + Button { text: "b7" } + } +} diff --git a/declarativeimports/test/gallery/Scrollers.qml b/declarativeimports/test/gallery/Scrollers.qml index 0fae6bf2a..25aa47ed8 100644 --- a/declarativeimports/test/gallery/Scrollers.qml +++ b/declarativeimports/test/gallery/Scrollers.qml @@ -20,110 +20,130 @@ import QtQuick 1.0 import org.kde.plasma.components 0.1 as PlasmaComponents -Column { - spacing: 20 +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height - Text { - font.pixelSize: 20 - text: "Scroll Bar" - } - - ListView { - id: scrollList - - width: 200 - height: 200 - clip: true - model: 20 - delegate: Text { - width: 200 - height: 30 - text: index - font.pixelSize: 18 - } - - Rectangle { - anchors.fill: parent - color: "grey" - opacity: 0.3 - } - - PlasmaComponents.ScrollBar { - id: scrollBar - orientation: Qt.Vertical - flickableItem: scrollList - stepSize: 40 - scrollButtonInterval: 50 - anchors { - top: scrollList.top - right: scrollList.right - bottom: scrollList.bottom - } - } - } - - Text { - font.pixelSize: 20 - text: "Scroll Decorator" - } - - Item { - width: 200 - height: 200 - PlasmaComponents.Highlight { anchors.fill: parent } - Flickable { - id: scrollArea - anchors.fill: parent - clip: true - contentWidth: 400 - contentHeight: 400 - - // Flickable Contents - Rectangle { - color: "green" - width: 100 - height: 100 - } - Rectangle { - x: 80 - y: 80 - color: "blue" - width: 200 - height: 200 - } - Rectangle { - x: 200 - y: 200 - color: "red" - width: 150 - height: 150 - } - } - - // Scroll Decorators - PlasmaComponents.ScrollBar { - orientation: Qt.Vertical - flickableItem: scrollArea - inverted: true - anchors { - top: scrollArea.top - right: scrollArea.right - bottom: scrollArea.bottom - } - Text { - y: parent.height / 2 - x: 13 - rotation: -90 - text: "inverted" - } + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + text: "ToolButton" } PlasmaComponents.ScrollBar { orientation: Qt.Horizontal + interactive: true flickableItem: scrollArea - anchors { - left: scrollArea.left - right: scrollArea.right - bottom: scrollArea.bottom + width: 200 + } + PlasmaComponents.TextField { + text: "hello" + } + } + Column { + spacing: 20 + + Text { + font.pixelSize: 20 + text: "Scroll Bar" + } + + ListView { + id: scrollList + + width: 200 + height: 200 + clip: true + model: 20 + delegate: Text { + width: 200 + height: 30 + text: index + font.pixelSize: 18 + } + + Rectangle { + anchors.fill: parent + color: "grey" + opacity: 0.3 + } + + PlasmaComponents.ScrollBar { + id: scrollBar + orientation: Qt.Vertical + flickableItem: scrollList + stepSize: 40 + scrollButtonInterval: 50 + anchors { + top: scrollList.top + right: scrollList.right + bottom: scrollList.bottom + } + } + } + + Text { + font.pixelSize: 20 + text: "Scroll Decorator" + } + + Item { + width: 200 + height: 200 + PlasmaComponents.Highlight { anchors.fill: parent } + Flickable { + id: scrollArea + anchors.fill: parent + clip: true + contentWidth: 400 + contentHeight: 400 + + // Flickable Contents + Rectangle { + color: "green" + width: 100 + height: 100 + } + Rectangle { + x: 80 + y: 80 + color: "blue" + width: 200 + height: 200 + } + Rectangle { + x: 200 + y: 200 + color: "red" + width: 150 + height: 150 + } + } + + // Scroll Decorators + PlasmaComponents.ScrollBar { + orientation: Qt.Vertical + flickableItem: scrollArea + inverted: true + anchors { + top: scrollArea.top + right: scrollArea.right + bottom: scrollArea.bottom + } + Text { + y: parent.height / 2 + x: 13 + rotation: -90 + text: "inverted" + } + } + PlasmaComponents.ScrollBar { + orientation: Qt.Horizontal + flickableItem: scrollArea + anchors { + left: scrollArea.left + right: scrollArea.right + bottom: scrollArea.bottom + } } } } diff --git a/declarativeimports/test/gallery/Sliders.qml b/declarativeimports/test/gallery/Sliders.qml index 4e1da8ec9..9d37996ad 100644 --- a/declarativeimports/test/gallery/Sliders.qml +++ b/declarativeimports/test/gallery/Sliders.qml @@ -20,111 +20,130 @@ import QtQuick 1.0 import org.kde.plasma.components 0.1 as PlasmaComponents -Column { - spacing: 20 +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height - PlasmaComponents.Label { - font.pixelSize: 20 - text: "Slider" - } - - PlasmaComponents.Highlight { - width: 300 - height: 400 - Column { - anchors { - fill: parent - } - spacing: 10 - - PlasmaComponents.Label { text: "Color Selector"; font.pixelSize: 20 } - - PlasmaComponents.Label { text: "Red" } - - PlasmaComponents.Slider { - id: redSlider - height: 20 - width: 255 - orientation: Qt.Horizontal - minimumValue: 0 - maximumValue: 255 - stepSize: 10 - Keys.onTabPressed: greenSlider.forceActiveFocus() - } - - PlasmaComponents.Label { text: "Green" } - - PlasmaComponents.Slider { - id: greenSlider - height: 20 - width: 255 - orientation: Qt.Horizontal - minimumValue: 0 - maximumValue: 255 - stepSize: 10 - animated: true - Keys.onTabPressed: blueSlider.forceActiveFocus() - } - - PlasmaComponents.Label { text: "Blue" } - - PlasmaComponents.Slider { - id: blueSlider - height: 20 - width: 255 - orientation: Qt.Horizontal - minimumValue: 0 - maximumValue: 255 - stepSize: 10 - Keys.onTabPressed: redSlider.forceActiveFocus() - } - - Rectangle { - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width / 2 - height: width - color: Qt.rgba(redSlider.value / 255, greenSlider.value / 255, blueSlider.value / 255, 1) - } + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + text: "ToolButton" + } + PlasmaComponents.Slider { + width: 140 + animated: true + enabled: true + } + PlasmaComponents.TextField { + text: "hello" } } + Column { + spacing: 20 - PlasmaComponents.Label { text: "Disabled Horizontal Slider" } + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Slider" + } - PlasmaComponents.Slider { - id: horizontalSlider - width: 140 - height: 20 - animated: true - enabled: false - } + PlasmaComponents.Highlight { + width: 300 + height: 400 + Column { + anchors { + fill: parent + } + spacing: 10 - PlasmaComponents.Label { text: "Inverted Horizontal Slider" } + PlasmaComponents.Label { text: "Color Selector"; font.pixelSize: 20 } - PlasmaComponents.Slider { - id: invHorizontalSlider - width: 140 - height: 20 - inverted: true - animated: true - enabled: true - } + PlasmaComponents.Label { text: "Red" } - PlasmaComponents.Label { text: "Vertical Slider" } + PlasmaComponents.Slider { + id: redSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + Keys.onTabPressed: greenSlider.forceActiveFocus() + } + + PlasmaComponents.Label { text: "Green" } + + PlasmaComponents.Slider { + id: greenSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + animated: true + Keys.onTabPressed: blueSlider.forceActiveFocus() + } + + PlasmaComponents.Label { text: "Blue" } + + PlasmaComponents.Slider { + id: blueSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + Keys.onTabPressed: redSlider.forceActiveFocus() + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width / 2 + height: width + color: Qt.rgba(redSlider.value / 255, greenSlider.value / 255, blueSlider.value / 255, 1) + } + } + } + + PlasmaComponents.Label { text: "Disabled Horizontal Slider" } - Row { - spacing: 30 PlasmaComponents.Slider { - id: verticalSlider - width: 20 - height: 140 - orientation: Qt.Vertical - minimumValue: 10 - maximumValue: 1000 - stepSize: 50 + id: horizontalSlider + width: 140 + height: 20 + animated: true + enabled: false + } + + PlasmaComponents.Label { text: "Inverted Horizontal Slider" } + + PlasmaComponents.Slider { + id: invHorizontalSlider + width: 140 + height: 20 inverted: true animated: true + enabled: true } - PlasmaComponents.Label { text: verticalSlider.value } - } + PlasmaComponents.Label { text: "Vertical Slider" } + + Row { + spacing: 30 + PlasmaComponents.Slider { + id: verticalSlider + width: 20 + height: 140 + orientation: Qt.Vertical + minimumValue: 10 + maximumValue: 1000 + stepSize: 50 + inverted: true + animated: true + } + PlasmaComponents.Label { text: verticalSlider.value } + } + + } } diff --git a/declarativeimports/test/gallery/Texts.qml b/declarativeimports/test/gallery/Texts.qml index ae3d0df48..1b0f4fc46 100644 --- a/declarativeimports/test/gallery/Texts.qml +++ b/declarativeimports/test/gallery/Texts.qml @@ -20,80 +20,97 @@ import QtQuick 1.1 import org.kde.plasma.components 0.1 as PlasmaComponents -Column { - spacing: 30 - Text { - text: "Text Fields" - font.pixelSize: 20 - } +PlasmaComponents.Page { + height: childrenRect.height + property int implicitHeight: childrenRect.height - PlasmaComponents.Highlight { - width: 200 - height: 100 - Column { - spacing: 10 - Row { - Text { - text: "Username: " - anchors.verticalCenter: tf1.verticalCenter - } - PlasmaComponents.TextField { - id: tf1 - placeholderText: "login" - Keys.onTabPressed: tf2.forceActiveFocus(); - } - } - - Row { - Text { - text: "Password: " - anchors.verticalCenter: tf2.verticalCenter - } - PlasmaComponents.TextField { - id: tf2 - width: 120 - echoMode: TextInput.Password - Keys.onTabPressed: loginButton.forceActiveFocus(); - } - } - - PlasmaComponents.Button { - id: loginButton - text: "Login" - anchors { - right: parent.right - rightMargin: 0 - } - width: 100 - } + tools: PlasmaComponents.ToolBarLayout { + spacing: 5 + PlasmaComponents.ToolButton { + text: "ToolButton" + } + PlasmaComponents.TextField { + placeholderText: "Place holder text" + } + PlasmaComponents.TextField { + text: "Text fields page" } } + Column { + spacing: 30 + Text { + text: "Text Fields" + font.pixelSize: 20 + } - PlasmaComponents.TextField { - width: 120 - placeholderText: "Disabled Text Field" - Keys.onTabPressed: loginButton.forceActiveFocus(); - enabled: false - } + PlasmaComponents.Highlight { + width: 200 + height: 100 + Column { + spacing: 10 + Row { + Text { + text: "Username: " + anchors.verticalCenter: tf1.verticalCenter + } + PlasmaComponents.TextField { + id: tf1 + placeholderText: "login" + Keys.onTabPressed: tf2.forceActiveFocus(); + } + } - Text { - text: "Text Area" - font.pixelSize: 20 - } + Row { + Text { + text: "Password: " + anchors.verticalCenter: tf2.verticalCenter + } + PlasmaComponents.TextField { + id: tf2 + width: 120 + echoMode: TextInput.Password + Keys.onTabPressed: loginButton.forceActiveFocus(); + } + } - PlasmaComponents.TextArea { - width: 200 - height: 200 - placeholderText: "Lorem ipsum et dolor" - wrapMode: TextEdit.WordWrap - contentMaxWidth: 400 - contentMaxHeight: 400 - } + PlasmaComponents.Button { + id: loginButton + text: "Login" + anchors { + right: parent.right + rightMargin: 0 + } + width: 100 + } + } + } - PlasmaComponents.TextArea { - width: 200 - height: 100 - enabled: false - text: "Disabled Text Area" + PlasmaComponents.TextField { + width: 120 + placeholderText: "Disabled Text Field" + Keys.onTabPressed: loginButton.forceActiveFocus(); + enabled: false + } + + Text { + text: "Text Area" + font.pixelSize: 20 + } + + PlasmaComponents.TextArea { + width: 200 + height: 200 + placeholderText: "Lorem ipsum et dolor" + wrapMode: TextEdit.WordWrap + contentMaxWidth: 400 + contentMaxHeight: 400 + } + + PlasmaComponents.TextArea { + width: 200 + height: 100 + enabled: false + text: "Disabled Text Area" + } } } From c2e980fa11ef0befbbe7e59c6ddbfa6ccfb3c0f3 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 22:06:25 +0100 Subject: [PATCH 60/87] center the text --- declarativeimports/plasmacomponents/qml/TextField.qml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml index ed644f126..a5148028e 100644 --- a/declarativeimports/plasmacomponents/qml/TextField.qml +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -112,7 +112,13 @@ Item { } Text { - anchors.fill: textInput + anchors { + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + leftMargin: 2 * base.margins.left + rightMargin: 2 * base.margins.right + } text: placeholderText visible: textInput.text == "" && !textField.activeFocus // XXX: using textColor and low opacity for theming placeholderText @@ -143,8 +149,6 @@ Item { rightMargin: 2 * base.margins.right } selectByMouse: true - y: (height - font.pixelSize) * 0.4 // XXX: verticalCenter anchor is not centering the text - height: Math.min(2 * font.pixelSize, parent.height) color: theme.textColor enabled: textField.enabled clip: true From 0c2995f8e84e72966aee7824ae75cfa443d912e0 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 22:31:39 +0100 Subject: [PATCH 61/87] give typical items the same (font based) height this way everything will look exactly vertically aligned --- declarativeimports/plasmacomponents/qml/Button.qml | 4 ++-- declarativeimports/plasmacomponents/qml/DualStateButton.qml | 2 +- declarativeimports/plasmacomponents/qml/Label.qml | 3 +++ declarativeimports/plasmacomponents/qml/Slider.qml | 4 ++-- declarativeimports/plasmacomponents/qml/TextField.qml | 4 ++-- declarativeimports/plasmacomponents/qml/ToolBar.qml | 2 +- declarativeimports/plasmacomponents/qml/ToolButton.qml | 4 ++-- declarativeimports/test/gallery/Texts.qml | 3 +++ 8 files changed, 16 insertions(+), 10 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index 1c389e09e..cb5716448 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -35,8 +35,8 @@ Item { signal clicked() - width: Math.max(50, icon.width + label.paintedWidth + surfaceNormal.margins.left + surfaceNormal.margins.right) + ((icon.valid) ? surfaceNormal.margins.left : 0); - height: Math.max(20, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom) + width: Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surfaceNormal.margins.left + surfaceNormal.margins.right) + ((icon.valid) ? surfaceNormal.margins.left : 0); + height: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom) // TODO: needs to define if there will be specific graphics for // disabled buttons diff --git a/declarativeimports/plasmacomponents/qml/DualStateButton.qml b/declarativeimports/plasmacomponents/qml/DualStateButton.qml index a4b81d359..c4427963a 100644 --- a/declarativeimports/plasmacomponents/qml/DualStateButton.qml +++ b/declarativeimports/plasmacomponents/qml/DualStateButton.qml @@ -35,7 +35,7 @@ Item { property alias shadow: shadowLoader.sourceComponent width: surfaceLoader.width + label.paintedWidth - height: surfaceLoader.height + height: theme.defaultFont.mSize.height*1.8 // TODO: needs to define if there will be specific graphics for // disabled buttons opacity: dualButton.enabled ? 1.0 : 0.5 diff --git a/declarativeimports/plasmacomponents/qml/Label.qml b/declarativeimports/plasmacomponents/qml/Label.qml index e52dc59e0..9fd941dae 100644 --- a/declarativeimports/plasmacomponents/qml/Label.qml +++ b/declarativeimports/plasmacomponents/qml/Label.qml @@ -23,6 +23,9 @@ import org.kde.plasma.core 0.1 as PlasmaCore Text { id: root + height: theme.defaultFont.mSize.height*1.8 + verticalAlignment: Text.AlignVCenter + font.capitalization: theme.defaultFont.capitalization font.family: theme.defaultFont.family font.italic: theme.defaultFont.italic diff --git a/declarativeimports/plasmacomponents/qml/Slider.qml b/declarativeimports/plasmacomponents/qml/Slider.qml index 0c82ccbb2..49f9e59da 100644 --- a/declarativeimports/plasmacomponents/qml/Slider.qml +++ b/declarativeimports/plasmacomponents/qml/Slider.qml @@ -43,8 +43,8 @@ Item { // Convenience API property bool _isVertical: orientation == Qt.Vertical - width: _isVertical ? 22 : 200 - height: _isVertical ? 200 : 22 + width: _isVertical ? theme.defaultFont.mSize.height*1.8 : 200 + height: _isVertical ? 200 : theme.defaultFont.mSize.height*1.8 // TODO: needs to define if there will be specific graphics for // disabled sliders opacity: enabled ? 1.0 : 0.5 diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml index a5148028e..5534b1cde 100644 --- a/declarativeimports/plasmacomponents/qml/TextField.qml +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -84,8 +84,8 @@ Item { property alias activeFocus: textInput.activeFocus // TODO: fix default size - implicitWidth: 100 - implicitHeight: 26 + implicitWidth: theme.defaultFont.mSize.width*12 + implicitHeight: theme.defaultFont.mSize.height*1.8 // TODO: needs to define if there will be specific graphics for // disabled text fields opacity: enabled ? 1.0 : 0.5 diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index d942571a9..4604d1c72 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -23,7 +23,7 @@ import org.kde.plasma.core 0.1 as PlasmaCore Item{ id: toolBar width: parent.width - height: 48 + frameSvg.margins.top + frameSvg.margins.bottom + height: theme.defaultFont.mSize.height*2 + frameSvg.margins.top + frameSvg.margins.bottom // The current set of tools; null if none. property Item tools diff --git a/declarativeimports/plasmacomponents/qml/ToolButton.qml b/declarativeimports/plasmacomponents/qml/ToolButton.qml index f135e6047..090a8601c 100644 --- a/declarativeimports/plasmacomponents/qml/ToolButton.qml +++ b/declarativeimports/plasmacomponents/qml/ToolButton.qml @@ -41,8 +41,8 @@ Item { } - implicitWidth: Math.max(50, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) - implicitHeight: Math.max(20, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) + implicitWidth: Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) + ((icon.valid) ? surface.margins.left : 0); + implicitHeight: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) // TODO: needs to define if there will be specific graphics for // disabled buttons diff --git a/declarativeimports/test/gallery/Texts.qml b/declarativeimports/test/gallery/Texts.qml index 1b0f4fc46..53c3993a7 100644 --- a/declarativeimports/test/gallery/Texts.qml +++ b/declarativeimports/test/gallery/Texts.qml @@ -26,6 +26,9 @@ PlasmaComponents.Page { tools: PlasmaComponents.ToolBarLayout { spacing: 5 + PlasmaComponents.Label { + text: "Text label:" + } PlasmaComponents.ToolButton { text: "ToolButton" } From e4c44a117e594d5e60df1600bb0ffd4a747c44f1 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 23:25:31 +0100 Subject: [PATCH 62/87] vertical centering only if there is more than one line --- declarativeimports/plasmacomponents/qml/Label.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/Label.qml b/declarativeimports/plasmacomponents/qml/Label.qml index 9fd941dae..dca9f70bb 100644 --- a/declarativeimports/plasmacomponents/qml/Label.qml +++ b/declarativeimports/plasmacomponents/qml/Label.qml @@ -24,7 +24,7 @@ Text { id: root height: theme.defaultFont.mSize.height*1.8 - verticalAlignment: Text.AlignVCenter + verticalAlignment: lineCount > 1 ? Text.AlignTop : Text.AlignVCenter font.capitalization: theme.defaultFont.capitalization font.family: theme.defaultFont.family From 96a7efd027e1427de63754c9e0b760a40e8f4d69 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 9 Nov 2011 23:31:52 +0100 Subject: [PATCH 63/87] square toolbuttons if without text --- declarativeimports/plasmacomponents/qml/ToolButton.qml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolButton.qml b/declarativeimports/plasmacomponents/qml/ToolButton.qml index 090a8601c..e582b7023 100644 --- a/declarativeimports/plasmacomponents/qml/ToolButton.qml +++ b/declarativeimports/plasmacomponents/qml/ToolButton.qml @@ -41,7 +41,13 @@ Item { } - implicitWidth: Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) + ((icon.valid) ? surface.margins.left : 0); + implicitWidth: { + if (label.paintedWidth == 0) { + return implicitHeight + } else { + return Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) + ((icon.valid) ? surface.margins.left : 0) + } + } implicitHeight: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) // TODO: needs to define if there will be specific graphics for From 8072396cbe6f2ae6fa7e4970311936f759fe8b12 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 11:32:19 +0100 Subject: [PATCH 64/87] add a comment to clarify what's going on there with the overwriting of installed files --- declarativeimports/plasmacomponents/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/declarativeimports/plasmacomponents/CMakeLists.txt b/declarativeimports/plasmacomponents/CMakeLists.txt index c7e2b6f92..f855e3b3e 100644 --- a/declarativeimports/plasmacomponents/CMakeLists.txt +++ b/declarativeimports/plasmacomponents/CMakeLists.txt @@ -28,6 +28,7 @@ install(DIRECTORY qml/ DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/compone #The platform specific stuff, overwrites a copy of the desktop one +#it does install some files on top of the old ones, it's pretty hackyu but it's intended since there are no more elegant ways to produce a fallback during a qml import from the most specific files to the general ones if specific were not found install(TARGETS plasmacomponentsplugin DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) install(DIRECTORY qml/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) From a5878df083ae9ad9f54643eb35722191195b18d2 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 12:07:25 +0100 Subject: [PATCH 65/87] layout fixes, behave differently on touch --- .../plasmacomponents/qml/TextArea.qml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/TextArea.qml b/declarativeimports/plasmacomponents/qml/TextArea.qml index f4ccddacc..6b229a554 100644 --- a/declarativeimports/plasmacomponents/qml/TextArea.qml +++ b/declarativeimports/plasmacomponents/qml/TextArea.qml @@ -76,7 +76,6 @@ Item { property alias interactive: flickArea.interactive property alias contentMaxWidth: textEdit.width property alias contentMaxHeight: textEdit.height - property real scrollWidth: 22 // Set active focus to it's internal textInput. // Overriding QtQuick.Item forceActiveFocus function. @@ -106,11 +105,7 @@ Item { // TODO: see what is the best policy for margins anchors { - fill: flickArea - leftMargin: -2 * base.margins.left - rightMargin: -2 * base.margins.right - topMargin: -2 * base.margins.top - bottomMargin: -2 * base.margins.bottom + fill: parent } imagePath: "widgets/lineedit" prefix: "base" @@ -120,10 +115,12 @@ Item { id: flickArea anchors { fill: parent - rightMargin: scrollWidth - bottomMargin: scrollWidth + leftMargin: 2 * base.margins.left + rightMargin: 2 * base.margins.right + (verticalScroll.visible ? verticalScroll.width : 0) + topMargin: 2 * base.margins.top + bottomMargin: 2 * base.margins.bottom + (horizontalScroll.visible ? verticalScroll.width : 0) } - interactive: false //textArea.activeFocus + interactive: !verticalScroll.interactive //textArea.activeFocus contentWidth: { if (textEdit.wrapMode == TextEdit.NoWrap) return textEdit.paintedWidth; @@ -151,7 +148,7 @@ Item { font.weight: theme.defaultFont.weight font.wordSpacing: theme.defaultFont.wordSpacing color: theme.viewTextColor - selectByMouse: true + selectByMouse: verticalScroll.interactive onCursorPositionChanged: { if (cursorRectangle.x < flickArea.contentX) { @@ -202,7 +199,6 @@ Item { } enabled: parent.enabled flickableItem: flickArea - height: visible ? scrollWidth : 0 orientation: Qt.Horizontal stepSize: textEdit.font.pixelSize } @@ -216,7 +212,6 @@ Item { } enabled: parent.enabled flickableItem: flickArea - width: visible ? scrollWidth : 0 orientation: Qt.Vertical stepSize: textEdit.font.pixelSize } From 7da0aaecfdf860b580daf71426ab61e2998c5043 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 12:45:31 +0100 Subject: [PATCH 66/87] workaround for not having qtquick 1.1 use paintedHeight instead of lineCount --- declarativeimports/plasmacomponents/qml/Label.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/Label.qml b/declarativeimports/plasmacomponents/qml/Label.qml index dca9f70bb..b227d9617 100644 --- a/declarativeimports/plasmacomponents/qml/Label.qml +++ b/declarativeimports/plasmacomponents/qml/Label.qml @@ -24,7 +24,8 @@ Text { id: root height: theme.defaultFont.mSize.height*1.8 - verticalAlignment: lineCount > 1 ? Text.AlignTop : Text.AlignVCenter + //FIXME: wait to rely on 1.1 for lineCount > 1 + verticalAlignment: paintedHeight > theme.defaultFont.mSize.height*1.5 ? Text.AlignTop : Text.AlignVCenter font.capitalization: theme.defaultFont.capitalization font.family: theme.defaultFont.family From 7b45e4e529e6ed3511181a4c6a09aadb93ae23a0 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 14:14:16 +0100 Subject: [PATCH 67/87] animate toolbar hide when shown --- .../plasmacomponents/qml/ToolBar.qml | 127 +++++++++--------- 1 file changed, 67 insertions(+), 60 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 4604d1c72..31e1c98b7 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -23,7 +23,11 @@ import org.kde.plasma.core 0.1 as PlasmaCore Item{ id: toolBar width: parent.width - height: theme.defaultFont.mSize.height*2 + frameSvg.margins.top + frameSvg.margins.bottom + height: (tools && enabled) ? theme.defaultFont.mSize.height*2 + frameSvg.margins.top + frameSvg.margins.bottom : 0 + visible: height > 0 + Behavior on height { + PropertyAnimation { duration: 250 } + } // The current set of tools; null if none. property Item tools @@ -45,66 +49,69 @@ Item{ toolBar.transition = transition toolBar.tools = tools } - onToolsChanged: { - var newContainer - var oldContainer - if (containerA.current) { - newContainer = containerB - oldContainer = containerA - } else { - newContainer = containerA - oldContainer = containerB + Connections { + target: toolBar + onToolsChanged: { + var newContainer + var oldContainer + if (containerA.current) { + newContainer = containerB + oldContainer = containerA + } else { + newContainer = containerA + oldContainer = containerB + } + containerA.current = !containerA.current + + tools.parent = newContainer + tools.visible = true + tools.anchors.left = newContainer.left + tools.anchors.right = newContainer.right + tools.anchors.verticalCenter = newContainer.verticalCenter + + switch (transition) { + case "push": + containerA.animationsEnabled = true + oldContainer.x = -oldContainer.width/2 + + containerA.animationsEnabled = false + newContainer.x = newContainer.width/2 + newContainer.y = 0 + containerA.animationsEnabled = true + newContainer.x = 0 + break + case "pop": + containerA.animationsEnabled = true + oldContainer.x = oldContainer.width/2 + + containerA.animationsEnabled = false + newContainer.x = -newContainer.width/2 + newContainer.y = 0 + containerA.animationsEnabled = true + newContainer.x = 0 + break + case "replace": + containerA.animationsEnabled = true + oldContainer.y = oldContainer.height + + containerA.animationsEnabled = false + newContainer.x = 0 + newContainer.y = -newContainer.height + containerA.animationsEnabled = true + newContainer.y = 0 + break + case "set": + default: + containerA.animationsEnabled = false + containerA.animationsEnabled = false + oldContainer.x = -oldContainer.width/2 + newContainer.x = 0 + break + } + + newContainer.opacity = 1 + oldContainer.opacity = 0 } - containerA.current = !containerA.current - - tools.parent = newContainer - tools.visible = true - tools.anchors.left = newContainer.left - tools.anchors.right = newContainer.right - tools.anchors.verticalCenter = newContainer.verticalCenter - - switch (transition) { - case "push": - containerA.animationsEnabled = true - oldContainer.x = -oldContainer.width/2 - - containerA.animationsEnabled = false - newContainer.x = newContainer.width/2 - newContainer.y = 0 - containerA.animationsEnabled = true - newContainer.x = 0 - break - case "pop": - containerA.animationsEnabled = true - oldContainer.x = oldContainer.width/2 - - containerA.animationsEnabled = false - newContainer.x = -newContainer.width/2 - newContainer.y = 0 - containerA.animationsEnabled = true - newContainer.x = 0 - break - case "replace": - containerA.animationsEnabled = true - oldContainer.y = oldContainer.height - - containerA.animationsEnabled = false - newContainer.x = 0 - newContainer.y = -newContainer.height - containerA.animationsEnabled = true - newContainer.y = 0 - break - case "set": - default: - containerA.animationsEnabled = false - containerA.animationsEnabled = false - oldContainer.x = -oldContainer.width/2 - newContainer.x = 0 - break - } - - newContainer.opacity = 1 - oldContainer.opacity = 0 } PlasmaCore.FrameSvgItem { From 63eb84ce806c339aae8f28280c08b11c57a0163d Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 14:27:35 +0100 Subject: [PATCH 68/87] left text alignment if icon --- declarativeimports/plasmacomponents/qml/Button.qml | 2 +- declarativeimports/plasmacomponents/qml/ToolButton.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index cb5716448..fb24e00cf 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -183,7 +183,7 @@ Item { font.weight: theme.defaultFont.weight font.wordSpacing: theme.defaultFont.wordSpacing color: theme.buttonTextColor - horizontalAlignment: Text.AlignHCenter + horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } diff --git a/declarativeimports/plasmacomponents/qml/ToolButton.qml b/declarativeimports/plasmacomponents/qml/ToolButton.qml index e582b7023..1b739ec9f 100644 --- a/declarativeimports/plasmacomponents/qml/ToolButton.qml +++ b/declarativeimports/plasmacomponents/qml/ToolButton.qml @@ -154,7 +154,7 @@ Item { font.weight: theme.defaultFont.weight font.wordSpacing: theme.defaultFont.wordSpacing color: theme.buttonTextColor - horizontalAlignment: Text.AlignHCenter + horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } From 9303301e838e5aac7b9204b91ada66b06512ba0a Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 14:29:39 +0100 Subject: [PATCH 69/87] square button if icon only --- declarativeimports/plasmacomponents/qml/Button.qml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index fb24e00cf..1f75caa3a 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -35,7 +35,13 @@ Item { signal clicked() - width: Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surfaceNormal.margins.left + surfaceNormal.margins.right) + ((icon.valid) ? surfaceNormal.margins.left : 0); + width: { + if (label.paintedWidth == 0) { + return height + } else { + return Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surfaceNormal.margins.left + surfaceNormal.margins.right) + ((icon.valid) ? surfaceNormal.margins.left : 0) + } + } height: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom) // TODO: needs to define if there will be specific graphics for From 9302b15079f5618e5f919ffc4ef1b9086f27578e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 14:50:04 +0100 Subject: [PATCH 70/87] enormous default Z --- declarativeimports/plasmacomponents/qml/ToolBar.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 31e1c98b7..90282d53b 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -28,6 +28,7 @@ Item{ Behavior on height { PropertyAnimation { duration: 250 } } + z: 1000 // The current set of tools; null if none. property Item tools From 580c5540fa304e439a4889a0223c779b9d2ccdd6 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 15:52:26 +0100 Subject: [PATCH 71/87] use KDE_PLASMA_COMPONENTS_PLATFORM --- .../plasmacomponents/plasmacomponentsplugin.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index ccca36ac7..b1bee475e 100644 --- a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -35,8 +35,11 @@ void PlasmaComponentsPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.plasma.components")); - KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform"); - const QString componentsPlatform = cg.readEntry("name", "desktop"); + QString componentsPlatform = getenv("KDE_PLASMA_COMPONENTS_PLATFORM"); + if (componentsPlatform.isEmpty()) { + KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform"); + componentsPlatform = cg.readEntry("name", "desktop"); + } if (componentsPlatform == "desktop") { qmlRegisterType(uri, 0, 1, "QueryDialog"); From 81382871613e83dc586071c86e99e5055fca3a52 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 16:21:42 +0100 Subject: [PATCH 72/87] layout fixes --- .../plasmacomponents/qml/ToolBar.qml | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 90282d53b..701ce1133 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -123,19 +123,20 @@ Item{ fill: parent leftMargin: -margins.left rightMargin: -margins.right - topMargin: toolBar.y <= 0 ? -margins.top : 0 - bottomMargin: toolBar.y >= toolBar.parent.height - toolBar.height ? -margins.bottom : 0 + //FIXME: difference between actial border and shadow + topMargin: toolBar.y <= 0 ? -margins.top : -margins.top/2 + bottomMargin: toolBar.y >= toolBar.parent.height - toolBar.height ? -margins.bottom : -margins.bottom/2 } } Item { - clip: true + clip: containerAOpacityAnimation.running anchors { fill: parent - leftMargin: parent.margins.left - topMargin: parent.margins.top - rightMargin: parent.margins.right - bottomMargin: parent.margins.bottom + leftMargin: frameSvg.margins.left/2 + topMargin: frameSvg.margins.top/2 + rightMargin: frameSvg.margins.right/2 + bottomMargin: frameSvg.margins.bottom/2 } Item { @@ -147,7 +148,10 @@ Item{ //this asymmetry just to not export a property property bool current: false Behavior on opacity { - PropertyAnimation { duration: 250 } + PropertyAnimation { + id: containerAOpacityAnimation + duration: 250 + } } Behavior on x { enabled: containerA.animationsEnabled From d19932168f214921fad636ec0fc1f561b32fc2c0 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 16:52:55 +0100 Subject: [PATCH 73/87] turn the clip on on appear/disappear animation --- declarativeimports/plasmacomponents/qml/ToolBar.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 701ce1133..9b1a29ba0 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -26,7 +26,10 @@ Item{ height: (tools && enabled) ? theme.defaultFont.mSize.height*2 + frameSvg.margins.top + frameSvg.margins.bottom : 0 visible: height > 0 Behavior on height { - PropertyAnimation { duration: 250 } + PropertyAnimation { + id: heightAnimation + duration: 250 + } } z: 1000 @@ -130,7 +133,7 @@ Item{ } Item { - clip: containerAOpacityAnimation.running + clip: containerAOpacityAnimation.running || heightAnimation.running anchors { fill: parent leftMargin: frameSvg.margins.left/2 From 96512897c730acdadfb39e32d56e4afaa270ecc5 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 10 Nov 2011 17:23:51 +0100 Subject: [PATCH 74/87] fix the slider shadow --- declarativeimports/plasmacomponents/qml/Slider.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/Slider.qml b/declarativeimports/plasmacomponents/qml/Slider.qml index 49f9e59da..da2c31908 100644 --- a/declarativeimports/plasmacomponents/qml/Slider.qml +++ b/declarativeimports/plasmacomponents/qml/Slider.qml @@ -147,7 +147,7 @@ Item { focusElement: "horizontal-slider-focus" hoverElement: "horizontal-slider-hover" shadowElement: "horizontal-slider-shadow" - state: slider.activeFocus ? "focus" : (mouseArea.containsMouse ? "hover" : "hidden") + state: slider.activeFocus ? "focus" : (mouseArea.containsMouse ? "hover" : "shadow") anchors.fill: handle } From a481b9a7cd66592bc483a2452380ed7bedb52391 Mon Sep 17 00:00:00 2001 From: Valentin Rusu Date: Fri, 11 Nov 2011 00:06:46 +0100 Subject: [PATCH 75/87] Merge branch 'master' of ../ksecretservice.move From ca2e34e48e9d6746e44d17c8cd5e3464d464a317 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 11:16:20 +0100 Subject: [PATCH 76/87] more spacing --- declarativeimports/plasmacomponents/qml/TabBar.qml | 2 +- declarativeimports/plasmacomponents/qml/TabBarLayout.qml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/TabBar.qml b/declarativeimports/plasmacomponents/qml/TabBar.qml index f87f84781..1c17404b8 100644 --- a/declarativeimports/plasmacomponents/qml/TabBar.qml +++ b/declarativeimports/plasmacomponents/qml/TabBar.qml @@ -51,7 +51,7 @@ Item { //Plasma extension property Item currentItem - implicitWidth: tabBarLayout.implicitWidth + backgroundFrame.margins.left + backgroundFrame.margins.right + buttonFrame.margins.left + buttonFrame.margins.right + implicitWidth: tabBarLayout.implicitWidth + backgroundFrame.margins.left + backgroundFrame.margins.right + (buttonFrame.margins.left + buttonFrame.margins.right)*tabBarLayout.children.length implicitHeight: tabBarLayout.implicitHeight + backgroundFrame.margins.top + backgroundFrame.margins.bottom + buttonFrame.margins.top + buttonFrame.margins.bottom PlasmaCore.FrameSvgItem { diff --git a/declarativeimports/plasmacomponents/qml/TabBarLayout.qml b/declarativeimports/plasmacomponents/qml/TabBarLayout.qml index 8077be30c..66b49db48 100644 --- a/declarativeimports/plasmacomponents/qml/TabBarLayout.qml +++ b/declarativeimports/plasmacomponents/qml/TabBarLayout.qml @@ -92,19 +92,19 @@ Item { var contentWidth = 0 var contentHeight = 0 if (childCount != 0) { - var itemWidth = root.width / childCount + var itemWidth = (root.width - (childCount-1)*10) / childCount var itemIndex = mirrored ? childCount - 1 : 0 var increment = mirrored ? - 1 : 1 for (var i = 0; i < childCount; ++i, itemIndex += increment) { var child = root.children[itemIndex] - child.x = i * itemWidth + child.x = i * itemWidth + i*10 child.y = 0 child.width = itemWidth child.height = root.height if (child.implicitWidth != undefined) { - contentWidth = Math.max(contentWidth, (child.implicitWidth + buttonFrame.margins.left*2 + buttonFrame.margins.right*2) * childCount) + contentWidth = Math.max(contentWidth + i*10, (child.implicitWidth + buttonFrame.margins.left*2 + buttonFrame.margins.right*2) * childCount) contentHeight = Math.max(contentHeight, (child.implicitHeight + buttonFrame.margins.top + buttonFrame.margins.bottom)) } } From a347b2ec049c74cde52eb0b190a58fd9a183189f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 14:36:36 +0100 Subject: [PATCH 77/87] plasma looking progressbars by tiling qpixmapitems --- .../plasmacomponents/qml/ProgressBar.qml | 63 ++++++++++++++----- .../qtextracomponents/qpixmapitem.cpp | 58 ++++++++++++++++- .../qtextracomponents/qpixmapitem.h | 16 +++++ 3 files changed, 118 insertions(+), 19 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ProgressBar.qml b/declarativeimports/plasmacomponents/qml/ProgressBar.qml index efce6f20f..3de9d919a 100644 --- a/declarativeimports/plasmacomponents/qml/ProgressBar.qml +++ b/declarativeimports/plasmacomponents/qml/ProgressBar.qml @@ -19,6 +19,7 @@ import QtQuick 1.0 import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.qtextracomponents 0.1 Item { id: progressBar @@ -32,9 +33,6 @@ Item { // Plasma API property int orientation: Qt.Horizontal - // Convinience API - property bool _isVertical: orientation == Qt.Vertical - width: 100 height: 20 opacity: enabled ? 1.0 : 0.5 @@ -54,26 +52,57 @@ Item { Item { id: contents + property bool _isVertical: orientation == Qt.Vertical + width: _isVertical ? progressBar.height : progressBar.width height: _isVertical ? progressBar.width : progressBar.height rotation: _isVertical ? 90 : 0 anchors.centerIn: parent - PlasmaCore.FrameSvgItem { - id: background - - anchors.fill: parent - imagePath: "widgets/bar_meter_horizontal" - prefix: "bar-inactive" + Timer { + id: resizeTimer + repeat: false + interval: 0 + running: false + onTriggered: { + barFrameSvg.resizeFrame(Qt.size(Math.floor(contents.height/1.6), contents.height)) + barPixmapItem.pixmap = barFrameSvg.framePixmap() + backgroundFrameSvg.resizeFrame(Qt.size(Math.floor(contents.height/1.6), contents.height)) + backgroundPixmapItem.pixmap = backgroundFrameSvg.framePixmap() + } + } + PlasmaCore.FrameSvg { + id: barFrameSvg + Component.onCompleted: { + barFrameSvg.setImagePath("widgets/bar_meter_horizontal") + barFrameSvg.setElementPrefix("bar-active") + resizeTimer.restart() + } + } + PlasmaCore.FrameSvg { + id: backgroundFrameSvg + Component.onCompleted: { + backgroundFrameSvg.setImagePath("widgets/bar_meter_horizontal") + backgroundFrameSvg.setElementPrefix("bar-inactive") + resizeTimer.restart() + } + } + QPixmapItem { + id: backgroundPixmapItem + fillMode: QPixmapItem.Tile + width: Math.floor(parent.width/(height/1.6))*Math.floor(height/1.6) + height: parent.height + onWidthChanged: resizeTimer.restart() + onHeightChanged: resizeTimer.restart() } - PlasmaCore.FrameSvgItem { - id: bar - width: indeterminate ? contents.width / 4 : range.position + QPixmapItem { + id: barPixmapItem + fillMode: QPixmapItem.Tile + width: indeterminate ? Math.floor(height/1.6)*2 : range.position height: contents.height - imagePath: "widgets/bar_meter_horizontal" - prefix: "bar-active" + visible: indeterminate || value > 0 SequentialAnimation { @@ -82,16 +111,16 @@ Item { loops: Animation.Infinite PropertyAnimation { - target: bar; + target: barPixmapItem property: "x" duration: 800 to: 0 } PropertyAnimation { - target: bar; + target: barPixmapItem property: "x" duration: 800 - to: background.width - bar.width + to: backgroundPixmapItem.width - barPixmapItem.width } } } diff --git a/declarativeimports/qtextracomponents/qpixmapitem.cpp b/declarativeimports/qtextracomponents/qpixmapitem.cpp index 3c09efec1..6fa784251 100644 --- a/declarativeimports/qtextracomponents/qpixmapitem.cpp +++ b/declarativeimports/qtextracomponents/qpixmapitem.cpp @@ -24,7 +24,8 @@ QPixmapItem::QPixmapItem(QDeclarativeItem *parent) : QDeclarativeItem(parent), - m_smooth(false) + m_smooth(false), + m_fillMode(QPixmapItem::Stretch) { setFlag(QGraphicsItem::ItemHasNoContents, false); } @@ -71,6 +72,22 @@ int QPixmapItem::nativeHeight() const return m_pixmap.size().height(); } +QPixmapItem::FillMode QPixmapItem::fillMode() const +{ + return m_fillMode; +} + +void QPixmapItem::setFillMode(QPixmapItem::FillMode mode) +{ + if (mode == m_fillMode) { + return; + } + + m_fillMode = mode; + update(); + emit fillModeChanged(); +} + void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); @@ -85,7 +102,44 @@ void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio painter->setRenderHint(QPainter::Antialiasing, m_smooth); painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); - painter->drawPixmap(boundingRect(), m_pixmap, m_pixmap.rect()); + QRect destRect; + switch (m_fillMode) { + case PreserveAspectFit: { + QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); + const qreal scale = qMin(m_pixmap.width()/minimumRect.width(), m_pixmap.height()/minimumRect.height()); + destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height()*scale)); + break; + } + case PreserveAspectCrop: { + QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); + const qreal scale = qMax(m_pixmap.width()/minimumRect.width(), m_pixmap.height()/minimumRect.height()); + destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height()*scale)); + break; + } + case TileVertically: { + QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); + const qreal scale = m_pixmap.width()/minimumRect.width(); + destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height())); + break; + } + case TileHorizontally: { + QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); + const qreal scale = m_pixmap.height()/minimumRect.height(); + destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width(), m_pixmap.height()*scale)); + break; + } + case Stretch: + case Tile: + default: + destRect = boundingRect().toRect(); + } + + if (m_fillMode >= Tile) { + painter->drawTiledPixmap(destRect, m_pixmap); + } else { + painter->drawPixmap(destRect, m_pixmap, m_pixmap.rect()); + } + painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); } diff --git a/declarativeimports/qtextracomponents/qpixmapitem.h b/declarativeimports/qtextracomponents/qpixmapitem.h index af2cc9ef0..ea91ac814 100644 --- a/declarativeimports/qtextracomponents/qpixmapitem.h +++ b/declarativeimports/qtextracomponents/qpixmapitem.h @@ -30,8 +30,19 @@ class QPixmapItem : public QDeclarativeItem Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged) Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged) + Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged) + Q_ENUMS(FillMode) public: + enum FillMode { + Stretch, // the image is scaled to fit + PreserveAspectFit, // the image is scaled uniformly to fit without cropping + PreserveAspectCrop, // the image is scaled uniformly to fill, cropping if necessary + Tile, // the image is duplicated horizontally and vertically + TileVertically, // the image is stretched horizontally and tiled vertically + TileHorizontally //the image is stretched vertically and tiled horizontally + }; + QPixmapItem(QDeclarativeItem *parent=0); ~QPixmapItem(); @@ -44,15 +55,20 @@ public: int nativeWidth() const; int nativeHeight() const; + FillMode fillMode() const; + void setFillMode(FillMode mode); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); Q_SIGNALS: void nativeWidthChanged(); void nativeHeightChanged(); + void fillModeChanged(); private: QPixmap m_pixmap; bool m_smooth; + FillMode m_fillMode; }; #endif From b5f6d6ff33853493749c762cd359bd6f27f32f4b Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 16:34:46 +0100 Subject: [PATCH 78/87] support all tiling options of Image --- .../qtextracomponents/qpixmapitem.cpp | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/declarativeimports/qtextracomponents/qpixmapitem.cpp b/declarativeimports/qtextracomponents/qpixmapitem.cpp index 6fa784251..690ed0f00 100644 --- a/declarativeimports/qtextracomponents/qpixmapitem.cpp +++ b/declarativeimports/qtextracomponents/qpixmapitem.cpp @@ -96,36 +96,36 @@ void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio if (m_pixmap.isNull()) { return; } - //do without painter save, faster and the support can be compiled out - const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing); - const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->save(); painter->setRenderHint(QPainter::Antialiasing, m_smooth); painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); QRect destRect; switch (m_fillMode) { case PreserveAspectFit: { - QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); - const qreal scale = qMin(m_pixmap.width()/minimumRect.width(), m_pixmap.height()/minimumRect.height()); - destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height()*scale)); + QSize scaled = m_pixmap.size(); + + scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatio); + destRect = QRect(QPoint(0, 0), scaled); break; } case PreserveAspectCrop: { - QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); - const qreal scale = qMax(m_pixmap.width()/minimumRect.width(), m_pixmap.height()/minimumRect.height()); - destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height()*scale)); + painter->setClipRect(boundingRect(), Qt::IntersectClip); + QSize scaled = m_pixmap.size(); + scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatioByExpanding); + destRect = QRect(QPoint(0, 0), scaled); break; } case TileVertically: { - QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); - const qreal scale = m_pixmap.width()/minimumRect.width(); - destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height())); + painter->scale(width()/(qreal)m_pixmap.width(), 1); + destRect = boundingRect().toRect(); + destRect.setWidth(destRect.width() / (width()/(qreal)m_pixmap.width())); break; } case TileHorizontally: { - QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect()); - const qreal scale = m_pixmap.height()/minimumRect.height(); - destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width(), m_pixmap.height()*scale)); + painter->scale(1, height()/(qreal)m_pixmap.height()); + destRect = boundingRect().toRect(); + destRect.setHeight(destRect.height() / (height()/(qreal)m_pixmap.height())); break; } case Stretch: @@ -140,8 +140,7 @@ void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio painter->drawPixmap(destRect, m_pixmap, m_pixmap.rect()); } - painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); - painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); + painter->restore(); } From 5880e5315c46a0372bbc2682756a5de7f2d5e62d Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 16:48:07 +0100 Subject: [PATCH 79/87] all the tiling option of Image --- .../qtextracomponents/qimageitem.cpp | 67 +++++++++++++++++-- .../qtextracomponents/qimageitem.h | 16 +++++ 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/declarativeimports/qtextracomponents/qimageitem.cpp b/declarativeimports/qtextracomponents/qimageitem.cpp index 086449d19..97eaec4c8 100644 --- a/declarativeimports/qtextracomponents/qimageitem.cpp +++ b/declarativeimports/qtextracomponents/qimageitem.cpp @@ -24,7 +24,8 @@ QImageItem::QImageItem(QDeclarativeItem *parent) : QDeclarativeItem(parent), - m_smooth(false) + m_smooth(false), + m_fillMode(QImageItem::Stretch) { setFlag(QGraphicsItem::ItemHasNoContents, false); } @@ -71,6 +72,22 @@ int QImageItem::nativeHeight() const return m_image.size().height(); } +QImageItem::FillMode QImageItem::fillMode() const +{ + return m_fillMode; +} + +void QImageItem::setFillMode(QImageItem::FillMode mode) +{ + if (mode == m_fillMode) { + return; + } + + m_fillMode = mode; + update(); + emit fillModeChanged(); +} + void QImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); @@ -79,15 +96,51 @@ void QImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option if (m_image.isNull()) { return; } - //do without painter save, faster and the support can be compiled out - const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing); - const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->save(); painter->setRenderHint(QPainter::Antialiasing, m_smooth); painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); - painter->drawImage(boundingRect(), m_image, m_image.rect()); - painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); - painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); + QRect destRect; + switch (m_fillMode) { + case PreserveAspectFit: { + QSize scaled = m_image.size(); + + scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatio); + destRect = QRect(QPoint(0, 0), scaled); + break; + } + case PreserveAspectCrop: { + painter->setClipRect(boundingRect(), Qt::IntersectClip); + QSize scaled = m_image.size(); + scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatioByExpanding); + destRect = QRect(QPoint(0, 0), scaled); + break; + } + case TileVertically: { + painter->scale(width()/(qreal)m_image.width(), 1); + destRect = boundingRect().toRect(); + destRect.setWidth(destRect.width() / (width()/(qreal)m_image.width())); + break; + } + case TileHorizontally: { + painter->scale(1, height()/(qreal)m_image.height()); + destRect = boundingRect().toRect(); + destRect.setHeight(destRect.height() / (height()/(qreal)m_image.height())); + break; + } + case Stretch: + case Tile: + default: + destRect = boundingRect().toRect(); + } + + if (m_fillMode >= Tile) { + painter->drawTiledPixmap(destRect, QPixmap::fromImage(m_image)); + } else { + painter->drawImage(destRect, m_image, m_image.rect()); + } + + painter->restore(); } diff --git a/declarativeimports/qtextracomponents/qimageitem.h b/declarativeimports/qtextracomponents/qimageitem.h index a4365b5dc..0c358ec71 100644 --- a/declarativeimports/qtextracomponents/qimageitem.h +++ b/declarativeimports/qtextracomponents/qimageitem.h @@ -30,8 +30,19 @@ class QImageItem : public QDeclarativeItem Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged) Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged) + Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged) + Q_ENUMS(FillMode) public: + enum FillMode { + Stretch, // the image is scaled to fit + PreserveAspectFit, // the image is scaled uniformly to fit without cropping + PreserveAspectCrop, // the image is scaled uniformly to fill, cropping if necessary + Tile, // the image is duplicated horizontally and vertically + TileVertically, // the image is stretched horizontally and tiled vertically + TileHorizontally //the image is stretched vertically and tiled horizontally + }; + QImageItem(QDeclarativeItem *parent=0); ~QImageItem(); @@ -44,15 +55,20 @@ public: int nativeWidth() const; int nativeHeight() const; + FillMode fillMode() const; + void setFillMode(FillMode mode); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); Q_SIGNALS: void nativeWidthChanged(); void nativeHeightChanged(); + void fillModeChanged(); private: QImage m_image; bool m_smooth; + FillMode m_fillMode; }; #endif From 60db3ff72da3f8055e13a682766b33a9b934652c Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 17:52:27 +0100 Subject: [PATCH 80/87] fix keyboard navigation --- declarativeimports/plasmacomponents/qml/Button.qml | 1 + declarativeimports/plasmacomponents/qml/TabBar.qml | 8 ++++---- declarativeimports/plasmacomponents/qml/TabBarLayout.qml | 7 +++++-- declarativeimports/plasmacomponents/qml/TabButton.qml | 6 +++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index 1f75caa3a..c4c521b8d 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -201,5 +201,6 @@ Item { hoverEnabled: true onPressed: internal.pressButton() onReleased: internal.releaseButton() + onCanceled: internal.releaseButton() } } \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/TabBar.qml b/declarativeimports/plasmacomponents/qml/TabBar.qml index 1c17404b8..9a1acb381 100644 --- a/declarativeimports/plasmacomponents/qml/TabBar.qml +++ b/declarativeimports/plasmacomponents/qml/TabBar.qml @@ -49,7 +49,7 @@ Item { property alias layout: tabBarLayout //Plasma extension - property Item currentItem + property Item currentTab implicitWidth: tabBarLayout.implicitWidth + backgroundFrame.margins.left + backgroundFrame.margins.right + (buttonFrame.margins.left + buttonFrame.margins.right)*tabBarLayout.children.length implicitHeight: tabBarLayout.implicitHeight + backgroundFrame.margins.top + backgroundFrame.margins.bottom + buttonFrame.margins.top + buttonFrame.margins.bottom @@ -65,10 +65,10 @@ Item { PlasmaCore.FrameSvgItem { id: buttonFrame - x: currentItem.x + backgroundFrame.margins.left + x: currentTab.x + backgroundFrame.margins.left y: backgroundFrame.margins.top - width: currentItem.width + buttonFrame.margins.left + buttonFrame.margins.right - height: currentItem.height + buttonFrame.margins.top + buttonFrame.margins.bottom + width: currentTab.width + buttonFrame.margins.left + buttonFrame.margins.right + height: currentTab.height + buttonFrame.margins.top + buttonFrame.margins.bottom imagePath: "widgets/button" prefix: "normal" Behavior on x { diff --git a/declarativeimports/plasmacomponents/qml/TabBarLayout.qml b/declarativeimports/plasmacomponents/qml/TabBarLayout.qml index 66b49db48..2602b1c1f 100644 --- a/declarativeimports/plasmacomponents/qml/TabBarLayout.qml +++ b/declarativeimports/plasmacomponents/qml/TabBarLayout.qml @@ -53,15 +53,18 @@ Item { Keys.onPressed: { if (event.key == Qt.Key_Right || event.key == Qt.Key_Left) { if (event.key == Qt.Key_Right || priv.mirrored) { - var oldIndex = priv.currentButtonIndex() + var oldIndex = priv.currentButtonIndex(); + if (oldIndex != root.children.length - 1) { priv.tabGroup.currentTab = root.children[oldIndex + 1].tab + root.parent.currentTab = root.children[oldIndex + 1] event.accepted = true } } else if (event.key == Qt.Key_Left || priv.mirrored) { var oldIndex = priv.currentButtonIndex() if (oldIndex != 0) { priv.tabGroup.currentTab = root.children[oldIndex - 1].tab + root.parent.currentTab = root.children[oldIndex - 1] event.accepted = true } } @@ -74,7 +77,7 @@ Item { id: priv property Item firstButton: root.children.length > 0 ? root.children[0] : null property Item firstTab: firstButton ? (firstButton.tab != null ? firstButton.tab : null) : null - property Item tabGroup: firstTab ? (firstTab.parent ? firstTab.parent.parent : null) : null + property Item tabGroup: firstTab ? (firstTab.parent ? firstTab.parent.parent.parent : null) : null property bool mirrored: root.LayoutMirroring.enabled onMirroredChanged: layoutChildren() diff --git a/declarativeimports/plasmacomponents/qml/TabButton.qml b/declarativeimports/plasmacomponents/qml/TabButton.qml index 74f97fd99..00ef0db75 100644 --- a/declarativeimports/plasmacomponents/qml/TabButton.qml +++ b/declarativeimports/plasmacomponents/qml/TabButton.qml @@ -63,7 +63,7 @@ Item { target: root onPressedChanged: { //TabBar is the granparent - root.parent.parent.currentItem = root + root.parent.parent.currentTab = root } } @@ -82,7 +82,7 @@ Item { Component.onCompleted: { if (internal.tabGroup.currentTab == tab) { - parent.parent.currentItem = root + parent.parent.currentTab = root } } } @@ -126,7 +126,7 @@ Item { internal.tabGroup.currentTab = tab } //TabBar is the granparent, done here too in case of no tabgroup - root.parent.parent.currentItem = root + root.parent.parent.currentTab = root } anchors.fill: parent From f44e697aab925c2b23056a02926b884049cb8a0f Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 18:01:59 +0100 Subject: [PATCH 81/87] fix painting --- declarativeimports/plasmacomponents/qml/BusyIndicator.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/BusyIndicator.qml b/declarativeimports/plasmacomponents/qml/BusyIndicator.qml index 5335d4328..c036b1117 100644 --- a/declarativeimports/plasmacomponents/qml/BusyIndicator.qml +++ b/declarativeimports/plasmacomponents/qml/BusyIndicator.qml @@ -54,11 +54,12 @@ Item { PlasmaCore.SvgItem { id: widget + svg: PlasmaCore.Svg { imagePath: "widgets/busywidget" } + elementId: "busywidget" anchors.centerIn: parent width: busy.width height: busy.height smooth: !running || smoothAnimation - svg: PlasmaCore.Svg { imagePath: "widgets/busywidget" } } } From 8c0f8f0e5a9e141d5cd9b95cfd86e42299d5c802 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 18:05:57 +0100 Subject: [PATCH 82/87] fix tooltip size --- .../platformcomponents/touch/SectionScroller.qml | 4 ++-- declarativeimports/plasmacomponents/qml/SectionScroller.qml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml index d93042c3b..0db1406f7 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml @@ -159,8 +159,8 @@ Item { } PlasmaCore.FrameSvgItem { imagePath: "widgets/tooltip" - width: childrenRect.width + margins.left + margins.right - height: childrenRect.height + margins.top + margins.bottom + width: sectionLabel.paintedWidth + margins.left + margins.right + height: sectionLabel.paintedHeight + margins.top + margins.bottom Label { id: sectionLabel font.pointSize: theme.defaultFont.pointSize*3 diff --git a/declarativeimports/plasmacomponents/qml/SectionScroller.qml b/declarativeimports/plasmacomponents/qml/SectionScroller.qml index 6ae7067a1..8aaddff69 100644 --- a/declarativeimports/plasmacomponents/qml/SectionScroller.qml +++ b/declarativeimports/plasmacomponents/qml/SectionScroller.qml @@ -110,8 +110,8 @@ Item { } PlasmaCore.FrameSvgItem { imagePath: "widgets/tooltip" - width: childrenRect.width + margins.left + margins.right - height: childrenRect.height + margins.top + margins.bottom + width: sectionLabel.paintedWidth + margins.left + margins.right + height: sectionLabel.paintedHeight + margins.top + margins.bottom Label { id: sectionLabel font.pointSize: theme.defaultFont.pointSize*3 From 9a0026969f5054ffaf4d90a6a698435549a3c439 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 14 Nov 2011 18:55:29 +0100 Subject: [PATCH 83/87] optional clear button in the lineedits --- .../plasmacomponents/qml/TextField.qml | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml index 5534b1cde..093bc1a2f 100644 --- a/declarativeimports/plasmacomponents/qml/TextField.qml +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -41,6 +41,9 @@ Item { property alias text: textInput.text property alias maximumLength: textInput.maximumLength + //Plasma api + property bool clearButtonShown: false + function copy() { textInput.copy(); } @@ -158,4 +161,30 @@ Item { Keys.onPressed: textField.Keys.pressed(event); Keys.onReleased: textField.Keys.released(event); } + + PlasmaCore.SvgItem { + svg: PlasmaCore.Svg {imagePath: "widgets/lineedit"} + elementId: "clearbutton" + width: textInput.height + height: textInput.height + opacity: (textInput.text != "" && clearButtonShown) ? 1 : 0 + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + anchors { + right: parent.right + rightMargin: y + verticalCenter: textInput.verticalCenter + } + MouseArea { + anchors.fill: parent + onClicked: { + textInput.text = "" + textInput.forceActiveFocus() + } + } + } } \ No newline at end of file From 4a10379637b7d3d3003a70c8ccac88626b1ceb29 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 15 Nov 2011 13:52:53 +0100 Subject: [PATCH 84/87] swap deletion to avoid a rare crash --- declarativeimports/core/dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/core/dialog.cpp b/declarativeimports/core/dialog.cpp index 45fb30413..57e9adecd 100644 --- a/declarativeimports/core/dialog.cpp +++ b/declarativeimports/core/dialog.cpp @@ -100,8 +100,8 @@ DialogProxy::DialogProxy(QObject *parent) DialogProxy::~DialogProxy() { - delete m_dialog; delete m_declarativeItemContainer; + delete m_dialog; } QGraphicsObject *DialogProxy::mainItem() const From f8ed323fab46b65b34fe3aa4da24fd3e0c321dc8 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 15 Nov 2011 15:54:55 +0100 Subject: [PATCH 85/87] fix immediate setting of tools --- declarativeimports/plasmacomponents/qml/ToolBar.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index 9b1a29ba0..28ccc779c 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -54,8 +54,10 @@ Item{ toolBar.tools = tools } Connections { + id: connection target: toolBar - onToolsChanged: { + function internalToolsChanged() + { var newContainer var oldContainer if (containerA.current) { @@ -116,6 +118,8 @@ Item{ newContainer.opacity = 1 oldContainer.opacity = 0 } + onToolsChanged: connection.internalToolsChanged() + Component.onCompleted: connection.internalToolsChanged() } PlasmaCore.FrameSvgItem { From cedf8f0075f901c01472c6f75ef665056e8c7a07 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 16 Nov 2011 11:05:22 +0100 Subject: [PATCH 86/87] resize when overshooting --- .../qml/ScrollDecoratorDelegate.qml | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml index 0532c56a9..2e9422bb0 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml @@ -48,10 +48,24 @@ PlasmaCore.FrameSvgItem { imagePath:"widgets/scrollbar" prefix: "slider" - property int length: internalLoader.isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width + function length() { + if (internalLoader.isVertical) { + var overshoot = 0 + if (flickableItem.atYBeginning || flickableItem.atYEnd) { + overshoot = Math.abs(flickableItem.visibleArea.yPosition * parent.height) + } + return (flickableItem.visibleArea.heightRatio * parent.height) - overshoot + } else { + var overshoot = 0 + if (flickableItem.atXBeginning || flickableItem.atXEnd) { + overshoot = Math.abs(flickableItem.visibleArea.xPosition * parent.width) + } + return (flickableItem.visibleArea.widthRatio * parent.width) - overshoot + } + } - width: internalLoader.isVertical ? parent.width : length - height: internalLoader.isVertical ? length : parent.height + width: internalLoader.isVertical ? parent.width : length() + height: internalLoader.isVertical ? length() : parent.height } } From b24cc1646ffaab7a0b2c0be8de5b183700ae04ce Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 16 Nov 2011 11:23:15 +0100 Subject: [PATCH 87/87] guard against a null scene --- declarativeimports/core/tooltip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/declarativeimports/core/tooltip.cpp b/declarativeimports/core/tooltip.cpp index 603bfd277..4eaa5b8fc 100644 --- a/declarativeimports/core/tooltip.cpp +++ b/declarativeimports/core/tooltip.cpp @@ -79,7 +79,7 @@ void ToolTipProxy::syncTarget() QObject *parent = m_target.data(); while ((parent = parent->parent())) { QGraphicsObject *qo = qobject_cast(parent); - if (qo) { + if (qo && qo->scene()) { scene = qo->scene(); scene->addItem(m_target.data()); break;