Merge branch 'master' into plasma-components-doc
This commit is contained in:
commit
72f52c5d29
@ -11,6 +11,7 @@ set(corebindings_SRCS
|
||||
framesvgitem.cpp
|
||||
dialog.cpp
|
||||
tooltip.cpp
|
||||
dataenginebindings.cpp
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
@ -23,7 +24,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)
|
||||
|
@ -23,17 +23,21 @@
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QDeclarativeContext>
|
||||
#include <QScriptEngine>
|
||||
|
||||
#include <kdeclarative.h>
|
||||
|
||||
#include <Plasma/FrameSvg>
|
||||
#include <Plasma/Svg>
|
||||
|
||||
#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"
|
||||
|
||||
void CoreBindingsPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)
|
||||
{
|
||||
@ -43,6 +47,19 @@ 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();
|
||||
|
||||
//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)
|
||||
|
66
declarativeimports/core/dataenginebindings.cpp
Normal file
66
declarativeimports/core/dataenginebindings.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2007 Richard J. Moore <rich@kde.org>
|
||||
*
|
||||
* 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<Plasma::Service *>(service), QScriptEngine::AutoOwnership, QScriptEngine::PreferExistingWrapperObject);
|
||||
}
|
||||
|
||||
void serviceFromQScriptValue(const QScriptValue &scriptValue, ServicePtr &service)
|
||||
{
|
||||
QObject *obj = scriptValue.toQObject();
|
||||
service = static_cast<Plasma::Service *>(obj);
|
||||
}
|
||||
|
||||
typedef Plasma::DataEngine *DataEnginePtr;
|
||||
QScriptValue qScriptValueFromDataEngine(QScriptEngine *engine, const DataEnginePtr &dataEngine)
|
||||
{
|
||||
return engine->newQObject(const_cast<Plasma::DataEngine *>(dataEngine), QScriptEngine::AutoOwnership, QScriptEngine::PreferExistingWrapperObject);
|
||||
}
|
||||
|
||||
void dataEngineFromQScriptValue(const QScriptValue &scriptValue, DataEnginePtr &dataEngine)
|
||||
{
|
||||
QObject *obj = scriptValue.toQObject();
|
||||
dataEngine = static_cast<Plasma::DataEngine *>(obj);
|
||||
}
|
||||
|
||||
typedef Plasma::ServiceJob *ServiceJobPtr;
|
||||
QScriptValue qScriptValueFromServiceJob(QScriptEngine *engine, const ServiceJobPtr &serviceJob)
|
||||
{
|
||||
return engine->newQObject(const_cast<Plasma::ServiceJob *>(serviceJob), QScriptEngine::AutoOwnership, QScriptEngine::PreferExistingWrapperObject);
|
||||
}
|
||||
|
||||
void serviceJobFromQScriptValue(const QScriptValue &scriptValue, ServiceJobPtr &serviceJob)
|
||||
{
|
||||
QObject *obj = scriptValue.toQObject();
|
||||
serviceJob = static_cast<Plasma::ServiceJob *>(obj);
|
||||
}
|
||||
|
||||
void registerDataEngineMetaTypes(QScriptEngine *engine)
|
||||
{
|
||||
qRegisterMetaType<Plasma::DataEngine::Data>("Plasma::DataEngine::Data");
|
||||
qRegisterMetaType<Plasma::DataEngine::Data>("DataEngine::Data");
|
||||
qScriptRegisterMapMetaType<Plasma::DataEngine::Data>(engine);
|
||||
qScriptRegisterMetaType<Plasma::Service *>(engine, qScriptValueFromService, serviceFromQScriptValue);
|
||||
qScriptRegisterMetaType<Plasma::DataEngine *>(engine, qScriptValueFromDataEngine, dataEngineFromQScriptValue);
|
||||
qScriptRegisterMetaType<Plasma::ServiceJob *>(engine, qScriptValueFromServiceJob, serviceJobFromQScriptValue);
|
||||
}
|
||||
|
83
declarativeimports/core/dataenginebindings_p.h
Normal file
83
declarativeimports/core/dataenginebindings_p.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2007 Richard J. Moore <rich@kde.org>
|
||||
*
|
||||
* 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 <QScriptEngine>
|
||||
#include <QScriptValue>
|
||||
#include <QScriptValueIterator>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <plasma/dataengine.h>
|
||||
#include <plasma/service.h>
|
||||
#include <plasma/servicejob.h>
|
||||
|
||||
using namespace Plasma;
|
||||
|
||||
Q_DECLARE_METATYPE(DataEngine::Dict)
|
||||
Q_DECLARE_METATYPE(DataEngine::Data)
|
||||
|
||||
template <class M>
|
||||
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 <class M>
|
||||
void qScriptValueToMap(const QScriptValue &value, M &map)
|
||||
{
|
||||
//kDebug() << "qScriptValueToMap called";
|
||||
QScriptValueIterator it(value);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
map[it.name()] = qscriptvalue_cast<typename M::mapped_type>(it.value());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int qScriptRegisterMapMetaType(
|
||||
QScriptEngine *engine,
|
||||
const QScriptValue &prototype = QScriptValue()
|
||||
#ifndef qdoc
|
||||
, T * /* dummy */ = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return qScriptRegisterMetaType<T>(engine, qScriptValueFromMap, qScriptValueToMap, prototype);
|
||||
}
|
||||
|
||||
void registerDataEngineMetaTypes(QScriptEngine *engine);
|
||||
|
||||
#endif // DATAENGINE_H
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "datamodel.h"
|
||||
#include "datasource_p.h"
|
||||
#include "datasource.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -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"
|
||||
|
@ -20,7 +20,9 @@
|
||||
#include "dialog.h"
|
||||
#include "declarativeitemcontainer_p.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDeclarativeItem>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGraphicsObject>
|
||||
#include <QGraphicsWidget>
|
||||
#include <QTimer>
|
||||
@ -31,6 +33,9 @@
|
||||
#include <Plasma/WindowEffects>
|
||||
|
||||
|
||||
int DialogProxy::offscreenX = 0;
|
||||
int DialogProxy::offscreenY = 0;
|
||||
|
||||
DialogMargins::DialogMargins(Plasma::Dialog *dialog, QObject *parent)
|
||||
: QObject(parent),
|
||||
m_dialog(dialog)
|
||||
@ -95,8 +100,8 @@ DialogProxy::DialogProxy(QObject *parent)
|
||||
|
||||
DialogProxy::~DialogProxy()
|
||||
{
|
||||
delete m_dialog;
|
||||
delete m_declarativeItemContainer;
|
||||
delete m_dialog;
|
||||
}
|
||||
|
||||
QGraphicsObject *DialogProxy::mainItem() const
|
||||
@ -171,6 +176,12 @@ void DialogProxy::syncMainItem()
|
||||
}
|
||||
}
|
||||
m_dialog->setGraphicsWidget(widget);
|
||||
|
||||
if (!qobject_cast<Plasma::Corona *>(scene)) {
|
||||
offscreenX -= 1024;
|
||||
offscreenY -= 1024;
|
||||
widget->setPos(offscreenX, offscreenY);
|
||||
}
|
||||
}
|
||||
|
||||
bool DialogProxy::isVisible() const
|
||||
@ -190,17 +201,99 @@ void DialogProxy::setVisible(const bool visible)
|
||||
}
|
||||
}
|
||||
|
||||
QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const
|
||||
QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment)
|
||||
{
|
||||
if (!item) {
|
||||
QGraphicsObject *actualItem = item;
|
||||
|
||||
//if no item is passed search the root item in order to figure out the view
|
||||
if (!actualItem) {
|
||||
actualItem = qobject_cast<QGraphicsObject *>(parent());
|
||||
|
||||
//search the root object
|
||||
while (true) {
|
||||
QGraphicsObject *ancestor = qobject_cast<QGraphicsObject *>(actualItem->parent());
|
||||
|
||||
if (ancestor) {
|
||||
actualItem = ancestor;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!actualItem) {
|
||||
return QPoint();
|
||||
}
|
||||
Plasma::Corona *corona = qobject_cast<Plasma::Corona *>(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<Plasma::Corona *>(actualItem->scene());
|
||||
if (corona && item) {
|
||||
return corona->popupPosition(actualItem, m_dialog->size(), (Qt::AlignmentFlag)alignment);
|
||||
} else {
|
||||
|
||||
QList<QGraphicsView*> views = actualItem->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(actualItem->sceneBoundingRect()) ||
|
||||
v->sceneRect().contains(actualItem->scenePos())) {
|
||||
if (v->isActiveWindow()) {
|
||||
found = v;
|
||||
} else {
|
||||
possibleFind = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
view = found ? found : possibleFind;
|
||||
}
|
||||
|
||||
if (!view) {
|
||||
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) {
|
||||
alignment = Qt::AlignLeft;
|
||||
} else {
|
||||
alignment = Qt::AlignRight;
|
||||
}
|
||||
}
|
||||
|
||||
int xOffset = 0;
|
||||
|
||||
if (alignment == Qt::AlignCenter) {
|
||||
xOffset = actualItem->boundingRect().width()/2 - m_dialog->width()/2;
|
||||
} else if (alignment == Qt::AlignRight) {
|
||||
xOffset = actualItem->boundingRect().width() - m_dialog->width();
|
||||
}
|
||||
|
||||
const QRect avail = QApplication::desktop()->availableGeometry(view);
|
||||
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(actualItem->scenePos() - QPoint(-xOffset, m_dialog->height())));
|
||||
}
|
||||
return menuPos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
@ -148,6 +153,8 @@ private:
|
||||
DialogMargins *m_margins;
|
||||
bool m_activeWindow;
|
||||
Plasma::Location m_location;
|
||||
static int offscreenX;
|
||||
static int offscreenY;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "framesvgitem_p.h"
|
||||
#include "framesvgitem.h"
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
@ -130,4 +130,4 @@ void FrameSvgItem::doUpdate()
|
||||
|
||||
} // Plasma namespace
|
||||
|
||||
#include "framesvgitem_p.moc"
|
||||
#include "framesvgitem.moc"
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "svgitem_p.h"
|
||||
#include "svgitem.h"
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
@ -124,4 +124,4 @@ void SvgItem::updateNeeded()
|
||||
|
||||
} // Plasma namespace
|
||||
|
||||
#include "svgitem_p.moc"
|
||||
#include "svgitem.moc"
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
|
||||
***************************************************************************/
|
||||
|
||||
#include "theme_p.h"
|
||||
#include "theme.h"
|
||||
|
||||
#include <KIconLoader>
|
||||
|
||||
@ -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 *************
|
||||
@ -299,5 +305,5 @@ int ThemeProxy::enormousIconSize() const
|
||||
return KIconLoader::SizeEnormous;
|
||||
}
|
||||
|
||||
#include "theme_p.moc"
|
||||
#include "theme.moc"
|
||||
|
||||
|
@ -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;
|
@ -70,13 +70,16 @@ void ToolTipProxy::setTarget(QGraphicsObject *target)
|
||||
|
||||
void ToolTipProxy::syncTarget()
|
||||
{
|
||||
if (!m_target) {
|
||||
return;
|
||||
}
|
||||
// find the scene
|
||||
QGraphicsScene *scene = m_target.data()->scene();
|
||||
if (!scene) {
|
||||
QObject *parent = m_target.data();
|
||||
while ((parent = parent->parent())) {
|
||||
QGraphicsObject *qo = qobject_cast<QGraphicsObject*>(parent);
|
||||
if (qo) {
|
||||
if (qo && qo->scene()) {
|
||||
scene = qo->scene();
|
||||
scene->addItem(m_target.data());
|
||||
break;
|
||||
|
@ -6,6 +6,7 @@ set(plasmacomponents_SRCS
|
||||
enums.cpp
|
||||
qmenu.cpp
|
||||
qmenuitem.cpp
|
||||
kdialogproxy.cpp
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
@ -18,8 +19,17 @@ 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)
|
||||
|
||||
install(DIRECTORY qml/ DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/components)
|
||||
|
||||
|
||||
|
||||
#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)
|
||||
install(DIRECTORY platformcomponents/touch/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components)
|
||||
|
151
declarativeimports/plasmacomponents/kdialogproxy.cpp
Normal file
151
declarativeimports/plasmacomponents/kdialogproxy.cpp
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Marco MArtin <mart@kde.org>
|
||||
*
|
||||
* 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 <QLabel>
|
||||
|
||||
#include <KIcon>
|
||||
|
||||
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()));
|
||||
connect(m_dialog, SIGNAL(closeClicked()), 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"
|
||||
|
88
declarativeimports/plasmacomponents/kdialogproxy.h
Normal file
88
declarativeimports/plasmacomponents/kdialogproxy.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Marco MArtin <mart@kde.org>
|
||||
*
|
||||
* 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 <QObject>
|
||||
#include <KDialog>
|
||||
#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
|
||||
|
@ -20,22 +20,34 @@
|
||||
#include "plasmacomponentsplugin.h"
|
||||
|
||||
#include <QtDeclarative/qdeclarative.h>
|
||||
#include <QtDeclarative/QDeclarativeEngine>
|
||||
|
||||
#include "qrangemodel.h"
|
||||
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include "enums.h"
|
||||
#include "qmenu.h"
|
||||
#include "qmenuitem.h"
|
||||
|
||||
#include "kdialogproxy.h"
|
||||
|
||||
void PlasmaComponentsPlugin::registerTypes(const char *uri)
|
||||
{
|
||||
Q_ASSERT(uri == QLatin1String("org.kde.plasma.components"));
|
||||
|
||||
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<KDialogProxy>(uri, 0, 1, "QueryDialog");
|
||||
|
||||
qmlRegisterType<QMenuProxy>(uri, 0, 1, "Menu");
|
||||
qmlRegisterType<QMenuProxy>(uri, 0, 1, "ContextMenu");
|
||||
qmlRegisterType<QMenuItem>(uri, 0, 1, "MenuItem");
|
||||
}
|
||||
|
||||
qmlRegisterType<Plasma::QRangeModel>(uri, 0, 1, "RangeModel");
|
||||
|
||||
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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
|
||||
property bool hasOverState: false
|
||||
|
||||
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
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "hidden"
|
||||
PropertyChanges {
|
||||
target: shadow
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
PropertyAnimation {
|
||||
properties: "opacity"
|
||||
duration: 250
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
**
|
||||
** 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
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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
|
||||
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: shadowSvg
|
||||
elementId: "shadow"
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "shadow"
|
||||
PropertyChanges {
|
||||
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"
|
||||
PropertyChanges {
|
||||
target: shadow
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 0
|
||||
elementId: hoverElement
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
PropertyAnimation {
|
||||
properties: "opacity"
|
||||
duration: 250
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
// Plasma API
|
||||
property bool inverted: false
|
||||
property alias stepSize: range.stepSize
|
||||
property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false
|
||||
property real scrollButtonInterval: 50
|
||||
|
||||
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
|
||||
|
||||
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: 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 (internalLoader.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 (internalLoader.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 (internalLoader.isVertical) {
|
||||
internalLoader.item.contents.height - internalLoader.item.handle.height
|
||||
} else {
|
||||
internalLoader.item.contents.width - internalLoader.item.handle.width
|
||||
}
|
||||
}
|
||||
value: internalLoader.isVertical ? flickableItem.contentY : flickableItem.contentX
|
||||
onValueChanged: {
|
||||
if (flickableItem.moving) {
|
||||
return
|
||||
}
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
flickableItem.contentY = value
|
||||
} else {
|
||||
flickableItem.contentX = value
|
||||
}
|
||||
}
|
||||
|
||||
position: internalLoader.isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x
|
||||
|
||||
onPositionChanged: {
|
||||
if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) {
|
||||
return
|
||||
}
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
internalLoader.item.handle.y = position
|
||||
} else {
|
||||
internalLoader.item.handle.x = position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source: interactive ? "ScrollBarDelegate.qml" : "ScrollDecoratorDelegate.qml"
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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.0
|
||||
|
||||
/**
|
||||
* Just provided for compatibility
|
||||
* Use ScrollBar instead. will behave like a ScrollDecorator on touchscreens
|
||||
*/
|
||||
ScrollBar {
|
||||
interactive: false
|
||||
}
|
@ -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: sectionLabel.paintedWidth + margins.left + margins.right
|
||||
height: sectionLabel.paintedHeight + 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
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property bool inPortrait: height > width
|
||||
signal orientationChangeAboutToStart
|
||||
signal orientationChangeStarted
|
||||
signal orientationChangeFinished
|
||||
|
||||
width: 800
|
||||
height: 480
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
onInPortraitChanged: {
|
||||
root.orientationChangeFinished()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
plugin plasmacomponentsplugin
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
TabBar 0.1 TabBar.qml
|
||||
TabButton 0.1 TabButton.qml
|
||||
TabGroup 0.1 TabGroup.qml
|
||||
SectionScroller 0.1 SectionScroller.qml
|
@ -24,6 +24,7 @@
|
||||
#include <QDesktopWidget>
|
||||
#include <QGraphicsObject>
|
||||
#include <QGraphicsView>
|
||||
#include <QDeclarativeItem>
|
||||
|
||||
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<QGraphicsObject *>(parent());
|
||||
QGraphicsObject *parentItem;
|
||||
if (m_visualParent) {
|
||||
parentItem = qobject_cast<QGraphicsObject *>(parent());
|
||||
} else {
|
||||
parentItem = m_visualParent.data();
|
||||
}
|
||||
|
||||
if (!parentItem || !parentItem->scene()) {
|
||||
showMenu(0, 0);
|
||||
|
@ -26,12 +26,15 @@
|
||||
#include "qmenuitem.h"
|
||||
#include "enums.h"
|
||||
|
||||
class QDeclarativeItem;
|
||||
|
||||
class QMenuProxy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QDeclarativeListProperty<QMenuItem> 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<QMenuItem*> m_items;
|
||||
QMenu *m_menu;
|
||||
DialogStatus::Status m_status;
|
||||
QWeakPointer<QDeclarativeItem> m_visualParent;
|
||||
};
|
||||
|
||||
#endif //QMENU_PROXY_H
|
||||
|
85
declarativeimports/plasmacomponents/qml/AppManager.js
Normal file
85
declarativeimports/plasmacomponents/qml/AppManager.js
Normal file
@ -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
|
||||
}
|
@ -75,11 +75,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" }
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 by Mark Gaiser <markg85@gmail.com>
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
@ -71,73 +73,127 @@ Item {
|
||||
|
||||
signal clicked()
|
||||
|
||||
|
||||
function pressButton() {
|
||||
if (button.enabled)
|
||||
surface.prefix = "pressed";
|
||||
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)
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
height: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom)
|
||||
|
||||
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();
|
||||
QtObject {
|
||||
id: internal
|
||||
property bool userPressed: false
|
||||
|
||||
function belongsToButtonGroup()
|
||||
{
|
||||
return button.parent
|
||||
&& button.parent.hasOwnProperty("checkedButton")
|
||||
&& button.parent.exclusive
|
||||
}
|
||||
|
||||
function pressButton()
|
||||
{
|
||||
userPressed = true
|
||||
}
|
||||
|
||||
function releaseButton()
|
||||
{
|
||||
userPressed = false
|
||||
if (!button.enabled) {
|
||||
return
|
||||
}
|
||||
|
||||
if ((!belongsToButtonGroup() || !button.checked) && button.checkable) {
|
||||
button.checked = !button.checked
|
||||
}
|
||||
|
||||
button.clicked()
|
||||
button.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onSpacePressed: internal.pressButton()
|
||||
Keys.onReturnPressed: internal.pressButton()
|
||||
Keys.onReleased: {
|
||||
if (event.key == Qt.Key_Space ||
|
||||
event.key == Qt.Key_Return)
|
||||
releaseButton();
|
||||
}
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
shadow.state = "focus"
|
||||
} else if (checked) {
|
||||
shadow.state = "hidden"
|
||||
} else {
|
||||
shadow.state = "shadow"
|
||||
}
|
||||
internal.releaseButton();
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
state: (internal.userPressed || checked) ? "pressed" : "normal"
|
||||
|
||||
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 {
|
||||
@ -156,9 +212,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
|
||||
@ -169,7 +227,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
|
||||
}
|
||||
}
|
||||
@ -179,25 +237,8 @@ Item {
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onPressed: {
|
||||
pressButton();
|
||||
}
|
||||
onReleased: {
|
||||
releaseButton();
|
||||
}
|
||||
onEntered: {
|
||||
shadow.state = "hover"
|
||||
}
|
||||
onExited: {
|
||||
if (button.activeFocus) {
|
||||
shadow.state = "focus"
|
||||
} else if (checked) {
|
||||
shadow.state = "hidden"
|
||||
} else {
|
||||
shadow.state = "shadow"
|
||||
onPressed: internal.pressButton()
|
||||
onReleased: internal.releaseButton()
|
||||
onCanceled: internal.releaseButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
Item {
|
||||
id: main
|
||||
state: parent.state
|
||||
property bool hasOverState: true
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: hover
|
||||
|
@ -38,24 +38,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
|
||||
|
164
declarativeimports/plasmacomponents/qml/CommonDialog.qml
Normal file
164
declarativeimports/plasmacomponents/qml/CommonDialog.qml
Normal file
@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
**
|
||||
** 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 string 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 {
|
||||
right: parent.right
|
||||
left: titleAreaIcon.source == "" ? parent.left : titleAreaIcon.right
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
IconLoader {
|
||||
id: titleAreaIcon
|
||||
width: theme.iconSizeSmall
|
||||
height: theme.iconSizeSmall
|
||||
source: titleIcon
|
||||
anchors.left: parent.left
|
||||
anchors.rightMargin: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
161
declarativeimports/plasmacomponents/qml/Dialog.qml
Normal file
161
declarativeimports/plasmacomponents/qml/Dialog.qml
Normal file
@ -0,0 +1,161 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
**
|
||||
** 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()
|
||||
}
|
||||
}
|
||||
}
|
@ -69,7 +69,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
|
||||
|
@ -35,6 +35,10 @@ import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
Text {
|
||||
id: root
|
||||
|
||||
height: theme.defaultFont.mSize.height*1.8
|
||||
//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
|
||||
font.italic: theme.defaultFont.italic
|
||||
|
95
declarativeimports/plasmacomponents/qml/ListItem.qml
Normal file
95
declarativeimports/plasmacomponents/qml/ListItem.qml
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2010 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
}
|
@ -77,7 +77,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
|
||||
@ -89,18 +89,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
|
||||
@ -113,36 +103,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,11 @@ function initPage(page, properties) {
|
||||
}
|
||||
|
||||
container.page = page;
|
||||
if (page.parent == null) {
|
||||
container.owner = container;
|
||||
} else {
|
||||
container.owner = page.parent;
|
||||
}
|
||||
|
||||
// the page has to be reparented if
|
||||
if (page.parent != container) {
|
||||
@ -161,6 +165,8 @@ function initPage(page, properties) {
|
||||
page.pageStack = root;
|
||||
}
|
||||
|
||||
page.anchors.fill = container
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,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
|
||||
@ -308,9 +308,10 @@ 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.
|
||||
function transitionEnded()
|
||||
@ -341,7 +342,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 {
|
||||
@ -352,7 +353,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 {
|
||||
@ -470,14 +471,17 @@ 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.anchors.fill = undefined
|
||||
page.parent = owner;
|
||||
}
|
||||
}
|
||||
|
||||
container.destroy();
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ Properties:
|
||||
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.qtextracomponents 0.1
|
||||
|
||||
Item {
|
||||
id: progressBar
|
||||
@ -64,9 +65,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
|
||||
@ -86,26 +84,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 {
|
||||
@ -114,16 +143,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,24 +44,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
|
||||
|
@ -40,13 +40,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
|
||||
@ -56,10 +62,7 @@ Item {
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: shadow
|
||||
svg: PlasmaCore.Svg {
|
||||
id: shadowSvg
|
||||
imagePath: "widgets/actionbutton"
|
||||
}
|
||||
svg: shadowSvg
|
||||
elementId: "shadow"
|
||||
|
||||
anchors.fill: parent
|
||||
@ -75,7 +78,7 @@ Item {
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 0
|
||||
elementId: "hover"
|
||||
elementId: hoverElement
|
||||
}
|
||||
},
|
||||
State {
|
||||
@ -87,7 +90,7 @@ Item {
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 1
|
||||
elementId: "hover"
|
||||
elementId: hoverElement
|
||||
}
|
||||
},
|
||||
State {
|
||||
@ -99,11 +102,11 @@ Item {
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 1
|
||||
elementId: "focus"
|
||||
elementId: focusElement
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "hover"
|
||||
name: "hidden"
|
||||
PropertyChanges {
|
||||
target: shadow
|
||||
opacity: 0
|
||||
@ -111,7 +114,7 @@ Item {
|
||||
PropertyChanges {
|
||||
target: hover
|
||||
opacity: 0
|
||||
elementId: "hover"
|
||||
elementId: hoverElement
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
@ -61,36 +62,34 @@ Properties:
|
||||
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 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 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
|
||||
property bool _inverted: _isVertical ?
|
||||
!scrollbar.inverted : scrollbar.inverted
|
||||
|
||||
implicitWidth: _isVertical ? 22 : 200
|
||||
implicitHeight: _isVertical ? 200 : 22
|
||||
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
|
||||
|
||||
visible: flickableItem && handle.width < contents.width
|
||||
visible: flickableItem && internalLoader.handleEnabled
|
||||
|
||||
anchors {
|
||||
right: flickableItem.right
|
||||
@ -99,300 +98,80 @@ Item {
|
||||
bottom: flickableItem.bottom
|
||||
}
|
||||
|
||||
function incrementValue(increment) {
|
||||
Loader {
|
||||
id: internalLoader
|
||||
anchors.fill: parent
|
||||
//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) {
|
||||
flickableItem.contentY = Math.min(flickableItem.contentHeight,
|
||||
flickableItem.contentY + increment);
|
||||
if (internalLoader.isVertical) {
|
||||
flickableItem.contentY = Math.max(0, Math.min(flickableItem.contentHeight,
|
||||
flickableItem.contentY + increment))
|
||||
} else {
|
||||
flickableItem.contentX = Math.min(flickableItem.contentWidth,
|
||||
flickableItem.contentX + increment);
|
||||
flickableItem.contentX = Math.max(0, Math.min(flickableItem.contentWidth,
|
||||
flickableItem.contentX + increment))
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onUpPressed: {
|
||||
if (!enabled || !_isVertical)
|
||||
return;
|
||||
|
||||
if (_inverted)
|
||||
incrementValue(-stepSize);
|
||||
else
|
||||
incrementValue(stepSize);
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
if (!enabled || !_isVertical)
|
||||
return;
|
||||
|
||||
if (_inverted)
|
||||
incrementValue(stepSize);
|
||||
else
|
||||
incrementValue(-stepSize);
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if (!enabled || _isVertical)
|
||||
return;
|
||||
|
||||
if (_inverted)
|
||||
incrementValue(stepSize);
|
||||
else
|
||||
incrementValue(-stepSize);
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
if (!enabled || _isVertical)
|
||||
return;
|
||||
|
||||
if (_inverted)
|
||||
incrementValue(-stepSize);
|
||||
else
|
||||
incrementValue(stepSize);
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: leftButton
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: 18
|
||||
width: _showButtons ? 18 : 0
|
||||
svg: scrollbarSvg
|
||||
elementId: {
|
||||
if (leftMousArea.pressed)
|
||||
return "sunken-arrow-left";
|
||||
|
||||
if (scrollbar.activeFocus || leftMousArea.containsMouse)
|
||||
return "mouseover-arrow-left";
|
||||
else
|
||||
return "arrow-left";
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: leftMousArea
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (internalLoader.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
|
||||
inverted: scrollbar.inverted
|
||||
positionAtMinimum: 0
|
||||
positionAtMaximum: {
|
||||
if (internalLoader.isVertical) {
|
||||
internalLoader.item.contents.height - internalLoader.item.handle.height
|
||||
} else {
|
||||
internalLoader.item.contents.width - internalLoader.item.handle.width
|
||||
}
|
||||
}
|
||||
value: internalLoader.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; }
|
||||
if (flickableItem.moving) {
|
||||
return
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: groove
|
||||
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/scrollbar"
|
||||
prefix: "background-horizontal"
|
||||
if (internalLoader.isVertical) {
|
||||
flickableItem.contentY = value
|
||||
} else {
|
||||
flickableItem.contentX = value
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: handle
|
||||
position: internalLoader.isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x
|
||||
|
||||
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;
|
||||
|
||||
return ratio * parent.width;
|
||||
}
|
||||
height: parent.height - margins.top // TODO: check mergin
|
||||
imagePath: "widgets/scrollbar"
|
||||
prefix: {
|
||||
if (scrollbar.pressed)
|
||||
return "sunken-slider";
|
||||
|
||||
if (scrollbar.activeFocus || mouseArea.containsMouse)
|
||||
return "mouseover-slider";
|
||||
else
|
||||
return "slider";
|
||||
onPositionChanged: {
|
||||
if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) {
|
||||
return
|
||||
}
|
||||
|
||||
Behavior on x {
|
||||
id: behavior
|
||||
enabled: !mouseArea.drag.active && scrollbar.animated &&
|
||||
!flickableItem.flicking
|
||||
|
||||
PropertyAnimation {
|
||||
duration: behavior.enabled ? 150 : 0
|
||||
easing.type: Easing.OutSine
|
||||
if (internalLoader.isVertical) {
|
||||
internalLoader.item.handle.y = position
|
||||
} else {
|
||||
internalLoader.item.handle.x = position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
source: interactive ? "ScrollBarDelegate.qml" : "ScrollDecoratorDelegate.qml"
|
||||
}
|
||||
}
|
||||
|
251
declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml
Normal file
251
declarativeimports/plasmacomponents/qml/ScrollBarDelegate.qml
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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: internalLoader.isVertical ? "background-vertical" : "background-horizontal"
|
||||
|
||||
Keys.onUpPressed: {
|
||||
if (!enabled || !internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
if (!enabled || !internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(stepSize);
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if (!enabled || internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
if (!enabled || internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(stepSize);
|
||||
}
|
||||
|
||||
property Item handle: handle
|
||||
|
||||
property Item contents: contents
|
||||
Item {
|
||||
id: contents
|
||||
anchors {
|
||||
fill: parent
|
||||
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 {
|
||||
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: internalLoader.isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width
|
||||
|
||||
width: internalLoader.isVertical ? parent.width : length
|
||||
height: internalLoader.isVertical ? length : parent.height
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.Svg {
|
||||
id: scrollbarSvg
|
||||
imagePath: "widgets/scrollbar"
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: leftButton
|
||||
visible: stepSize > 0
|
||||
|
||||
anchors {
|
||||
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
|
||||
svg: scrollbarSvg
|
||||
elementId: {
|
||||
if (leftMouseArea.pressed) {
|
||||
return internalLoader.isVertical ? "sunken-arrow-up" : "sunken-arrow-left"
|
||||
}
|
||||
|
||||
if (scrollbar.activeFocus || leftMouseArea.containsMouse) {
|
||||
return internalLoader.isVertical ? "mouseover-arrow-up" : "mouseover-arrow-left"
|
||||
} else {
|
||||
return internalLoader.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: {
|
||||
background.forceActiveFocus()
|
||||
if (inverted) {
|
||||
internalLoader.incrementValue(stepSize);
|
||||
} else {
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: rightButton
|
||||
visible: stepSize > 0
|
||||
|
||||
anchors {
|
||||
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
|
||||
svg: scrollbarSvg
|
||||
elementId: {
|
||||
if (leftMouseArea.pressed) {
|
||||
return internalLoader.isVertical ? "sunken-arrow-down" : "sunken-arrow-right"
|
||||
}
|
||||
|
||||
if (scrollbar.activeFocus || leftMouseArea.containsMouse) {
|
||||
return internalLoader.isVertical ? "mouseover-arrow-down" : "mouseover-arrow-right"
|
||||
} else {
|
||||
return internalLoader.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: {
|
||||
background.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: internalLoader.isVertical ? Drag.YAxis : Drag.XAxis
|
||||
minimumX: range.positionAtMinimum
|
||||
maximumX: range.positionAtMaximum
|
||||
minimumY: range.positionAtMinimum
|
||||
maximumY: range.positionAtMaximum
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (internalLoader.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
|
||||
}
|
||||
}
|
||||
|
||||
background.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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: internalLoader.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"
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
property MouseArea mouseArea: null
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
onMovingChanged: {
|
||||
if (flickableItem.moving) {
|
||||
opacityTimer.running = false
|
||||
background.opacity = 1
|
||||
} else {
|
||||
opacityTimer.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: opacityTimer
|
||||
interval: 500
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: {
|
||||
background.opacity = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,16 +85,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
|
||||
@ -107,15 +100,6 @@ Item {
|
||||
bottom: listView.bottom
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: fadeTimer
|
||||
interval: 4000
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: {
|
||||
root.opacity = 0
|
||||
}
|
||||
}
|
||||
|
||||
RangeModel {
|
||||
id: range
|
||||
@ -124,99 +108,42 @@ 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"
|
||||
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
|
||||
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
|
||||
|
135
declarativeimports/plasmacomponents/qml/SelectionDialog.qml
Normal file
135
declarativeimports/plasmacomponents/qml/SelectionDialog.qml
Normal file
@ -0,0 +1,135 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
**
|
||||
** 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 * 40
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -82,11 +82,11 @@ Item {
|
||||
property bool updateValueWhileDragging: true
|
||||
property real handleSize: 22
|
||||
|
||||
// Convinience API
|
||||
// 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
|
||||
@ -151,8 +151,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 {
|
||||
@ -176,51 +176,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" : "shadow")
|
||||
anchors.fill: handle
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: handle
|
||||
|
||||
transform: Translate { x: - handle.width / 2 }
|
||||
x: fakeHandle.x
|
||||
anchors {
|
||||
verticalCenter: groove.verticalCenter
|
||||
@ -245,7 +220,6 @@ Item {
|
||||
id: fakeHandle
|
||||
width: handle.width
|
||||
height: handle.height
|
||||
transform: Translate { x: - handle.width / 2 }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@ -261,33 +235,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,13 +40,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
|
||||
|
@ -69,9 +69,9 @@ 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
|
||||
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 {
|
||||
@ -85,10 +85,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 {
|
||||
|
@ -67,15 +67,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
|
||||
}
|
||||
}
|
||||
@ -88,7 +91,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()
|
||||
@ -106,19 +109,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))
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ Item {
|
||||
target: root
|
||||
onPressedChanged: {
|
||||
//TabBar is the granparent
|
||||
root.parent.parent.currentItem = root
|
||||
root.parent.parent.currentTab = root
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (internal.tabGroup.currentTab == tab) {
|
||||
parent.parent.currentItem = root
|
||||
parent.parent.currentTab = root
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,7 +157,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
|
||||
|
@ -165,7 +165,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.
|
||||
@ -178,32 +177,12 @@ 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";
|
||||
state: textArea.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden")
|
||||
anchors.fill: base
|
||||
}
|
||||
|
||||
opacity: (mouseWatcher.containsMouse||textArea.activeFocus) ? 1 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseWatcher
|
||||
anchors.fill: hover
|
||||
@ -215,11 +194,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"
|
||||
@ -229,10 +204,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;
|
||||
@ -260,6 +237,7 @@ Item {
|
||||
font.weight: theme.defaultFont.weight
|
||||
font.wordSpacing: theme.defaultFont.wordSpacing
|
||||
color: theme.viewTextColor
|
||||
selectByMouse: verticalScroll.interactive
|
||||
|
||||
onCursorPositionChanged: {
|
||||
if (cursorRectangle.x < flickArea.contentX) {
|
||||
@ -310,7 +288,6 @@ Item {
|
||||
}
|
||||
enabled: parent.enabled
|
||||
flickableItem: flickArea
|
||||
height: visible ? scrollWidth : 0
|
||||
orientation: Qt.Horizontal
|
||||
stepSize: textEdit.font.pixelSize
|
||||
}
|
||||
@ -324,7 +301,6 @@ Item {
|
||||
}
|
||||
enabled: parent.enabled
|
||||
flickableItem: flickArea
|
||||
width: visible ? scrollWidth : 0
|
||||
orientation: Qt.Vertical
|
||||
stepSize: textEdit.font.pixelSize
|
||||
}
|
||||
|
@ -119,6 +119,9 @@ Item {
|
||||
property alias text: textInput.text
|
||||
property alias maximumLength: textInput.maximumLength
|
||||
|
||||
//Plasma api
|
||||
property bool clearButtonShown: false
|
||||
|
||||
function copy() {
|
||||
textInput.copy();
|
||||
}
|
||||
@ -162,12 +165,18 @@ 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
|
||||
|
||||
TextFieldFocus {
|
||||
id: hover
|
||||
state: textInput.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden")
|
||||
anchors.fill: base
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: base
|
||||
|
||||
@ -177,32 +186,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
|
||||
@ -210,7 +193,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
|
||||
@ -235,12 +224,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
|
||||
}
|
||||
y: (height - font.pixelSize) * 0.4 // XXX: verticalCenter anchor is not centering the text
|
||||
height: Math.min(2 * font.pixelSize, parent.height)
|
||||
selectByMouse: true
|
||||
color: theme.textColor
|
||||
enabled: textField.enabled
|
||||
clip: true
|
||||
@ -250,4 +239,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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
98
declarativeimports/plasmacomponents/qml/TextFieldFocus.qml
Normal file
98
declarativeimports/plasmacomponents/qml/TextFieldFocus.qml
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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: "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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -44,12 +44,18 @@ Properties:
|
||||
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: (tools && enabled) ? theme.defaultFont.mSize.height*2 + frameSvg.margins.top + frameSvg.margins.bottom : 0
|
||||
visible: height > 0
|
||||
Behavior on height {
|
||||
PropertyAnimation {
|
||||
id: heightAnimation
|
||||
duration: 250
|
||||
}
|
||||
}
|
||||
z: 1000
|
||||
|
||||
// The current set of tools; null if none.
|
||||
property Item tools
|
||||
@ -71,7 +77,11 @@ PlasmaCore.FrameSvgItem {
|
||||
toolBar.transition = transition
|
||||
toolBar.tools = tools
|
||||
}
|
||||
onToolsChanged: {
|
||||
Connections {
|
||||
id: connection
|
||||
target: toolBar
|
||||
function internalToolsChanged()
|
||||
{
|
||||
var newContainer
|
||||
var oldContainer
|
||||
if (containerA.current) {
|
||||
@ -92,20 +102,20 @@ PlasmaCore.FrameSvgItem {
|
||||
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
|
||||
@ -124,7 +134,7 @@ PlasmaCore.FrameSvgItem {
|
||||
default:
|
||||
containerA.animationsEnabled = false
|
||||
containerA.animationsEnabled = false
|
||||
oldContainer.x = -oldContainer.width
|
||||
oldContainer.x = -oldContainer.width/2
|
||||
newContainer.x = 0
|
||||
break
|
||||
}
|
||||
@ -132,14 +142,32 @@ PlasmaCore.FrameSvgItem {
|
||||
newContainer.opacity = 1
|
||||
oldContainer.opacity = 0
|
||||
}
|
||||
onToolsChanged: connection.internalToolsChanged()
|
||||
Component.onCompleted: connection.internalToolsChanged()
|
||||
}
|
||||
|
||||
Item {
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: frameSvg
|
||||
imagePath: "widgets/frame"
|
||||
prefix: "raised"
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: parent.margins.left
|
||||
topMargin: parent.margins.top
|
||||
rightMargin: parent.margins.right
|
||||
bottomMargin: parent.margins.bottom
|
||||
leftMargin: -margins.left
|
||||
rightMargin: -margins.right
|
||||
//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: containerAOpacityAnimation.running || heightAnimation.running
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: frameSvg.margins.left/2
|
||||
topMargin: frameSvg.margins.top/2
|
||||
rightMargin: frameSvg.margins.right/2
|
||||
bottomMargin: frameSvg.margins.bottom/2
|
||||
}
|
||||
|
||||
Item {
|
||||
@ -151,7 +179,10 @@ PlasmaCore.FrameSvgItem {
|
||||
//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
|
||||
|
66
declarativeimports/plasmacomponents/qml/ToolBarLayout.qml
Normal file
66
declarativeimports/plasmacomponents/qml/ToolBarLayout.qml
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* 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.
|
||||
|
||||
import QtQuick 1.1
|
||||
import "." 0.1
|
||||
|
||||
|
||||
Row {
|
||||
id: root
|
||||
|
||||
visible: false
|
||||
|
||||
Item {
|
||||
id: spacer
|
||||
width: 10
|
||||
height: 10
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: internal
|
||||
property bool layouting: false
|
||||
function layoutChildren()
|
||||
{
|
||||
var numChildren = root.children.length
|
||||
if (layouting || parent == null ||
|
||||
root.width == 0 || numChildren < 2) {
|
||||
return
|
||||
}
|
||||
|
||||
layouting = true
|
||||
spacer.parent = null
|
||||
|
||||
spacer.width = root.parent.width - root.childrenRect.width -10
|
||||
|
||||
var last = root.children[numChildren-2]
|
||||
last.parent = null
|
||||
spacer.parent = root
|
||||
last.parent = root
|
||||
layouting = false
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: internal.layoutChildren()
|
||||
onChildrenChanged: internal.layoutChildren()
|
||||
onWidthChanged: internal.layoutChildren()
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 by Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
@ -76,41 +77,26 @@ Item {
|
||||
surface.opacity = 1
|
||||
}
|
||||
|
||||
function pressButton() {
|
||||
if (button.enabled)
|
||||
surface.prefix = "pressed";
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
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
|
||||
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: {
|
||||
@ -123,6 +109,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
|
||||
@ -134,8 +145,9 @@ Item {
|
||||
|
||||
anchors.fill: parent
|
||||
imagePath: "widgets/button"
|
||||
prefix: "normal"
|
||||
opacity: 0
|
||||
prefix: (internal.userPressed || checked) ? "pressed" : "normal"
|
||||
//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 }
|
||||
}
|
||||
@ -179,7 +191,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
|
||||
}
|
||||
}
|
||||
@ -190,23 +202,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) {
|
||||
|
@ -15,19 +15,20 @@ 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 ToolButton.qml
|
||||
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
|
||||
Window 0.1 Window.qml
|
||||
|
||||
|
||||
TabBar 0.1 TabBar.qml
|
||||
TabButton 0.1 TabButton.qml
|
||||
|
@ -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)
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "qiconitem.h"
|
||||
|
||||
#include <kicon.h>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
|
||||
@ -34,9 +35,14 @@ QIconItem::~QIconItem()
|
||||
{
|
||||
}
|
||||
|
||||
void QIconItem::setIcon(const QIcon &icon)
|
||||
void QIconItem::setIcon(const QVariant &icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
if(icon.canConvert<QIcon>()) {
|
||||
m_icon = icon.value<QIcon>();
|
||||
}
|
||||
else if(icon.canConvert<QString>()) {
|
||||
m_icon = KIcon(icon.toString());
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -21,19 +21,20 @@
|
||||
|
||||
#include <QDeclarativeItem>
|
||||
#include <QPixmap>
|
||||
#include <QVariant>
|
||||
|
||||
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(const QVariant &icon);
|
||||
QIcon icon() const;
|
||||
|
||||
void setSmooth(const bool smooth);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
@ -79,15 +96,51 @@ 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);
|
||||
|
||||
painter->drawPixmap(boundingRect(), m_pixmap, m_pixmap.rect());
|
||||
painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias);
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform);
|
||||
QRect destRect;
|
||||
switch (m_fillMode) {
|
||||
case PreserveAspectFit: {
|
||||
QSize scaled = m_pixmap.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_pixmap.size();
|
||||
scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatioByExpanding);
|
||||
destRect = QRect(QPoint(0, 0), scaled);
|
||||
break;
|
||||
}
|
||||
case TileVertically: {
|
||||
painter->scale(width()/(qreal)m_pixmap.width(), 1);
|
||||
destRect = boundingRect().toRect();
|
||||
destRect.setWidth(destRect.width() / (width()/(qreal)m_pixmap.width()));
|
||||
break;
|
||||
}
|
||||
case TileHorizontally: {
|
||||
painter->scale(1, height()/(qreal)m_pixmap.height());
|
||||
destRect = boundingRect().toRect();
|
||||
destRect.setHeight(destRect.height() / (height()/(qreal)m_pixmap.height()));
|
||||
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->restore();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -20,6 +20,22 @@
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
PlasmaComponents.Page {
|
||||
height: childrenRect.height
|
||||
property int implicitHeight: childrenRect.height
|
||||
|
||||
tools: PlasmaComponents.ToolBarLayout {
|
||||
spacing: 5
|
||||
PlasmaComponents.ToolButton {
|
||||
text: "ToolButton"
|
||||
}
|
||||
PlasmaComponents.ProgressBar {
|
||||
value: 0.3
|
||||
}
|
||||
PlasmaComponents.TextField {
|
||||
text: "Busy widgets"
|
||||
}
|
||||
}
|
||||
Column {
|
||||
spacing: 20
|
||||
|
||||
@ -76,3 +92,4 @@ Column {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,19 @@
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
PlasmaComponents.Page {
|
||||
height: childrenRect.height
|
||||
tools: PlasmaComponents.ToolBarLayout {
|
||||
spacing: 5
|
||||
PlasmaComponents.Button {
|
||||
text: "Button"
|
||||
}
|
||||
PlasmaComponents.Button {
|
||||
text: "toolbar of the Buttons page"
|
||||
}
|
||||
PlasmaComponents.TextField {}
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 20
|
||||
|
||||
@ -97,3 +110,4 @@ Column {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,23 @@
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
|
||||
PlasmaComponents.Page {
|
||||
height: childrenRect.height
|
||||
property int implicitHeight: childrenRect.height
|
||||
|
||||
tools: PlasmaComponents.ToolBarLayout {
|
||||
spacing: 5
|
||||
PlasmaComponents.ToolButton {
|
||||
text: "ToolButton"
|
||||
}
|
||||
PlasmaComponents.CheckBox {
|
||||
text: "Checkbox in the toolbar"
|
||||
}
|
||||
PlasmaComponents.TextField {
|
||||
text: "hello"
|
||||
}
|
||||
}
|
||||
Column {
|
||||
spacing: 20
|
||||
|
||||
@ -105,3 +122,4 @@ Column {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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,76 +33,88 @@ 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"
|
||||
}
|
||||
}
|
||||
Row {
|
||||
id: toolbarB
|
||||
visible: false
|
||||
spacing: 5
|
||||
PlasmaComponents.ToolButton {
|
||||
text: "Switch toolbar"
|
||||
onClicked: toolBar.setTools(toolbarA, "pop")
|
||||
delegate: ListItem {
|
||||
enabled: true
|
||||
Column {
|
||||
Label {
|
||||
text: title
|
||||
}
|
||||
PlasmaComponents.ToolButton {
|
||||
flat: false
|
||||
text: "button on second toolbar"
|
||||
}
|
||||
PlasmaComponents.TextField {}
|
||||
onClicked: pageStack.replace(Qt.createComponent(page))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
flickableItem: page
|
||||
animated: true
|
||||
orientation: Qt.Horizontal
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: verticalScrollBar.left
|
||||
@ -110,14 +122,13 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.ScrollBar {
|
||||
ScrollBar {
|
||||
id: verticalScrollBar
|
||||
|
||||
stepSize: 30
|
||||
|
||||
orientation: Qt.Vertical
|
||||
flickableItem: page
|
||||
animated: true
|
||||
anchors {
|
||||
top: toolBar.bottom
|
||||
right: parent.right
|
||||
|
636
declarativeimports/test/gallery/Misc.qml
Normal file
636
declarativeimports/test/gallery/Misc.qml
Normal file
@ -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" }
|
||||
}
|
||||
}
|
@ -20,6 +20,25 @@
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
PlasmaComponents.Page {
|
||||
height: childrenRect.height
|
||||
property int implicitHeight: childrenRect.height
|
||||
|
||||
tools: PlasmaComponents.ToolBarLayout {
|
||||
spacing: 5
|
||||
PlasmaComponents.ToolButton {
|
||||
text: "ToolButton"
|
||||
}
|
||||
PlasmaComponents.ScrollBar {
|
||||
orientation: Qt.Horizontal
|
||||
interactive: true
|
||||
flickableItem: scrollArea
|
||||
width: 200
|
||||
}
|
||||
PlasmaComponents.TextField {
|
||||
text: "hello"
|
||||
}
|
||||
}
|
||||
Column {
|
||||
spacing: 20
|
||||
|
||||
@ -52,7 +71,6 @@ Column {
|
||||
id: scrollBar
|
||||
orientation: Qt.Vertical
|
||||
flickableItem: scrollList
|
||||
animated: true
|
||||
stepSize: 40
|
||||
scrollButtonInterval: 50
|
||||
anchors {
|
||||
@ -102,7 +120,7 @@ Column {
|
||||
}
|
||||
|
||||
// Scroll Decorators
|
||||
PlasmaComponents.ScrollDecorator {
|
||||
PlasmaComponents.ScrollBar {
|
||||
orientation: Qt.Vertical
|
||||
flickableItem: scrollArea
|
||||
inverted: true
|
||||
@ -118,7 +136,7 @@ Column {
|
||||
text: "inverted"
|
||||
}
|
||||
}
|
||||
PlasmaComponents.ScrollDecorator {
|
||||
PlasmaComponents.ScrollBar {
|
||||
orientation: Qt.Horizontal
|
||||
flickableItem: scrollArea
|
||||
anchors {
|
||||
@ -129,3 +147,4 @@ Column {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,24 @@
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
PlasmaComponents.Page {
|
||||
height: childrenRect.height
|
||||
property int implicitHeight: childrenRect.height
|
||||
|
||||
tools: PlasmaComponents.ToolBarLayout {
|
||||
spacing: 5
|
||||
PlasmaComponents.ToolButton {
|
||||
text: "ToolButton"
|
||||
}
|
||||
PlasmaComponents.Slider {
|
||||
width: 140
|
||||
animated: true
|
||||
enabled: true
|
||||
}
|
||||
PlasmaComponents.TextField {
|
||||
text: "hello"
|
||||
}
|
||||
}
|
||||
Column {
|
||||
spacing: 20
|
||||
|
||||
@ -49,7 +67,6 @@ Column {
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
stepSize: 10
|
||||
animated: true
|
||||
Keys.onTabPressed: greenSlider.forceActiveFocus()
|
||||
}
|
||||
|
||||
@ -77,7 +94,6 @@ Column {
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
stepSize: 10
|
||||
animated: true
|
||||
Keys.onTabPressed: redSlider.forceActiveFocus()
|
||||
}
|
||||
|
||||
@ -130,3 +146,4 @@ Column {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,25 @@
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
PlasmaComponents.Page {
|
||||
height: childrenRect.height
|
||||
property int implicitHeight: childrenRect.height
|
||||
|
||||
tools: PlasmaComponents.ToolBarLayout {
|
||||
spacing: 5
|
||||
PlasmaComponents.Label {
|
||||
text: "Text label:"
|
||||
}
|
||||
PlasmaComponents.ToolButton {
|
||||
text: "ToolButton"
|
||||
}
|
||||
PlasmaComponents.TextField {
|
||||
placeholderText: "Place holder text"
|
||||
}
|
||||
PlasmaComponents.TextField {
|
||||
text: "Text fields page"
|
||||
}
|
||||
}
|
||||
Column {
|
||||
spacing: 30
|
||||
Text {
|
||||
@ -97,3 +116,4 @@ Column {
|
||||
text: "Disabled Text Area"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -372,6 +372,7 @@ public Q_SLOTS:
|
||||
void togglePopup();
|
||||
void hidePopup();
|
||||
void showPopup();
|
||||
void showPopup(int timeout);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 :/
|
||||
|
@ -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);
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <Plasma/PackageMetadata>
|
||||
|
||||
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 <path>", ki18nc("Do not translate <path>", "Generate a SHA1 hash for the package at <path>"));
|
||||
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")) {
|
||||
|
Loading…
Reference in New Issue
Block a user