Merge branch 'master' into plasma-components-doc

This commit is contained in:
Giorgos Tsiapaliwkas 2011-11-16 18:06:25 +02:00
commit 72f52c5d29
86 changed files with 4839 additions and 1371 deletions

View File

@ -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)

View File

@ -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)

View 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);
}

View 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

View File

@ -18,7 +18,7 @@
*/
#include "datamodel.h"
#include "datasource_p.h"
#include "datasource.h"
#include <QTimer>

View File

@ -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"

View File

@ -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,16 +201,98 @@ void DialogProxy::setVisible(const bool visible)
}
}
QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const
QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment)
{
if (!item) {
return QPoint();
QGraphicsObject *actualItem = item;
//if no item is passed search the root item in order to figure out the view
if (!actualItem) {
actualItem = qobject_cast<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 {
return QPoint();
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;
}
}

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -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)

View 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"

View 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

View File

@ -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");
}
qmlRegisterType<QMenuProxy>(uri, 0, 1, "Menu");
qmlRegisterType<QMenuProxy>(uri, 0, 1, "ContextMenu");
qmlRegisterType<QMenuItem>(uri, 0, 1, "MenuItem");
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");

View File

@ -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
}
}
]
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
]
}

View File

@ -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"
}
}

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -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
}
}
]
}

View File

@ -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()
}
}
}

View File

@ -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

View File

@ -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);

View File

@ -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

View 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
}

View File

@ -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" }
}
}

View File

@ -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)
}
}
height: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom)
function releaseButton() {
if (!button.enabled)
return;
if (button.checkable)
button.checked = !button.checked;
// TODO: "checked" state must have special graphics?
if (button.checked)
surface.prefix = "pressed";
else
surface.prefix = "normal";
button.clicked();
button.forceActiveFocus();
}
width: Math.max(50, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right)
height: Math.max(20, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom)
// TODO: needs to define if there will be specific graphics for
// disabled buttons
opacity: enabled ? 1.0 : 0.5
Keys.onSpacePressed: pressButton();
Keys.onReturnPressed: pressButton();
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()
}
}

View File

@ -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

View File

@ -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

View 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
}
}
}

View 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()
}
}
}

View File

@ -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

View File

@ -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

View 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
}
}
}

View File

@ -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
}
}
}
}

View File

@ -150,7 +150,11 @@ function initPage(page, properties) {
}
container.page = page;
container.owner = page.parent;
if (page.parent == null) {
container.owner = container;
} else {
container.owner = page.parent;
}
// the page has to be reparented if
if (page.parent != container) {
@ -161,6 +165,8 @@ function initPage(page, properties) {
page.pageStack = root;
}
page.anchors.fill = container
return container;
}

View File

@ -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,8 +308,9 @@ Item {
{
transitionAnimationRunning = true;
internal.ongoingTransitionCount++;
if (root.visible)
if (root.visible) {
internal.setPageStatus(page, (state == "") ? PageStatus.Activating : PageStatus.Deactivating);
}
}
// Called when a transition has ended.
@ -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();
}
}

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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
}
}
]

View File

@ -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) {
if (!flickableItem)
return;
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
if (_isVertical) {
flickableItem.contentY = Math.min(flickableItem.contentHeight,
flickableItem.contentY + increment);
} else {
flickableItem.contentX = Math.min(flickableItem.contentWidth,
flickableItem.contentX + increment);
}
}
function incrementValue(increment)
{
if (!flickableItem)
return;
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"
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))
}
}
PlasmaCore.SvgItem {
id: leftButton
RangeModel {
id: range
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
height: 18
width: _showButtons ? 18 : 0
svg: scrollbarSvg
elementId: {
if (leftMousArea.pressed)
return "sunken-arrow-left";
minimumValue: 0
maximumValue: {
var diff;
if (internalLoader.isVertical) {
diff = flickableItem.contentHeight - flickableItem.height
} else {
diff = flickableItem.contentWidth - flickableItem.width
}
if (scrollbar.activeFocus || leftMousArea.containsMouse)
return "mouseover-arrow-left";
else
return "arrow-left";
return Math.max(0, diff)
}
MouseArea {
id: leftMousArea
stepSize: 10
inverted: scrollbar.inverted
positionAtMinimum: 0
positionAtMaximum: {
if (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
}
anchors.fill: parent
enabled: scrollbar.enabled
Timer {
id: leftTimer
interval: scrollbar.scrollButtonInterval;
running: parent.pressed
repeat: true
onTriggered: {
scrollbar.forceActiveFocus();
if (_inverted)
incrementValue(stepSize);
else
incrementValue(-stepSize);
}
if (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
}
}
}
PlasmaCore.SvgItem {
id: rightButton
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
height: 18
width: _showButtons ? 18 : 0
svg: scrollbarSvg
elementId: {
if (rightMousArea.pressed)
return "sunken-arrow-right";
if (scrollbar.activeFocus || rightMousArea.containsMouse)
return "mouseover-arrow-right";
else
return "arrow-right";
}
MouseArea {
id: rightMousArea
anchors.fill: parent
enabled: scrollbar.enabled
Timer {
id: rightTimer
interval: scrollbar.scrollButtonInterval;
running: parent.pressed;
repeat: true
onTriggered: {
scrollbar.forceActiveFocus();
if (_inverted)
incrementValue(-stepSize);
else
incrementValue(stepSize);
}
}
}
}
Item {
id: contents
anchors {
left: leftButton.right
top: parent.top
bottom: parent.bottom
right: rightButton.left
}
RangeModel {
id: range
minimumValue: 0
maximumValue: {
var diff;
if (_isVertical)
diff = flickableItem.contentHeight - flickableItem.height;
else
diff = flickableItem.contentWidth - flickableItem.width;
return Math.max(0, diff);
}
stepSize: 10
inverted: _inverted
positionAtMinimum: 0 + handle.width / 2
positionAtMaximum: contents.width - handle.width / 2
value: _isVertical ? flickableItem.contentY : flickableItem.contentX
onValueChanged: {
if (flickableItem.flicking)
return;
if (_isVertical)
flickableItem.contentY = value;
else
flickableItem.contentX = value;
}
position: handle.x
onPositionChanged: { handle.x = position; }
}
PlasmaCore.FrameSvgItem {
id: groove
anchors.fill: parent
imagePath: "widgets/scrollbar"
prefix: "background-horizontal"
}
PlasmaCore.FrameSvgItem {
id: handle
transform: Translate { x: - handle.width / 2 }
x: fakeHandle.x
anchors.verticalCenter: groove.verticalCenter
width: {
var ratio;
if (_isVertical)
ratio = flickableItem.visibleArea.heightRatio;
else
ratio = flickableItem.visibleArea.widthRatio;
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";
}
Behavior on x {
id: behavior
enabled: !mouseArea.drag.active && scrollbar.animated &&
!flickableItem.flicking
PropertyAnimation {
duration: behavior.enabled ? 150 : 0
easing.type: Easing.OutSine
}
}
}
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"
}
}

View 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();
}
}
}

View File

@ -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
}
}
}

View File

@ -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

View 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
}
}
}

View File

@ -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
}
}
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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))
}
}

View File

@ -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

View File

@ -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";
}
opacity: (mouseWatcher.containsMouse||textArea.activeFocus) ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: 250
easing.type: Easing.InOutQuad
}
}
state: textArea.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden")
anchors.fill: base
}
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
}

View File

@ -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()
}
}
}
}

View 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
}
}
]
}

View File

@ -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,75 +77,97 @@ PlasmaCore.FrameSvgItem {
toolBar.transition = transition
toolBar.tools = tools
}
onToolsChanged: {
var newContainer
var oldContainer
if (containerA.current) {
newContainer = containerB
oldContainer = containerA
} else {
newContainer = containerA
oldContainer = containerB
Connections {
id: connection
target: toolBar
function internalToolsChanged()
{
var newContainer
var oldContainer
if (containerA.current) {
newContainer = containerB
oldContainer = containerA
} else {
newContainer = containerA
oldContainer = containerB
}
containerA.current = !containerA.current
tools.parent = newContainer
tools.visible = true
tools.anchors.left = newContainer.left
tools.anchors.right = newContainer.right
tools.anchors.verticalCenter = newContainer.verticalCenter
switch (transition) {
case "push":
containerA.animationsEnabled = true
oldContainer.x = -oldContainer.width/2
containerA.animationsEnabled = false
newContainer.x = newContainer.width/2
newContainer.y = 0
containerA.animationsEnabled = true
newContainer.x = 0
break
case "pop":
containerA.animationsEnabled = true
oldContainer.x = oldContainer.width/2
containerA.animationsEnabled = false
newContainer.x = -newContainer.width/2
newContainer.y = 0
containerA.animationsEnabled = true
newContainer.x = 0
break
case "replace":
containerA.animationsEnabled = true
oldContainer.y = oldContainer.height
containerA.animationsEnabled = false
newContainer.x = 0
newContainer.y = -newContainer.height
containerA.animationsEnabled = true
newContainer.y = 0
break
case "set":
default:
containerA.animationsEnabled = false
containerA.animationsEnabled = false
oldContainer.x = -oldContainer.width/2
newContainer.x = 0
break
}
newContainer.opacity = 1
oldContainer.opacity = 0
}
containerA.current = !containerA.current
onToolsChanged: connection.internalToolsChanged()
Component.onCompleted: connection.internalToolsChanged()
}
tools.parent = newContainer
tools.visible = true
tools.anchors.left = newContainer.left
tools.anchors.right = newContainer.right
tools.anchors.verticalCenter = newContainer.verticalCenter
switch (transition) {
case "push":
containerA.animationsEnabled = true
oldContainer.x = -oldContainer.width
containerA.animationsEnabled = false
newContainer.x = newContainer.width
newContainer.y = 0
containerA.animationsEnabled = true
newContainer.x = 0
break
case "pop":
containerA.animationsEnabled = true
oldContainer.x = oldContainer.width
containerA.animationsEnabled = false
newContainer.x = -newContainer.width
newContainer.y = 0
containerA.animationsEnabled = true
newContainer.x = 0
break
case "replace":
containerA.animationsEnabled = true
oldContainer.y = oldContainer.height
containerA.animationsEnabled = false
newContainer.x = 0
newContainer.y = -newContainer.height
containerA.animationsEnabled = true
newContainer.y = 0
break
case "set":
default:
containerA.animationsEnabled = false
containerA.animationsEnabled = false
oldContainer.x = -oldContainer.width
newContainer.x = 0
break
PlasmaCore.FrameSvgItem {
id: frameSvg
imagePath: "widgets/frame"
prefix: "raised"
anchors {
fill: parent
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
}
newContainer.opacity = 1
oldContainer.opacity = 0
}
Item {
clip: containerAOpacityAnimation.running || heightAnimation.running
anchors {
fill: parent
leftMargin: parent.margins.left
topMargin: parent.margins.top
rightMargin: parent.margins.right
bottomMargin: parent.margins.bottom
leftMargin: frameSvg.margins.left/2
topMargin: frameSvg.margins.top/2
rightMargin: frameSvg.margins.right/2
bottomMargin: frameSvg.margins.bottom/2
}
Item {
@ -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

View 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()
}

View File

@ -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) {

View File

@ -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

View File

@ -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)

View File

@ -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();
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -20,59 +20,76 @@
import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents
Column {
spacing: 20
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
Text {
font.pixelSize: 20
text: "Busy Indicator"
}
PlasmaComponents.BusyIndicator { }
PlasmaComponents.BusyIndicator { running: true }
Text {
font.pixelSize: 20
text: "Progress Bar"
}
Text { text: "Horizontal" }
PlasmaComponents.ProgressBar {
value: 0.3
}
PlasmaComponents.ProgressBar {
indeterminate: true
}
PlasmaComponents.ProgressBar {
minimumValue: 0
maximumValue: 100
value: 30
}
Text { text: "Vertical" }
Row {
spacing: 20
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.ProgressBar {
value: 0.3
orientation: Qt.Vertical
width: 20
height: 100
}
PlasmaComponents.ProgressBar {
value: 0.4
orientation: Qt.Vertical
width: 20
height: 120
PlasmaComponents.TextField {
text: "Busy widgets"
}
}
Column {
spacing: 20
Text {
font.pixelSize: 20
text: "Busy Indicator"
}
PlasmaComponents.BusyIndicator { }
PlasmaComponents.BusyIndicator { running: true }
Text {
font.pixelSize: 20
text: "Progress Bar"
}
Text { text: "Horizontal" }
PlasmaComponents.ProgressBar {
value: 0.3
}
PlasmaComponents.ProgressBar {
orientation: Qt.Vertical
width: 20
height: 100
indeterminate: true
}
PlasmaComponents.ProgressBar {
minimumValue: 0
maximumValue: 100
value: 30
}
Text { text: "Vertical" }
Row {
spacing: 20
PlasmaComponents.ProgressBar {
value: 0.3
orientation: Qt.Vertical
width: 20
height: 100
}
PlasmaComponents.ProgressBar {
value: 0.4
orientation: Qt.Vertical
width: 20
height: 120
}
PlasmaComponents.ProgressBar {
orientation: Qt.Vertical
width: 20
height: 100
indeterminate: true
}
}
}
}

View File

@ -20,80 +20,94 @@
import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents
Column {
spacing: 20
Text {
font.pixelSize: 20
text: "Buttons"
PlasmaComponents.Page {
height: childrenRect.height
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.Button {
text: "Button"
}
PlasmaComponents.Button {
text: "toolbar of the Buttons page"
}
PlasmaComponents.TextField {}
}
PlasmaComponents.Button {
id: bt1
width: 140
height: 30
text: "Button"
Column {
spacing: 20
onClicked: {
console.log("Clicked");
Text {
font.pixelSize: 20
text: "Buttons"
}
Keys.onTabPressed: bt2.forceActiveFocus();
}
PlasmaComponents.Button {
id: bt1
width: 140
height: 30
text: "Button"
PlasmaComponents.Button {
id: bt2
width: 140
height: 30
text: "Checkable Button"
checkable: true
onClicked: {
console.log("Clicked");
}
onCheckedChanged: {
if (checked)
console.log("Button Checked");
else
console.log("Button Unchecked");
Keys.onTabPressed: bt2.forceActiveFocus();
}
Keys.onTabPressed: bt3.forceActiveFocus();
}
PlasmaComponents.Button {
id: bt2
width: 140
height: 30
text: "Checkable Button"
checkable: true
PlasmaComponents.Button {
id: bt3
width: 140
height: 30
text: "Different Font"
font {
pixelSize: 20
family: "Helvetica"
onCheckedChanged: {
if (checked)
console.log("Button Checked");
else
console.log("Button Unchecked");
}
Keys.onTabPressed: bt3.forceActiveFocus();
}
Keys.onTabPressed: bt4.forceActiveFocus();
}
PlasmaComponents.Button {
id: bt3
width: 140
height: 30
text: "Different Font"
font {
pixelSize: 20
family: "Helvetica"
}
PlasmaComponents.Button {
id: bt4
width: 140
height: 30
text: "Icon Button"
iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png"
Keys.onTabPressed: bt4.forceActiveFocus();
}
Keys.onTabPressed: bt5.forceActiveFocus();
}
PlasmaComponents.Button {
id: bt4
width: 140
height: 30
text: "Icon Button"
iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png"
PlasmaComponents.Button {
id: bt5
width: 140
height: 30
iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png"
Keys.onTabPressed: bt5.forceActiveFocus();
}
Keys.onTabPressed: bt1.forceActiveFocus();
}
PlasmaComponents.Button {
id: bt5
width: 140
height: 30
iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png"
PlasmaComponents.Button {
width: 140
height: 30
text: "Disabled Button"
enabled: false
Keys.onTabPressed: bt1.forceActiveFocus();
}
PlasmaComponents.Button {
width: 140
height: 30
text: "Disabled Button"
enabled: false
}
}
}

View File

@ -20,88 +20,106 @@
import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents
Column {
spacing: 20
Text {
font.pixelSize: 20
text: "Check Box"
}
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
PlasmaComponents.CheckBox {
width: 140
height: 30
text: "Check Box 1"
onCheckedChanged: {
if (checked)
console.log("CheckBox checked");
else
console.log("CheckBox unchecked");
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
onClicked: {
console.log("CheckBox clicked");
PlasmaComponents.CheckBox {
text: "Checkbox in the toolbar"
}
PlasmaComponents.TextField {
text: "hello"
}
}
PlasmaComponents.CheckBox {
height: 30
text: "Disabled"
enabled: false
}
PlasmaComponents.CheckBox {
height: 30
text: ""
}
PlasmaComponents.CheckBox {
height: 30
text: "A loooooooooooooong text"
}
Text {
font.pixelSize: 20
text: "Radio Button"
}
PlasmaComponents.RadioButton {
width: 140
height: 30
text: "RadioButton"
onCheckedChanged: {
if (checked)
console.log("RadioButton Checked");
else
console.log("RadioButton Unchecked");
}
}
PlasmaComponents.Switch { }
Text {
font.pixelSize: 20
text: "Button Row"
}
PlasmaComponents.ButtonRow {
Column {
spacing: 20
PlasmaComponents.RadioButton { text: "A" }
PlasmaComponents.RadioButton { text: "B" }
PlasmaComponents.RadioButton { text: "C" }
}
Text {
font.pixelSize: 20
text: "Button Column"
}
Text {
font.pixelSize: 20
text: "Check Box"
}
PlasmaComponents.ButtonColumn {
spacing: 20
PlasmaComponents.RadioButton { text: "Alice" }
PlasmaComponents.RadioButton { text: "Bob" }
PlasmaComponents.RadioButton { text: "Charles" }
}
PlasmaComponents.CheckBox {
width: 140
height: 30
text: "Check Box 1"
onCheckedChanged: {
if (checked)
console.log("CheckBox checked");
else
console.log("CheckBox unchecked");
}
onClicked: {
console.log("CheckBox clicked");
}
}
PlasmaComponents.CheckBox {
height: 30
text: "Disabled"
enabled: false
}
PlasmaComponents.CheckBox {
height: 30
text: ""
}
PlasmaComponents.CheckBox {
height: 30
text: "A loooooooooooooong text"
}
Text {
font.pixelSize: 20
text: "Radio Button"
}
PlasmaComponents.RadioButton {
width: 140
height: 30
text: "RadioButton"
onCheckedChanged: {
if (checked)
console.log("RadioButton Checked");
else
console.log("RadioButton Unchecked");
}
}
PlasmaComponents.Switch { }
Text {
font.pixelSize: 20
text: "Button Row"
}
PlasmaComponents.ButtonRow {
spacing: 20
PlasmaComponents.RadioButton { text: "A" }
PlasmaComponents.RadioButton { text: "B" }
PlasmaComponents.RadioButton { text: "C" }
}
Text {
font.pixelSize: 20
text: "Button Column"
}
PlasmaComponents.ButtonColumn {
spacing: 20
PlasmaComponents.RadioButton { text: "Alice" }
PlasmaComponents.RadioButton { text: "Bob" }
PlasmaComponents.RadioButton { text: "Charles" }
}
}
}

View File

@ -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"
}
}
delegate: ListItem {
enabled: true
Column {
Label {
text: title
}
}
onClicked: pageStack.replace(Qt.createComponent(page))
}
}
Row {
id: toolbarB
visible: false
spacing: 5
PlasmaComponents.ToolButton {
text: "Switch toolbar"
onClicked: toolBar.setTools(toolbarA, "pop")
}
PlasmaComponents.ToolButton {
flat: false
text: "button on second toolbar"
}
PlasmaComponents.TextField {}
}
Flickable {
id: page
anchors {
top: toolBar.bottom
left: parent.left
left: pageSelector.right
right: parent.right
bottom: parent.bottom
}
contentWidth: 2200
contentHeight: 1000
contentWidth: pageStack.currentPage.implicitWidth
contentHeight: pageStack.currentPage.implicitHeight
Row {
x: 30
anchors {
top: parent.top
bottom: parent.bottom
margins: 20
}
spacing: 30
Buttons{ }
CheckableButtons { }
Busy { }
Sliders { }
Scrollers { }
Texts { }
PageStack {
id: pageStack
toolBar: toolBar
width: page.width
height: currentPage.implicitHeight
initialPage: Qt.createComponent("Buttons.qml")
}
}
PlasmaComponents.ScrollBar {
ScrollBar {
id: horizontalScrollBar
stepSize: 30
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

View 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" }
}
}

View File

@ -20,111 +20,130 @@
import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents
Column {
spacing: 20
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
Text {
font.pixelSize: 20
text: "Scroll Bar"
}
ListView {
id: scrollList
width: 200
height: 200
clip: true
model: 20
delegate: Text {
width: 200
height: 30
text: index
font.pixelSize: 18
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
Rectangle {
anchors.fill: parent
color: "grey"
opacity: 0.3
}
PlasmaComponents.ScrollBar {
id: scrollBar
orientation: Qt.Vertical
flickableItem: scrollList
animated: true
stepSize: 40
scrollButtonInterval: 50
anchors {
top: scrollList.top
right: scrollList.right
bottom: scrollList.bottom
}
}
}
Text {
font.pixelSize: 20
text: "Scroll Decorator"
}
Item {
width: 200
height: 200
PlasmaComponents.Highlight { anchors.fill: parent }
Flickable {
id: scrollArea
anchors.fill: parent
clip: true
contentWidth: 400
contentHeight: 400
// Flickable Contents
Rectangle {
color: "green"
width: 100
height: 100
}
Rectangle {
x: 80
y: 80
color: "blue"
width: 200
height: 200
}
Rectangle {
x: 200
y: 200
color: "red"
width: 150
height: 150
}
}
// Scroll Decorators
PlasmaComponents.ScrollDecorator {
orientation: Qt.Vertical
flickableItem: scrollArea
inverted: true
anchors {
top: scrollArea.top
right: scrollArea.right
bottom: scrollArea.bottom
}
Text {
y: parent.height / 2
x: 13
rotation: -90
text: "inverted"
}
}
PlasmaComponents.ScrollDecorator {
orientation: Qt.Horizontal
interactive: true
flickableItem: scrollArea
anchors {
left: scrollArea.left
right: scrollArea.right
bottom: scrollArea.bottom
width: 200
}
PlasmaComponents.TextField {
text: "hello"
}
}
Column {
spacing: 20
Text {
font.pixelSize: 20
text: "Scroll Bar"
}
ListView {
id: scrollList
width: 200
height: 200
clip: true
model: 20
delegate: Text {
width: 200
height: 30
text: index
font.pixelSize: 18
}
Rectangle {
anchors.fill: parent
color: "grey"
opacity: 0.3
}
PlasmaComponents.ScrollBar {
id: scrollBar
orientation: Qt.Vertical
flickableItem: scrollList
stepSize: 40
scrollButtonInterval: 50
anchors {
top: scrollList.top
right: scrollList.right
bottom: scrollList.bottom
}
}
}
Text {
font.pixelSize: 20
text: "Scroll Decorator"
}
Item {
width: 200
height: 200
PlasmaComponents.Highlight { anchors.fill: parent }
Flickable {
id: scrollArea
anchors.fill: parent
clip: true
contentWidth: 400
contentHeight: 400
// Flickable Contents
Rectangle {
color: "green"
width: 100
height: 100
}
Rectangle {
x: 80
y: 80
color: "blue"
width: 200
height: 200
}
Rectangle {
x: 200
y: 200
color: "red"
width: 150
height: 150
}
}
// Scroll Decorators
PlasmaComponents.ScrollBar {
orientation: Qt.Vertical
flickableItem: scrollArea
inverted: true
anchors {
top: scrollArea.top
right: scrollArea.right
bottom: scrollArea.bottom
}
Text {
y: parent.height / 2
x: 13
rotation: -90
text: "inverted"
}
}
PlasmaComponents.ScrollBar {
orientation: Qt.Horizontal
flickableItem: scrollArea
anchors {
left: scrollArea.left
right: scrollArea.right
bottom: scrollArea.bottom
}
}
}
}

View File

@ -20,113 +20,130 @@
import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents
Column {
spacing: 20
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
PlasmaComponents.Label {
font.pixelSize: 20
text: "Slider"
}
PlasmaComponents.Highlight {
width: 300
height: 400
Column {
anchors {
fill: parent
}
spacing: 10
PlasmaComponents.Label { text: "Color Selector"; font.pixelSize: 20 }
PlasmaComponents.Label { text: "Red" }
PlasmaComponents.Slider {
id: redSlider
height: 20
width: 255
orientation: Qt.Horizontal
minimumValue: 0
maximumValue: 255
stepSize: 10
animated: true
Keys.onTabPressed: greenSlider.forceActiveFocus()
}
PlasmaComponents.Label { text: "Green" }
PlasmaComponents.Slider {
id: greenSlider
height: 20
width: 255
orientation: Qt.Horizontal
minimumValue: 0
maximumValue: 255
stepSize: 10
animated: true
Keys.onTabPressed: blueSlider.forceActiveFocus()
}
PlasmaComponents.Label { text: "Blue" }
PlasmaComponents.Slider {
id: blueSlider
height: 20
width: 255
orientation: Qt.Horizontal
minimumValue: 0
maximumValue: 255
stepSize: 10
animated: true
Keys.onTabPressed: redSlider.forceActiveFocus()
}
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width / 2
height: width
color: Qt.rgba(redSlider.value / 255, greenSlider.value / 255, blueSlider.value / 255, 1)
}
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.Slider {
width: 140
animated: true
enabled: true
}
PlasmaComponents.TextField {
text: "hello"
}
}
Column {
spacing: 20
PlasmaComponents.Label { text: "Disabled Horizontal Slider" }
PlasmaComponents.Label {
font.pixelSize: 20
text: "Slider"
}
PlasmaComponents.Slider {
id: horizontalSlider
width: 140
height: 20
animated: true
enabled: false
}
PlasmaComponents.Highlight {
width: 300
height: 400
Column {
anchors {
fill: parent
}
spacing: 10
PlasmaComponents.Label { text: "Inverted Horizontal Slider" }
PlasmaComponents.Label { text: "Color Selector"; font.pixelSize: 20 }
PlasmaComponents.Slider {
id: invHorizontalSlider
width: 140
height: 20
inverted: true
animated: true
enabled: true
}
PlasmaComponents.Label { text: "Red" }
PlasmaComponents.Label { text: "Vertical Slider" }
PlasmaComponents.Slider {
id: redSlider
height: 20
width: 255
orientation: Qt.Horizontal
minimumValue: 0
maximumValue: 255
stepSize: 10
Keys.onTabPressed: greenSlider.forceActiveFocus()
}
PlasmaComponents.Label { text: "Green" }
PlasmaComponents.Slider {
id: greenSlider
height: 20
width: 255
orientation: Qt.Horizontal
minimumValue: 0
maximumValue: 255
stepSize: 10
animated: true
Keys.onTabPressed: blueSlider.forceActiveFocus()
}
PlasmaComponents.Label { text: "Blue" }
PlasmaComponents.Slider {
id: blueSlider
height: 20
width: 255
orientation: Qt.Horizontal
minimumValue: 0
maximumValue: 255
stepSize: 10
Keys.onTabPressed: redSlider.forceActiveFocus()
}
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width / 2
height: width
color: Qt.rgba(redSlider.value / 255, greenSlider.value / 255, blueSlider.value / 255, 1)
}
}
}
PlasmaComponents.Label { text: "Disabled Horizontal Slider" }
Row {
spacing: 30
PlasmaComponents.Slider {
id: verticalSlider
width: 20
height: 140
orientation: Qt.Vertical
minimumValue: 10
maximumValue: 1000
stepSize: 50
id: horizontalSlider
width: 140
height: 20
animated: true
enabled: false
}
PlasmaComponents.Label { text: "Inverted Horizontal Slider" }
PlasmaComponents.Slider {
id: invHorizontalSlider
width: 140
height: 20
inverted: true
animated: true
enabled: true
}
PlasmaComponents.Label { text: verticalSlider.value }
}
PlasmaComponents.Label { text: "Vertical Slider" }
Row {
spacing: 30
PlasmaComponents.Slider {
id: verticalSlider
width: 20
height: 140
orientation: Qt.Vertical
minimumValue: 10
maximumValue: 1000
stepSize: 50
inverted: true
animated: true
}
PlasmaComponents.Label { text: verticalSlider.value }
}
}
}

View File

@ -20,80 +20,100 @@
import QtQuick 1.1
import org.kde.plasma.components 0.1 as PlasmaComponents
Column {
spacing: 30
Text {
text: "Text Fields"
font.pixelSize: 20
}
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
PlasmaComponents.Highlight {
width: 200
height: 100
Column {
spacing: 10
Row {
Text {
text: "Username: "
anchors.verticalCenter: tf1.verticalCenter
}
PlasmaComponents.TextField {
id: tf1
placeholderText: "login"
Keys.onTabPressed: tf2.forceActiveFocus();
}
}
Row {
Text {
text: "Password: "
anchors.verticalCenter: tf2.verticalCenter
}
PlasmaComponents.TextField {
id: tf2
width: 120
echoMode: TextInput.Password
Keys.onTabPressed: loginButton.forceActiveFocus();
}
}
PlasmaComponents.Button {
id: loginButton
text: "Login"
anchors {
right: parent.right
rightMargin: 0
}
width: 100
}
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.Label {
text: "Text label:"
}
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.TextField {
placeholderText: "Place holder text"
}
PlasmaComponents.TextField {
text: "Text fields page"
}
}
Column {
spacing: 30
Text {
text: "Text Fields"
font.pixelSize: 20
}
PlasmaComponents.TextField {
width: 120
placeholderText: "Disabled Text Field"
Keys.onTabPressed: loginButton.forceActiveFocus();
enabled: false
}
PlasmaComponents.Highlight {
width: 200
height: 100
Column {
spacing: 10
Row {
Text {
text: "Username: "
anchors.verticalCenter: tf1.verticalCenter
}
PlasmaComponents.TextField {
id: tf1
placeholderText: "login"
Keys.onTabPressed: tf2.forceActiveFocus();
}
}
Text {
text: "Text Area"
font.pixelSize: 20
}
Row {
Text {
text: "Password: "
anchors.verticalCenter: tf2.verticalCenter
}
PlasmaComponents.TextField {
id: tf2
width: 120
echoMode: TextInput.Password
Keys.onTabPressed: loginButton.forceActiveFocus();
}
}
PlasmaComponents.TextArea {
width: 200
height: 200
placeholderText: "Lorem ipsum et dolor"
wrapMode: TextEdit.WordWrap
contentMaxWidth: 400
contentMaxHeight: 400
}
PlasmaComponents.Button {
id: loginButton
text: "Login"
anchors {
right: parent.right
rightMargin: 0
}
width: 100
}
}
}
PlasmaComponents.TextArea {
width: 200
height: 100
enabled: false
text: "Disabled Text Area"
PlasmaComponents.TextField {
width: 120
placeholderText: "Disabled Text Field"
Keys.onTabPressed: loginButton.forceActiveFocus();
enabled: false
}
Text {
text: "Text Area"
font.pixelSize: 20
}
PlasmaComponents.TextArea {
width: 200
height: 200
placeholderText: "Lorem ipsum et dolor"
wrapMode: TextEdit.WordWrap
contentMaxWidth: 400
contentMaxHeight: 400
}
PlasmaComponents.TextArea {
width: 200
height: 100
enabled: false
text: "Disabled Text Area"
}
}
}

View File

@ -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);

View File

@ -372,6 +372,7 @@ public Q_SLOTS:
void togglePopup();
void hidePopup();
void showPopup();
void showPopup(int timeout);
};

View File

@ -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 :/

View File

@ -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);

View File

@ -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")) {