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 framesvgitem.cpp
dialog.cpp dialog.cpp
tooltip.cpp tooltip.cpp
dataenginebindings.cpp
) )
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
@ -23,7 +24,7 @@ qt4_automoc(${corebindings_SRCS})
add_library(corebindingsplugin SHARED ${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(TARGETS corebindingsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/core)
install(FILES qmldir 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 <QtDeclarative/qdeclarative.h>
#include <QDeclarativeContext> #include <QDeclarativeContext>
#include <QScriptEngine>
#include <kdeclarative.h>
#include <Plasma/FrameSvg> #include <Plasma/FrameSvg>
#include <Plasma/Svg> #include <Plasma/Svg>
#include "datasource_p.h" #include "datasource.h"
#include "datamodel.h" #include "datamodel.h"
#include "framesvgitem_p.h" #include "framesvgitem.h"
#include "svgitem_p.h" #include "svgitem.h"
#include "theme_p.h" #include "theme.h"
#include "dialog.h" #include "dialog.h"
#include "tooltip.h" #include "tooltip.h"
#include "dataenginebindings_p.h"
void CoreBindingsPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri) void CoreBindingsPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)
{ {
@ -43,6 +47,19 @@ void CoreBindingsPlugin::initializeEngine(QDeclarativeEngine *engine, const char
ThemeProxy *theme = new ThemeProxy(context); ThemeProxy *theme = new ThemeProxy(context);
context->setContextProperty("theme", theme); 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) 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 "datamodel.h"
#include "datasource_p.h" #include "datasource.h"
#include <QTimer> #include <QTimer>

View File

@ -19,7 +19,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "datasource_p.h" #include "datasource.h"
#include "qdeclarativeengine.h" #include "qdeclarativeengine.h"
#include "qdeclarativecontext.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 "dialog.h"
#include "declarativeitemcontainer_p.h" #include "declarativeitemcontainer_p.h"
#include <QApplication>
#include <QDeclarativeItem> #include <QDeclarativeItem>
#include <QDesktopWidget>
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QGraphicsWidget> #include <QGraphicsWidget>
#include <QTimer> #include <QTimer>
@ -31,6 +33,9 @@
#include <Plasma/WindowEffects> #include <Plasma/WindowEffects>
int DialogProxy::offscreenX = 0;
int DialogProxy::offscreenY = 0;
DialogMargins::DialogMargins(Plasma::Dialog *dialog, QObject *parent) DialogMargins::DialogMargins(Plasma::Dialog *dialog, QObject *parent)
: QObject(parent), : QObject(parent),
m_dialog(dialog) m_dialog(dialog)
@ -95,8 +100,8 @@ DialogProxy::DialogProxy(QObject *parent)
DialogProxy::~DialogProxy() DialogProxy::~DialogProxy()
{ {
delete m_dialog;
delete m_declarativeItemContainer; delete m_declarativeItemContainer;
delete m_dialog;
} }
QGraphicsObject *DialogProxy::mainItem() const QGraphicsObject *DialogProxy::mainItem() const
@ -171,6 +176,12 @@ void DialogProxy::syncMainItem()
} }
} }
m_dialog->setGraphicsWidget(widget); m_dialog->setGraphicsWidget(widget);
if (!qobject_cast<Plasma::Corona *>(scene)) {
offscreenX -= 1024;
offscreenY -= 1024;
widget->setPos(offscreenX, offscreenY);
}
} }
bool DialogProxy::isVisible() const bool DialogProxy::isVisible() const
@ -190,17 +201,99 @@ void DialogProxy::setVisible(const bool visible)
} }
} }
QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment)
{ {
if (!item) { QGraphicsObject *actualItem = item;
//if no item is passed search the root item in order to figure out the view
if (!actualItem) {
actualItem = qobject_cast<QGraphicsObject *>(parent());
//search the root object
while (true) {
QGraphicsObject *ancestor = qobject_cast<QGraphicsObject *>(actualItem->parent());
if (ancestor) {
actualItem = ancestor;
} else {
break;
}
}
if (!actualItem) {
return QPoint(); 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 { } else {
QList<QGraphicsView*> views = actualItem->scene()->views();
if (views.size() < 1) {
return QPoint(); 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; 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 //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 //FIXME:: Qt::WidgetAttribute should be already
Q_INVOKABLE void setAttribute(int attribute, bool on); Q_INVOKABLE void setAttribute(int attribute, bool on);
@ -148,6 +153,8 @@ private:
DialogMargins *m_margins; DialogMargins *m_margins;
bool m_activeWindow; bool m_activeWindow;
Plasma::Location m_location; Plasma::Location m_location;
static int offscreenX;
static int offscreenY;
}; };
#endif #endif

View File

@ -17,7 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "framesvgitem_p.h" #include "framesvgitem.h"
#include <QtGui/QPainter> #include <QtGui/QPainter>
@ -130,4 +130,4 @@ void FrameSvgItem::doUpdate()
} // Plasma namespace } // 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. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "svgitem_p.h" #include "svgitem.h"
#include <QtGui/QPainter> #include <QtGui/QPainter>
@ -124,4 +124,4 @@ void SvgItem::updateNeeded()
} // Plasma namespace } // 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 . * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/ ***************************************************************************/
#include "theme_p.h" #include "theme.h"
#include <KIconLoader> #include <KIconLoader>
@ -64,6 +64,8 @@ FontProxy::FontProxy(Plasma::Theme::FontRole role, QObject *parent)
this, SIGNAL(weightChanged())); this, SIGNAL(weightChanged()));
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
this, SIGNAL(wordSpacingChanged())); this, SIGNAL(wordSpacingChanged()));
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
this, SIGNAL(mSizeChanged()));
} }
FontProxy::~FontProxy() FontProxy::~FontProxy()
@ -140,6 +142,10 @@ qreal FontProxy::wordSpacing() const
return Plasma::Theme::defaultTheme()->font(m_fontRole).wordSpacing(); return Plasma::Theme::defaultTheme()->font(m_fontRole).wordSpacing();
} }
QSize FontProxy::mSize() const
{
return QFontMetrics(Plasma::Theme::defaultTheme()->font(m_fontRole)).boundingRect("M").size();
}
//********** Theme ************* //********** Theme *************
@ -299,5 +305,5 @@ int ThemeProxy::enormousIconSize() const
return KIconLoader::SizeEnormous; 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(bool underline READ underline NOTIFY underlineChanged )
Q_PROPERTY(Weight weight READ weight NOTIFY weightChanged ) Q_PROPERTY(Weight weight READ weight NOTIFY weightChanged )
Q_PROPERTY(qreal wordSpacing READ wordSpacing NOTIFY wordSpacingChanged ) Q_PROPERTY(qreal wordSpacing READ wordSpacing NOTIFY wordSpacingChanged )
Q_PROPERTY(QSize mSize READ mSize NOTIFY mSizeChanged )
Q_ENUMS(Capitalization) Q_ENUMS(Capitalization)
Q_ENUMS(Weight) Q_ENUMS(Weight)
@ -80,6 +81,11 @@ public:
Weight weight() const; Weight weight() const;
qreal wordSpacing() const; qreal wordSpacing() const;
/**
* @return The size of an uppercase M in this font
*/
QSize mSize() const;
Q_SIGNALS: Q_SIGNALS:
void boldChanged(); void boldChanged();
void capitalizationChanged(); void capitalizationChanged();
@ -92,6 +98,7 @@ Q_SIGNALS:
void underlineChanged(); void underlineChanged();
void weightChanged(); void weightChanged();
void wordSpacingChanged(); void wordSpacingChanged();
void mSizeChanged();
private: private:
Plasma::Theme::FontRole m_fontRole; Plasma::Theme::FontRole m_fontRole;

View File

@ -70,13 +70,16 @@ void ToolTipProxy::setTarget(QGraphicsObject *target)
void ToolTipProxy::syncTarget() void ToolTipProxy::syncTarget()
{ {
if (!m_target) {
return;
}
// find the scene // find the scene
QGraphicsScene *scene = m_target.data()->scene(); QGraphicsScene *scene = m_target.data()->scene();
if (!scene) { if (!scene) {
QObject *parent = m_target.data(); QObject *parent = m_target.data();
while ((parent = parent->parent())) { while ((parent = parent->parent())) {
QGraphicsObject *qo = qobject_cast<QGraphicsObject*>(parent); QGraphicsObject *qo = qobject_cast<QGraphicsObject*>(parent);
if (qo) { if (qo && qo->scene()) {
scene = qo->scene(); scene = qo->scene();
scene->addItem(m_target.data()); scene->addItem(m_target.data());
break; break;

View File

@ -6,6 +6,7 @@ set(plasmacomponents_SRCS
enums.cpp enums.cpp
qmenu.cpp qmenu.cpp
qmenuitem.cpp qmenuitem.cpp
kdialogproxy.cpp
) )
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
@ -18,8 +19,17 @@ qt4_automoc(${plasmacomponents_SRCS})
add_library(plasmacomponentsplugin SHARED ${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(TARGETS plasmacomponentsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/components)
install(DIRECTORY qml/ 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 "plasmacomponentsplugin.h"
#include <QtDeclarative/qdeclarative.h> #include <QtDeclarative/qdeclarative.h>
#include <QtDeclarative/QDeclarativeEngine>
#include "qrangemodel.h" #include "qrangemodel.h"
#include <KSharedConfig>
#include "enums.h" #include "enums.h"
#include "qmenu.h" #include "qmenu.h"
#include "qmenuitem.h" #include "qmenuitem.h"
#include "kdialogproxy.h"
void PlasmaComponentsPlugin::registerTypes(const char *uri) void PlasmaComponentsPlugin::registerTypes(const char *uri)
{ {
Q_ASSERT(uri == QLatin1String("org.kde.plasma.components")); Q_ASSERT(uri == QLatin1String("org.kde.plasma.components"));
QString componentsPlatform = getenv("KDE_PLASMA_COMPONENTS_PLATFORM");
if (componentsPlatform.isEmpty()) {
KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform");
componentsPlatform = cg.readEntry("name", "desktop");
}
if (componentsPlatform == "desktop") {
qmlRegisterType<KDialogProxy>(uri, 0, 1, "QueryDialog");
qmlRegisterType<QMenuProxy>(uri, 0, 1, "Menu"); qmlRegisterType<QMenuProxy>(uri, 0, 1, "Menu");
qmlRegisterType<QMenuProxy>(uri, 0, 1, "ContextMenu"); qmlRegisterType<QMenuProxy>(uri, 0, 1, "ContextMenu");
qmlRegisterType<QMenuItem>(uri, 0, 1, "MenuItem"); qmlRegisterType<QMenuItem>(uri, 0, 1, "MenuItem");
}
qmlRegisterType<Plasma::QRangeModel>(uri, 0, 1, "RangeModel"); 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 <QDesktopWidget>
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QGraphicsView> #include <QGraphicsView>
#include <QDeclarativeItem>
QMenuProxy::QMenuProxy (QObject *parent) QMenuProxy::QMenuProxy (QObject *parent)
: QObject(parent), : QObject(parent),
@ -57,6 +58,21 @@ DialogStatus::Status QMenuProxy::status() const
return m_status; 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) void QMenuProxy::showMenu(int x, int y)
{ {
m_menu->clear(); m_menu->clear();
@ -79,7 +95,12 @@ void QMenuProxy::open()
} }
m_menu->updateGeometry(); 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()) { if (!parentItem || !parentItem->scene()) {
showMenu(0, 0); showMenu(0, 0);

View File

@ -26,12 +26,15 @@
#include "qmenuitem.h" #include "qmenuitem.h"
#include "enums.h" #include "enums.h"
class QDeclarativeItem;
class QMenuProxy : public QObject class QMenuProxy : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QDeclarativeListProperty<QMenuItem> items READ items CONSTANT) Q_PROPERTY(QDeclarativeListProperty<QMenuItem> items READ items CONSTANT)
Q_CLASSINFO("DefaultProperty", "items") Q_CLASSINFO("DefaultProperty", "items")
Q_PROPERTY(QDeclarativeItem *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged())
Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged) Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged)
public: public:
@ -43,17 +46,22 @@ public:
QMenuItem *action(int) const; QMenuItem *action(int) const;
DialogStatus::Status status() const; DialogStatus::Status status() const;
QDeclarativeItem *visualParent() const;
void setVisualParent(QDeclarativeItem *parent);
void showMenu(int x, int y); void showMenu(int x, int y);
Q_INVOKABLE void open(); Q_INVOKABLE void open();
Q_INVOKABLE void close(); Q_INVOKABLE void close();
Q_SIGNALS: Q_SIGNALS:
void statusChanged(); void statusChanged();
void visualParentChanged();
private: private:
QList<QMenuItem*> m_items; QList<QMenuItem*> m_items;
QMenu *m_menu; QMenu *m_menu;
DialogStatus::Status m_status; DialogStatus::Status m_status;
QWeakPointer<QDeclarativeItem> m_visualParent;
}; };
#endif //QMENU_PROXY_H #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 { PlasmaCore.SvgItem {
id: widget id: widget
svg: PlasmaCore.Svg { imagePath: "widgets/busywidget" }
elementId: "busywidget"
anchors.centerIn: parent anchors.centerIn: parent
width: busy.width width: busy.width
height: busy.height height: busy.height
smooth: !running || smoothAnimation 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 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 * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as * it under the terms of the GNU Library General Public License as
@ -71,73 +73,127 @@ Item {
signal clicked() signal clicked()
width: {
function pressButton() { if (label.paintedWidth == 0) {
if (button.enabled) return height
surface.prefix = "pressed"; } else {
return Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surfaceNormal.margins.left + surfaceNormal.margins.right) + ((icon.valid) ? surfaceNormal.margins.left : 0)
} }
function releaseButton() {
if (!button.enabled)
return;
if (button.checkable)
button.checked = !button.checked;
// TODO: "checked" state must have special graphics?
if (button.checked)
surface.prefix = "pressed";
else
surface.prefix = "normal";
button.clicked();
button.forceActiveFocus();
} }
height: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom)
width: Math.max(50, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right)
height: Math.max(20, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom)
// TODO: needs to define if there will be specific graphics for // TODO: needs to define if there will be specific graphics for
// disabled buttons // disabled buttons
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
Keys.onSpacePressed: pressButton(); QtObject {
Keys.onReturnPressed: pressButton(); 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: { Keys.onReleased: {
if (event.key == Qt.Key_Space || if (event.key == Qt.Key_Space ||
event.key == Qt.Key_Return) event.key == Qt.Key_Return)
releaseButton(); internal.releaseButton();
}
onActiveFocusChanged: {
if (activeFocus) {
shadow.state = "focus"
} else if (checked) {
shadow.state = "hidden"
} else {
shadow.state = "shadow"
}
} }
ButtonShadow { ButtonShadow {
id: shadow id: shadow
anchors.fill: parent 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 { PlasmaCore.FrameSvgItem {
id: surface id: surfaceNormal
anchors.fill: parent anchors.fill: parent
imagePath: "widgets/button" imagePath: "widgets/button"
prefix: "normal" prefix: "normal"
} }
// The pressed state
PlasmaCore.FrameSvgItem {
id: surfacePressed
anchors.fill: parent
imagePath: "widgets/button"
prefix: "pressed"
opacity: 0
}
Item { 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 { anchors {
fill: parent fill: parent
leftMargin: surface.margins.left leftMargin: surfaceNormal.margins.left
topMargin: surface.margins.top topMargin: surfaceNormal.margins.top
rightMargin: surface.margins.right rightMargin: surfaceNormal.margins.right
bottomMargin: surface.margins.bottom bottomMargin: surfaceNormal.margins.bottom
} }
IconLoader { IconLoader {
@ -156,9 +212,11 @@ Item {
anchors { anchors {
top: parent.top top: parent.top
bottom: parent.bottom bottom: parent.bottom
left: icon.valid ? icon.right : parent.left
right: parent.right right: parent.right
left: icon.valid ? icon.right : parent.left
leftMargin: icon.valid ? parent.anchors.leftMargin : 0
} }
font.capitalization: theme.defaultFont.capitalization font.capitalization: theme.defaultFont.capitalization
font.family: theme.defaultFont.family font.family: theme.defaultFont.family
font.italic: theme.defaultFont.italic font.italic: theme.defaultFont.italic
@ -169,7 +227,7 @@ Item {
font.weight: theme.defaultFont.weight font.weight: theme.defaultFont.weight
font.wordSpacing: theme.defaultFont.wordSpacing font.wordSpacing: theme.defaultFont.wordSpacing
color: theme.buttonTextColor color: theme.buttonTextColor
horizontalAlignment: Text.AlignHCenter horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
} }
@ -179,25 +237,8 @@ Item {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onPressed: internal.pressButton()
onPressed: { onReleased: internal.releaseButton()
pressButton(); onCanceled: internal.releaseButton()
}
onReleased: {
releaseButton();
}
onEntered: {
shadow.state = "hover"
}
onExited: {
if (button.activeFocus) {
shadow.state = "focus"
} else if (checked) {
shadow.state = "hidden"
} else {
shadow.state = "shadow"
} }
} }
}
}

View File

@ -39,6 +39,7 @@ import org.kde.plasma.core 0.1 as PlasmaCore
Item { Item {
id: main id: main
state: parent.state state: parent.state
property bool hasOverState: true
PlasmaCore.FrameSvgItem { PlasmaCore.FrameSvgItem {
id: hover id: hover

View File

@ -38,24 +38,9 @@ DualStateButton {
view: PlasmaCore.FrameSvgItem { view: PlasmaCore.FrameSvgItem {
imagePath: "widgets/button" imagePath: "widgets/button"
prefix: "normal" prefix: "normal"
width: fontMetricText.height + margins.left width: theme.defaultFont.mSize.height + margins.left
height: fontMetricText.height + margins.top height: theme.defaultFont.mSize.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
}
PlasmaCore.SvgItem { PlasmaCore.SvgItem {
svg: PlasmaCore.Svg { svg: PlasmaCore.Svg {
id: checkmarkSvg 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 property alias shadow: shadowLoader.sourceComponent
width: surfaceLoader.width + label.paintedWidth 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 // TODO: needs to define if there will be specific graphics for
// disabled buttons // disabled buttons
opacity: dualButton.enabled ? 1.0 : 0.5 opacity: dualButton.enabled ? 1.0 : 0.5

View File

@ -35,6 +35,10 @@ import org.kde.plasma.core 0.1 as PlasmaCore
Text { Text {
id: root 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.capitalization: theme.defaultFont.capitalization
font.family: theme.defaultFont.family font.family: theme.defaultFont.family
font.italic: theme.defaultFont.italic 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 // PageStatus.Deactivating - the page is transitioning into becoming inactive
property int status: PageStatus.Inactive property int status: PageStatus.Inactive
property PageStack pageStack property Item pageStack
// Defines orientation lock for a page // Defines orientation lock for a page
property int orientationLock: PageOrientation.Automatic property int orientationLock: PageOrientation.Automatic
@ -89,18 +89,8 @@ Item {
width: visible && parent ? parent.width : internal.previousWidth width: visible && parent ? parent.width : internal.previousWidth
height: visible && parent ? parent.height : internal.previousHeight height: visible && parent ? parent.height : internal.previousHeight
onWidthChanged: internal.previousWidth = visible ? width : internal.previousWidth onWidthChanged: internal.previousWidth = (visible ? width : internal.previousWidth)
onHeightChanged: internal.previousHeight = visible ? height : internal.previousHeight onHeightChanged: internal.previousHeight = (visible ? height : internal.previousHeight)
onStatusChanged: {
if (status == PageStatus.Activating)
internal.orientationLockCheck();
}
onOrientationLockChanged: {
if (status == PageStatus.Activating || status == PageStatus.Active)
internal.orientationLockCheck();
}
// This is needed to make a parentless Page component visible in the Designer of QtCreator. // 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 // It's done here instead of binding the visible property because binding it to a script
@ -113,36 +103,5 @@ Item {
id: internal id: internal
property int previousWidth: 0 property int previousWidth: 0
property int previousHeight: 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.page = page;
if (page.parent == null) {
container.owner = container;
} else {
container.owner = page.parent; container.owner = page.parent;
}
// the page has to be reparented if // the page has to be reparented if
if (page.parent != container) { if (page.parent != container) {
@ -161,6 +165,8 @@ function initPage(page, properties) {
page.pageStack = root; page.pageStack = root;
} }
page.anchors.fill = container
return container; return container;
} }

View File

@ -204,8 +204,8 @@ Item {
// The owner of the page. // The owner of the page.
property Item owner: null property Item owner: null
// The width of the longer screen dimension // The width of the longer stack dimension
property int screenWidth: Math.max(screen.width, screen.height) property int stackWidth: Math.max(root.width, root.height)
// Duration of transition animation (in ms) // Duration of transition animation (in ms)
property int transitionDuration: 250 property int transitionDuration: 250
@ -308,9 +308,10 @@ Item {
{ {
transitionAnimationRunning = true; transitionAnimationRunning = true;
internal.ongoingTransitionCount++; internal.ongoingTransitionCount++;
if (root.visible) if (root.visible) {
internal.setPageStatus(page, (state == "") ? PageStatus.Activating : PageStatus.Deactivating); internal.setPageStatus(page, (state == "") ? PageStatus.Activating : PageStatus.Deactivating);
} }
}
// Called when a transition has ended. // Called when a transition has ended.
function transitionEnded() function transitionEnded()
@ -341,7 +342,7 @@ Item {
// when exiting portrait and entering landscape. // when exiting portrait and entering landscape.
State { State {
name: "LandscapeLeft" 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. // Start state for push entry, end state for pop exit.
State { State {
@ -352,7 +353,7 @@ Item {
// when exiting portrait and entering landscape. // when exiting portrait and entering landscape.
State { State {
name: "LandscapeRight" name: "LandscapeRight"
PropertyChanges { target: container; x: screenWidth / 2; opacity: 0 } PropertyChanges { target: container; x: stackWidth / 2; opacity: 0 }
}, },
// Inactive state. // Inactive state.
State { State {
@ -470,14 +471,17 @@ Item {
function cleanup() function cleanup()
{ {
if (page != null) { if (page != null) {
if (page.status == PageStatus.Active) if (page.status == PageStatus.Active) {
internal.setPageStatus(page, PageStatus.Inactive); internal.setPageStatus(page, PageStatus.Inactive)
}
if (owner != container) { if (owner != container) {
// container is not the owner of the page - re-parent back to original owner // container is not the owner of the page - re-parent back to original owner
page.visible = false; page.visible = false;
page.anchors.fill = undefined
page.parent = owner; page.parent = owner;
} }
} }
container.destroy(); container.destroy();
} }
} }

View File

@ -51,6 +51,7 @@ Properties:
import QtQuick 1.0 import QtQuick 1.0
import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.qtextracomponents 0.1
Item { Item {
id: progressBar id: progressBar
@ -64,9 +65,6 @@ Item {
// Plasma API // Plasma API
property int orientation: Qt.Horizontal property int orientation: Qt.Horizontal
// Convinience API
property bool _isVertical: orientation == Qt.Vertical
width: 100 width: 100
height: 20 height: 20
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
@ -86,26 +84,57 @@ Item {
Item { Item {
id: contents id: contents
property bool _isVertical: orientation == Qt.Vertical
width: _isVertical ? progressBar.height : progressBar.width width: _isVertical ? progressBar.height : progressBar.width
height: _isVertical ? progressBar.width : progressBar.height height: _isVertical ? progressBar.width : progressBar.height
rotation: _isVertical ? 90 : 0 rotation: _isVertical ? 90 : 0
anchors.centerIn: parent anchors.centerIn: parent
PlasmaCore.FrameSvgItem { Timer {
id: background id: resizeTimer
repeat: false
anchors.fill: parent interval: 0
imagePath: "widgets/bar_meter_horizontal" running: false
prefix: "bar-inactive" 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 height: contents.height
imagePath: "widgets/bar_meter_horizontal"
prefix: "bar-active"
visible: indeterminate || value > 0 visible: indeterminate || value > 0
SequentialAnimation { SequentialAnimation {
@ -114,16 +143,16 @@ Item {
loops: Animation.Infinite loops: Animation.Infinite
PropertyAnimation { PropertyAnimation {
target: bar; target: barPixmapItem
property: "x" property: "x"
duration: 800 duration: 800
to: 0 to: 0
} }
PropertyAnimation { PropertyAnimation {
target: bar; target: barPixmapItem
property: "x" property: "x"
duration: 800 duration: 800
to: background.width - bar.width to: backgroundPixmapItem.width - barPixmapItem.width
} }
} }
} }

View File

@ -44,24 +44,9 @@ DualStateButton {
imagePath: "widgets/actionbutton" imagePath: "widgets/actionbutton"
} }
elementId: "normal" elementId: "normal"
width: fontMetricText.height + 6 width: theme.defaultFont.mSize.height + 6
height: width 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 { PlasmaCore.SvgItem {
svg: PlasmaCore.Svg { svg: PlasmaCore.Svg {
id: checkmarkSvg id: checkmarkSvg

View File

@ -40,13 +40,19 @@ import org.kde.plasma.core 0.1 as PlasmaCore
Item { Item {
id: main id: main
state: parent.state 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 { PlasmaCore.SvgItem {
id: hover id: hover
svg: PlasmaCore.Svg { svg: shadowSvg
id: hoverSvg
imagePath: "widgets/actionbutton"
}
elementId: "hover" elementId: "hover"
anchors.fill: parent anchors.fill: parent
@ -56,10 +62,7 @@ Item {
PlasmaCore.SvgItem { PlasmaCore.SvgItem {
id: shadow id: shadow
svg: PlasmaCore.Svg { svg: shadowSvg
id: shadowSvg
imagePath: "widgets/actionbutton"
}
elementId: "shadow" elementId: "shadow"
anchors.fill: parent anchors.fill: parent
@ -75,7 +78,7 @@ Item {
PropertyChanges { PropertyChanges {
target: hover target: hover
opacity: 0 opacity: 0
elementId: "hover" elementId: hoverElement
} }
}, },
State { State {
@ -87,7 +90,7 @@ Item {
PropertyChanges { PropertyChanges {
target: hover target: hover
opacity: 1 opacity: 1
elementId: "hover" elementId: hoverElement
} }
}, },
State { State {
@ -99,11 +102,11 @@ Item {
PropertyChanges { PropertyChanges {
target: hover target: hover
opacity: 1 opacity: 1
elementId: "focus" elementId: focusElement
} }
}, },
State { State {
name: "hover" name: "hidden"
PropertyChanges { PropertyChanges {
target: shadow target: shadow
opacity: 0 opacity: 0
@ -111,7 +114,7 @@ Item {
PropertyChanges { PropertyChanges {
target: hover target: hover
opacity: 0 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 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 * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as * it under the terms of the GNU Library General Public License as
@ -61,36 +62,34 @@ Properties:
import QtQuick 1.1 import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore 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 { Item {
id: scrollbar id: scrollbar
// Common API // Common API
property Flickable flickableItem: null property Flickable flickableItem: null
property bool interactive property int orientation: Qt.Vertical
property bool interactive: true
// Plasma API // Plasma API
property int orientation: Qt.Vertical
property bool animated: true
property bool inverted: false property bool inverted: false
property bool updateValueWhileDragging: true
property alias stepSize: range.stepSize 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 property real scrollButtonInterval: 50
// Convinience API implicitWidth: internalLoader.isVertical ? (interactive ? 22 : 12) : 200
property bool _isVertical: orientation == Qt.Vertical implicitHeight: internalLoader.isVertical ? 200 : (interactive ? 22 : 12)
property bool _showButtons: stepSize != 0
property bool _inverted: _isVertical ?
!scrollbar.inverted : scrollbar.inverted
implicitWidth: _isVertical ? 22 : 200
implicitHeight: _isVertical ? 200 : 22
// TODO: needs to define if there will be specific graphics for // TODO: needs to define if there will be specific graphics for
// disabled scroll bars // disabled scroll bars
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
visible: flickableItem && handle.width < contents.width visible: flickableItem && internalLoader.handleEnabled
anchors { anchors {
right: flickableItem.right right: flickableItem.right
@ -99,300 +98,80 @@ Item {
bottom: flickableItem.bottom bottom: flickableItem.bottom
} }
function incrementValue(increment) { Loader {
id: internalLoader
anchors.fill: parent
//property bool handleEnabled: internalLoader.isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width
property bool handleEnabled: internalLoader.isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width
property bool isVertical: orientation == Qt.Vertical
function incrementValue(increment)
{
if (!flickableItem) if (!flickableItem)
return; return;
if (_isVertical) { if (internalLoader.isVertical) {
flickableItem.contentY = Math.min(flickableItem.contentHeight, flickableItem.contentY = Math.max(0, Math.min(flickableItem.contentHeight,
flickableItem.contentY + increment); flickableItem.contentY + increment))
} else { } else {
flickableItem.contentX = Math.min(flickableItem.contentWidth, flickableItem.contentX = Math.max(0, Math.min(flickableItem.contentWidth,
flickableItem.contentX + increment); flickableItem.contentX + increment))
} }
} }
Keys.onUpPressed: {
if (!enabled || !_isVertical)
return;
if (_inverted)
incrementValue(-stepSize);
else
incrementValue(stepSize);
}
Keys.onDownPressed: {
if (!enabled || !_isVertical)
return;
if (_inverted)
incrementValue(stepSize);
else
incrementValue(-stepSize);
}
Keys.onLeftPressed: {
if (!enabled || _isVertical)
return;
if (_inverted)
incrementValue(stepSize);
else
incrementValue(-stepSize);
}
Keys.onRightPressed: {
if (!enabled || _isVertical)
return;
if (_inverted)
incrementValue(-stepSize);
else
incrementValue(stepSize);
}
Item {
width: _isVertical ? scrollbar.height : scrollbar.width
height: _isVertical ? scrollbar.width : scrollbar.height
rotation: _isVertical ? -90 : 0
anchors.centerIn: parent
PlasmaCore.Svg {
id: scrollbarSvg
imagePath: "widgets/scrollbar"
}
PlasmaCore.SvgItem {
id: leftButton
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
height: 18
width: _showButtons ? 18 : 0
svg: scrollbarSvg
elementId: {
if (leftMousArea.pressed)
return "sunken-arrow-left";
if (scrollbar.activeFocus || leftMousArea.containsMouse)
return "mouseover-arrow-left";
else
return "arrow-left";
}
MouseArea {
id: leftMousArea
anchors.fill: parent
enabled: scrollbar.enabled
Timer {
id: leftTimer
interval: scrollbar.scrollButtonInterval;
running: parent.pressed
repeat: true
onTriggered: {
scrollbar.forceActiveFocus();
if (_inverted)
incrementValue(stepSize);
else
incrementValue(-stepSize);
}
}
}
}
PlasmaCore.SvgItem {
id: rightButton
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
height: 18
width: _showButtons ? 18 : 0
svg: scrollbarSvg
elementId: {
if (rightMousArea.pressed)
return "sunken-arrow-right";
if (scrollbar.activeFocus || rightMousArea.containsMouse)
return "mouseover-arrow-right";
else
return "arrow-right";
}
MouseArea {
id: rightMousArea
anchors.fill: parent
enabled: scrollbar.enabled
Timer {
id: rightTimer
interval: scrollbar.scrollButtonInterval;
running: parent.pressed;
repeat: true
onTriggered: {
scrollbar.forceActiveFocus();
if (_inverted)
incrementValue(-stepSize);
else
incrementValue(stepSize);
}
}
}
}
Item {
id: contents
anchors {
left: leftButton.right
top: parent.top
bottom: parent.bottom
right: rightButton.left
}
RangeModel { RangeModel {
id: range id: range
minimumValue: 0 minimumValue: 0
maximumValue: { maximumValue: {
var diff; var diff;
if (_isVertical) if (internalLoader.isVertical) {
diff = flickableItem.contentHeight - flickableItem.height; diff = flickableItem.contentHeight - flickableItem.height
else } else {
diff = flickableItem.contentWidth - flickableItem.width; diff = flickableItem.contentWidth - flickableItem.width
return Math.max(0, diff);
} }
return Math.max(0, diff)
}
stepSize: 10 stepSize: 10
inverted: _inverted inverted: scrollbar.inverted
positionAtMinimum: 0 + handle.width / 2 positionAtMinimum: 0
positionAtMaximum: contents.width - handle.width / 2 positionAtMaximum: {
value: _isVertical ? flickableItem.contentY : flickableItem.contentX 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: { onValueChanged: {
if (flickableItem.flicking) if (flickableItem.moving) {
return; return
if (_isVertical)
flickableItem.contentY = value;
else
flickableItem.contentX = value;
}
position: handle.x
onPositionChanged: { handle.x = position; }
} }
PlasmaCore.FrameSvgItem { if (internalLoader.isVertical) {
id: groove flickableItem.contentY = value
} else {
anchors.fill: parent flickableItem.contentX = value
imagePath: "widgets/scrollbar" }
prefix: "background-horizontal"
} }
PlasmaCore.FrameSvgItem { position: internalLoader.isVertical ? internalLoader.item.handle.y : internalLoader.item.handle.x
id: handle
transform: Translate { x: - handle.width / 2 } onPositionChanged: {
x: fakeHandle.x if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) {
anchors.verticalCenter: groove.verticalCenter return
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 { if (internalLoader.isVertical) {
id: behavior internalLoader.item.handle.y = position
enabled: !mouseArea.drag.active && scrollbar.animated && } else {
!flickableItem.flicking internalLoader.item.handle.x = position
PropertyAnimation {
duration: behavior.enabled ? 150 : 0
easing.type: Easing.OutSine
} }
} }
} }
Item { source: interactive ? "ScrollBarDelegate.qml" : "ScrollDecoratorDelegate.qml"
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
}
} }
} }

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() internal.initDirtyObserver()
} }
} }
onMovementStarted: root.opacity = 1
onMovementEnded: {
if (!dragArea.pressed) {
fadeTimer.restart()
}
}
} }
width: 48 width: 22
opacity: 0
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: 250 duration: 250
@ -107,15 +100,6 @@ Item {
bottom: listView.bottom bottom: listView.bottom
} }
Timer {
id: fadeTimer
interval: 4000
repeat: false
running: false
onTriggered: {
root.opacity = 0
}
}
RangeModel { RangeModel {
id: range id: range
@ -124,99 +108,42 @@ Item {
maximumValue: Math.max(0, listView.contentHeight - listView.height) maximumValue: Math.max(0, listView.contentHeight - listView.height)
stepSize: 0 stepSize: 0
//inverted: true //inverted: true
positionAtMinimum: handle.height / 2 positionAtMinimum: root.width*2
positionAtMaximum: root.height - handle.height - handle.height / 2 positionAtMaximum: root.height - root.width*2
value: listView.contentY value: listView.contentY
onValueChanged: { onPositionChanged: sectionLabel.text = Sections.closestSection(position/listView.height)
if (listView.moving) {
return
} else {
listView.contentY = value
}
}
//position: handle.y
onPositionChanged: {
if (!dragArea.pressed) {
handle.y = position
}
}
} }
Rectangle { ScrollBar {
id: scrollBar
flickableItem: listView
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(0,0,0,0.3) interactive: true
}
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 { PlasmaCore.FrameSvgItem {
imagePath: "widgets/tooltip" imagePath: "widgets/tooltip"
width: childrenRect.width + margins.left + margins.right width: sectionLabel.paintedWidth + margins.left + margins.right
height: childrenRect.height + margins.top + margins.bottom height: sectionLabel.paintedHeight + margins.top + margins.bottom
Label { Label {
id: sectionLabel id: sectionLabel
font.pointSize: theme.defaultFont.pointSize*3 font.pointSize: theme.defaultFont.pointSize*3
x: parent.margins.left x: parent.margins.left
y: parent.margins.top 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 { anchors {
//verticalCenter: handle.verticalCenter //verticalCenter: handle.verticalCenter
right: parent.left right: parent.left
} }
opacity: dragArea.pressed?1:0 opacity: sectionLabel.text && scrollBar.pressed?1:0
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: 250 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 { QtObject {
id: internal 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 bool updateValueWhileDragging: true
property real handleSize: 22 property real handleSize: 22
// Convinience API // Convenience API
property bool _isVertical: orientation == Qt.Vertical property bool _isVertical: orientation == Qt.Vertical
width: _isVertical ? 22 : 200 width: _isVertical ? theme.defaultFont.mSize.height*1.8 : 200
height: _isVertical ? 200 : 22 height: _isVertical ? 200 : theme.defaultFont.mSize.height*1.8
// TODO: needs to define if there will be specific graphics for // TODO: needs to define if there will be specific graphics for
// disabled sliders // disabled sliders
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
@ -151,8 +151,8 @@ Item {
value: 0 value: 0
stepSize: 0.0 stepSize: 0.0
inverted: false inverted: false
positionAtMinimum: 0 + handle.width / 2 positionAtMinimum: 0
positionAtMaximum: contents.width - handle.width / 2 positionAtMaximum: contents.width - handle.width
} }
PlasmaCore.Svg { PlasmaCore.Svg {
@ -176,51 +176,26 @@ Item {
imagePath: "widgets/slider" imagePath: "widgets/slider"
prefix: "groove-highlight" prefix: "groove-highlight"
height: groove.height 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 x: inverted ? handle.x : 0
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: range.position > 0 && slider.enabled visible: range.position > 0 && slider.enabled
} }
PlasmaCore.SvgItem { RoundShadow {
id: focus id: shadow
imagePath: "widgets/slider"
transform: Translate { x: - handle.width / 2 } focusElement: "horizontal-slider-focus"
anchors { hoverElement: "horizontal-slider-hover"
fill: handle shadowElement: "horizontal-slider-shadow"
margins: -1 // Hardcoded state: slider.activeFocus ? "focus" : (mouseArea.containsMouse ? "hover" : "shadow")
} anchors.fill: handle
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 }
}
} }
PlasmaCore.SvgItem { PlasmaCore.SvgItem {
id: handle id: handle
transform: Translate { x: - handle.width / 2 }
x: fakeHandle.x x: fakeHandle.x
anchors { anchors {
verticalCenter: groove.verticalCenter verticalCenter: groove.verticalCenter
@ -245,7 +220,6 @@ Item {
id: fakeHandle id: fakeHandle
width: handle.width width: handle.width
height: handle.height height: handle.height
transform: Translate { x: - handle.width / 2 }
} }
MouseArea { MouseArea {
@ -261,33 +235,25 @@ Item {
} }
hoverEnabled: true hoverEnabled: true
onEntered: {
hover.opacity = 1;
}
onExited: {
if (!pressed)
hover.opacity = 0;
}
onPressed: { onPressed: {
// Clamp the value // Clamp the value
var newX = Math.max(mouse.x, drag.minimumX); var newX = Math.max(mouse.x, drag.minimumX)
newX = Math.min(newX, drag.maximumX); newX = Math.min(newX, drag.maximumX)
// Debounce the press: a press event inside the handler will not // Debounce the press: a press event inside the handler will not
// change its position, the user needs to drag it. // change its position, the user needs to drag it.
if (Math.abs(newX - fakeHandle.x) > handle.width / 2) if (Math.abs(newX - fakeHandle.x) > handle.width / 2) {
range.position = newX; range.position = newX
}
slider.forceActiveFocus(); slider.forceActiveFocus()
} }
onReleased: { onReleased: {
// If we don't update while dragging, this is the only // If we don't update while dragging, this is the only
// moment that the range is updated. // moment that the range is updated.
if (!slider.updateValueWhileDragging) if (!slider.updateValueWhileDragging) {
range.position = fakeHandle.x; range.position = fakeHandle.x
}
if (!containsMouse)
hover.opacity = 0;
} }
} }
} }

View File

@ -40,13 +40,7 @@ DualStateButton {
imagePath: "widgets/slider" imagePath: "widgets/slider"
prefix: "groove" prefix: "groove"
width: height * 2 width: height * 2
height: fontMetricText.height + margins.top height: theme.defaultFont.mSize.height + margins.top
//FIXME: an hack to have font metrics: can we have a proper binding?
Text {
id: fontMetricText
text: "M"
visible: false
}
PlasmaCore.FrameSvgItem { PlasmaCore.FrameSvgItem {
id: highlight id: highlight

View File

@ -69,9 +69,9 @@ Item {
property alias layout: tabBarLayout property alias layout: tabBarLayout
//Plasma extension //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 implicitHeight: tabBarLayout.implicitHeight + backgroundFrame.margins.top + backgroundFrame.margins.bottom + buttonFrame.margins.top + buttonFrame.margins.bottom
PlasmaCore.FrameSvgItem { PlasmaCore.FrameSvgItem {
@ -85,10 +85,10 @@ Item {
PlasmaCore.FrameSvgItem { PlasmaCore.FrameSvgItem {
id: buttonFrame id: buttonFrame
x: currentItem.x + backgroundFrame.margins.left x: currentTab.x + backgroundFrame.margins.left
y: backgroundFrame.margins.top y: backgroundFrame.margins.top
width: currentItem.width + buttonFrame.margins.left + buttonFrame.margins.right width: currentTab.width + buttonFrame.margins.left + buttonFrame.margins.right
height: currentItem.height + buttonFrame.margins.top + buttonFrame.margins.bottom height: currentTab.height + buttonFrame.margins.top + buttonFrame.margins.bottom
imagePath: "widgets/button" imagePath: "widgets/button"
prefix: "normal" prefix: "normal"
Behavior on x { Behavior on x {

View File

@ -67,15 +67,18 @@ Item {
Keys.onPressed: { Keys.onPressed: {
if (event.key == Qt.Key_Right || event.key == Qt.Key_Left) { if (event.key == Qt.Key_Right || event.key == Qt.Key_Left) {
if (event.key == Qt.Key_Right || priv.mirrored) { if (event.key == Qt.Key_Right || priv.mirrored) {
var oldIndex = priv.currentButtonIndex() var oldIndex = priv.currentButtonIndex();
if (oldIndex != root.children.length - 1) { if (oldIndex != root.children.length - 1) {
priv.tabGroup.currentTab = root.children[oldIndex + 1].tab priv.tabGroup.currentTab = root.children[oldIndex + 1].tab
root.parent.currentTab = root.children[oldIndex + 1]
event.accepted = true event.accepted = true
} }
} else if (event.key == Qt.Key_Left || priv.mirrored) { } else if (event.key == Qt.Key_Left || priv.mirrored) {
var oldIndex = priv.currentButtonIndex() var oldIndex = priv.currentButtonIndex()
if (oldIndex != 0) { if (oldIndex != 0) {
priv.tabGroup.currentTab = root.children[oldIndex - 1].tab priv.tabGroup.currentTab = root.children[oldIndex - 1].tab
root.parent.currentTab = root.children[oldIndex - 1]
event.accepted = true event.accepted = true
} }
} }
@ -88,7 +91,7 @@ Item {
id: priv id: priv
property Item firstButton: root.children.length > 0 ? root.children[0] : null property Item firstButton: root.children.length > 0 ? root.children[0] : null
property Item firstTab: firstButton ? (firstButton.tab != null ? firstButton.tab : null) : 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 property bool mirrored: root.LayoutMirroring.enabled
onMirroredChanged: layoutChildren() onMirroredChanged: layoutChildren()
@ -106,19 +109,19 @@ Item {
var contentWidth = 0 var contentWidth = 0
var contentHeight = 0 var contentHeight = 0
if (childCount != 0) { if (childCount != 0) {
var itemWidth = root.width / childCount var itemWidth = (root.width - (childCount-1)*10) / childCount
var itemIndex = mirrored ? childCount - 1 : 0 var itemIndex = mirrored ? childCount - 1 : 0
var increment = mirrored ? - 1 : 1 var increment = mirrored ? - 1 : 1
for (var i = 0; i < childCount; ++i, itemIndex += increment) { for (var i = 0; i < childCount; ++i, itemIndex += increment) {
var child = root.children[itemIndex] var child = root.children[itemIndex]
child.x = i * itemWidth child.x = i * itemWidth + i*10
child.y = 0 child.y = 0
child.width = itemWidth child.width = itemWidth
child.height = root.height child.height = root.height
if (child.implicitWidth != undefined) { 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)) contentHeight = Math.max(contentHeight, (child.implicitHeight + buttonFrame.margins.top + buttonFrame.margins.bottom))
} }
} }

View File

@ -94,7 +94,7 @@ Item {
target: root target: root
onPressedChanged: { onPressedChanged: {
//TabBar is the granparent //TabBar is the granparent
root.parent.parent.currentItem = root root.parent.parent.currentTab = root
} }
} }
@ -113,7 +113,7 @@ Item {
Component.onCompleted: { Component.onCompleted: {
if (internal.tabGroup.currentTab == tab) { if (internal.tabGroup.currentTab == tab) {
parent.parent.currentItem = root parent.parent.currentTab = root
} }
} }
} }
@ -157,7 +157,7 @@ Item {
internal.tabGroup.currentTab = tab internal.tabGroup.currentTab = tab
} }
//TabBar is the granparent, done here too in case of no tabgroup //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 anchors.fill: parent

View File

@ -165,7 +165,6 @@ Item {
property alias interactive: flickArea.interactive property alias interactive: flickArea.interactive
property alias contentMaxWidth: textEdit.width property alias contentMaxWidth: textEdit.width
property alias contentMaxHeight: textEdit.height property alias contentMaxHeight: textEdit.height
property real scrollWidth: 22
// Set active focus to it's internal textInput. // Set active focus to it's internal textInput.
// Overriding QtQuick.Item forceActiveFocus function. // Overriding QtQuick.Item forceActiveFocus function.
@ -178,32 +177,12 @@ Item {
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
PlasmaCore.FrameSvgItem { TextFieldFocus {
id: hover id: hover
state: textArea.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden")
anchors { anchors.fill: base
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
}
}
}
MouseArea { MouseArea {
id: mouseWatcher id: mouseWatcher
anchors.fill: hover anchors.fill: hover
@ -215,11 +194,7 @@ Item {
// TODO: see what is the best policy for margins // TODO: see what is the best policy for margins
anchors { anchors {
fill: flickArea fill: parent
leftMargin: -2 * base.margins.left
rightMargin: -2 * base.margins.right
topMargin: -2 * base.margins.top
bottomMargin: -2 * base.margins.bottom
} }
imagePath: "widgets/lineedit" imagePath: "widgets/lineedit"
prefix: "base" prefix: "base"
@ -229,10 +204,12 @@ Item {
id: flickArea id: flickArea
anchors { anchors {
fill: parent fill: parent
rightMargin: scrollWidth leftMargin: 2 * base.margins.left
bottomMargin: scrollWidth 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: { contentWidth: {
if (textEdit.wrapMode == TextEdit.NoWrap) if (textEdit.wrapMode == TextEdit.NoWrap)
return textEdit.paintedWidth; return textEdit.paintedWidth;
@ -260,6 +237,7 @@ Item {
font.weight: theme.defaultFont.weight font.weight: theme.defaultFont.weight
font.wordSpacing: theme.defaultFont.wordSpacing font.wordSpacing: theme.defaultFont.wordSpacing
color: theme.viewTextColor color: theme.viewTextColor
selectByMouse: verticalScroll.interactive
onCursorPositionChanged: { onCursorPositionChanged: {
if (cursorRectangle.x < flickArea.contentX) { if (cursorRectangle.x < flickArea.contentX) {
@ -310,7 +288,6 @@ Item {
} }
enabled: parent.enabled enabled: parent.enabled
flickableItem: flickArea flickableItem: flickArea
height: visible ? scrollWidth : 0
orientation: Qt.Horizontal orientation: Qt.Horizontal
stepSize: textEdit.font.pixelSize stepSize: textEdit.font.pixelSize
} }
@ -324,7 +301,6 @@ Item {
} }
enabled: parent.enabled enabled: parent.enabled
flickableItem: flickArea flickableItem: flickArea
width: visible ? scrollWidth : 0
orientation: Qt.Vertical orientation: Qt.Vertical
stepSize: textEdit.font.pixelSize stepSize: textEdit.font.pixelSize
} }

View File

@ -119,6 +119,9 @@ Item {
property alias text: textInput.text property alias text: textInput.text
property alias maximumLength: textInput.maximumLength property alias maximumLength: textInput.maximumLength
//Plasma api
property bool clearButtonShown: false
function copy() { function copy() {
textInput.copy(); textInput.copy();
} }
@ -162,12 +165,18 @@ Item {
property alias activeFocus: textInput.activeFocus property alias activeFocus: textInput.activeFocus
// TODO: fix default size // TODO: fix default size
implicitWidth: 100 implicitWidth: theme.defaultFont.mSize.width*12
implicitHeight: 26 implicitHeight: theme.defaultFont.mSize.height*1.8
// TODO: needs to define if there will be specific graphics for // TODO: needs to define if there will be specific graphics for
// disabled text fields // disabled text fields
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
TextFieldFocus {
id: hover
state: textInput.activeFocus ? "focus" : (mouseWatcher.containsMouse ? "hover" : "hidden")
anchors.fill: base
}
PlasmaCore.FrameSvgItem { PlasmaCore.FrameSvgItem {
id: base id: base
@ -177,32 +186,6 @@ Item {
prefix: "base" 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 { MouseArea {
id: mouseWatcher id: mouseWatcher
anchors.fill: hover anchors.fill: hover
@ -210,7 +193,13 @@ Item {
} }
Text { 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 text: placeholderText
visible: textInput.text == "" && !textField.activeFocus visible: textInput.text == "" && !textField.activeFocus
// XXX: using textColor and low opacity for theming placeholderText // XXX: using textColor and low opacity for theming placeholderText
@ -235,12 +224,12 @@ Item {
anchors { anchors {
left: parent.left left: parent.left
right: parent.right right: parent.right
verticalCenter: parent.verticalCenter
// TODO: see what is the correct policy for margins // TODO: see what is the correct policy for margins
leftMargin: 2 * base.margins.left leftMargin: 2 * base.margins.left
rightMargin: 2 * base.margins.right rightMargin: 2 * base.margins.right
} }
y: (height - font.pixelSize) * 0.4 // XXX: verticalCenter anchor is not centering the text selectByMouse: true
height: Math.min(2 * font.pixelSize, parent.height)
color: theme.textColor color: theme.textColor
enabled: textField.enabled enabled: textField.enabled
clip: true clip: true
@ -250,4 +239,30 @@ Item {
Keys.onPressed: textField.Keys.pressed(event); Keys.onPressed: textField.Keys.pressed(event);
Keys.onReleased: textField.Keys.released(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 QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.plasma.core 0.1 as PlasmaCore
PlasmaCore.FrameSvgItem { Item{
id: toolBar id: toolBar
imagePath: "widgets/frame"
prefix: "raised"
width: parent.width 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. // The current set of tools; null if none.
property Item tools property Item tools
@ -71,7 +77,11 @@ PlasmaCore.FrameSvgItem {
toolBar.transition = transition toolBar.transition = transition
toolBar.tools = tools toolBar.tools = tools
} }
onToolsChanged: { Connections {
id: connection
target: toolBar
function internalToolsChanged()
{
var newContainer var newContainer
var oldContainer var oldContainer
if (containerA.current) { if (containerA.current) {
@ -92,20 +102,20 @@ PlasmaCore.FrameSvgItem {
switch (transition) { switch (transition) {
case "push": case "push":
containerA.animationsEnabled = true containerA.animationsEnabled = true
oldContainer.x = -oldContainer.width oldContainer.x = -oldContainer.width/2
containerA.animationsEnabled = false containerA.animationsEnabled = false
newContainer.x = newContainer.width newContainer.x = newContainer.width/2
newContainer.y = 0 newContainer.y = 0
containerA.animationsEnabled = true containerA.animationsEnabled = true
newContainer.x = 0 newContainer.x = 0
break break
case "pop": case "pop":
containerA.animationsEnabled = true containerA.animationsEnabled = true
oldContainer.x = oldContainer.width oldContainer.x = oldContainer.width/2
containerA.animationsEnabled = false containerA.animationsEnabled = false
newContainer.x = -newContainer.width newContainer.x = -newContainer.width/2
newContainer.y = 0 newContainer.y = 0
containerA.animationsEnabled = true containerA.animationsEnabled = true
newContainer.x = 0 newContainer.x = 0
@ -124,7 +134,7 @@ PlasmaCore.FrameSvgItem {
default: default:
containerA.animationsEnabled = false containerA.animationsEnabled = false
containerA.animationsEnabled = false containerA.animationsEnabled = false
oldContainer.x = -oldContainer.width oldContainer.x = -oldContainer.width/2
newContainer.x = 0 newContainer.x = 0
break break
} }
@ -132,14 +142,32 @@ PlasmaCore.FrameSvgItem {
newContainer.opacity = 1 newContainer.opacity = 1
oldContainer.opacity = 0 oldContainer.opacity = 0
} }
onToolsChanged: connection.internalToolsChanged()
Component.onCompleted: connection.internalToolsChanged()
}
Item { PlasmaCore.FrameSvgItem {
id: frameSvg
imagePath: "widgets/frame"
prefix: "raised"
anchors { anchors {
fill: parent fill: parent
leftMargin: parent.margins.left leftMargin: -margins.left
topMargin: parent.margins.top rightMargin: -margins.right
rightMargin: parent.margins.right //FIXME: difference between actial border and shadow
bottomMargin: parent.margins.bottom topMargin: toolBar.y <= 0 ? -margins.top : -margins.top/2
bottomMargin: toolBar.y >= toolBar.parent.height - toolBar.height ? -margins.bottom : -margins.bottom/2
}
}
Item {
clip: containerAOpacityAnimation.running || heightAnimation.running
anchors {
fill: parent
leftMargin: frameSvg.margins.left/2
topMargin: frameSvg.margins.top/2
rightMargin: frameSvg.margins.right/2
bottomMargin: frameSvg.margins.bottom/2
} }
Item { Item {
@ -151,7 +179,10 @@ PlasmaCore.FrameSvgItem {
//this asymmetry just to not export a property //this asymmetry just to not export a property
property bool current: false property bool current: false
Behavior on opacity { Behavior on opacity {
PropertyAnimation { duration: 250 } PropertyAnimation {
id: containerAOpacityAnimation
duration: 250
}
} }
Behavior on x { Behavior on x {
enabled: containerA.animationsEnabled 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 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 * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as * it under the terms of the GNU Library General Public License as
@ -76,41 +77,26 @@ Item {
surface.opacity = 1 surface.opacity = 1
} }
function pressButton() {
if (button.enabled) implicitWidth: {
surface.prefix = "pressed"; 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();
} }
implicitHeight: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom)
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)
// TODO: needs to define if there will be specific graphics for // TODO: needs to define if there will be specific graphics for
// disabled buttons // disabled buttons
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
Keys.onSpacePressed: pressButton(); Keys.onSpacePressed: internal.pressButton()
Keys.onReturnPressed: pressButton(); Keys.onReturnPressed: internal.pressButton()
Keys.onReleased: { Keys.onReleased: {
if (event.key == Qt.Key_Space || if (event.key == Qt.Key_Space ||
event.key == Qt.Key_Return) event.key == Qt.Key_Return)
releaseButton(); internal.releaseButton()
} }
onActiveFocusChanged: { 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 { ButtonShadow {
id: shadow id: shadow
anchors.fill: parent anchors.fill: parent
@ -134,8 +145,9 @@ Item {
anchors.fill: parent anchors.fill: parent
imagePath: "widgets/button" imagePath: "widgets/button"
prefix: "normal" prefix: (internal.userPressed || checked) ? "pressed" : "normal"
opacity: 0 //internal: if there is no hover status, don't paint on mouse over in touchscreens
opacity: (internal.userPressed || checked || !flat || (shadow.hasOverState && mouse.containsMouse)) ? 1 : 0
Behavior on opacity { Behavior on opacity {
PropertyAnimation { duration: 250 } PropertyAnimation { duration: 250 }
} }
@ -179,7 +191,7 @@ Item {
font.weight: theme.defaultFont.weight font.weight: theme.defaultFont.weight
font.wordSpacing: theme.defaultFont.wordSpacing font.wordSpacing: theme.defaultFont.wordSpacing
color: theme.buttonTextColor color: theme.buttonTextColor
horizontalAlignment: Text.AlignHCenter horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
} }
@ -190,23 +202,17 @@ Item {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onPressed: { onPressed: internal.pressButton();
pressButton();
} onReleased: internal.releaseButton();
onReleased: {
releaseButton();
}
onEntered: { onEntered: {
if (flat) { if (!flat) {
surface.opacity = 1
} else {
shadow.state = "hover" shadow.state = "hover"
} }
} }
onExited: { onExited: {
if (flat) { if (!flat) {
surface.opacity = 0
} else {
if (button.activeFocus) { if (button.activeFocus) {
shadow.state = "focus" shadow.state = "focus"
} else if (checked) { } else if (checked) {

View File

@ -15,19 +15,20 @@ ProgressBar 0.1 ProgressBar.qml
PushButton 0.1 PushButton.qml PushButton 0.1 PushButton.qml
RadioButton 0.1 RadioButton.qml RadioButton 0.1 RadioButton.qml
ScrollBar 0.1 ScrollBar.qml ScrollBar 0.1 ScrollBar.qml
ScrollDecorator 0.1 ScrollDecorator.qml
Slider 0.1 Slider.qml Slider 0.1 Slider.qml
Switch 0.1 Switch.qml Switch 0.1 Switch.qml
TextArea 0.1 TextArea.qml TextArea 0.1 TextArea.qml
TextField 0.1 TextField.qml TextField 0.1 TextField.qml
ToolBar 0.1 ToolBar.qml ToolBar 0.1 ToolBar.qml
ToolButton 0.1 ToolButton.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 Page 0.1 Page.qml
PageStack 0.1 PageStack.qml PageStack 0.1 PageStack.qml
Window 0.1 Window.qml
TabBar 0.1 TabBar.qml TabBar 0.1 TabBar.qml
TabButton 0.1 TabButton.qml TabButton 0.1 TabButton.qml

View File

@ -19,7 +19,7 @@ qt4_automoc(${qtextracomponents_SRCS})
add_library(qtextracomponentsplugin SHARED ${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) install(TARGETS qtextracomponentsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/qtextracomponents)

View File

@ -19,6 +19,7 @@
#include "qiconitem.h" #include "qiconitem.h"
#include <kicon.h>
#include <QtGui/QPainter> #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(); update();
} }

View File

@ -21,19 +21,20 @@
#include <QDeclarativeItem> #include <QDeclarativeItem>
#include <QPixmap> #include <QPixmap>
#include <QVariant>
class QIconItem : public QDeclarativeItem class QIconItem : public QDeclarativeItem
{ {
Q_OBJECT 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) Q_PROPERTY(bool smooth READ smooth WRITE setSmooth)
public: public:
QIconItem(QDeclarativeItem *parent=0); QIconItem(QDeclarativeItem *parent=0);
~QIconItem(); ~QIconItem();
void setIcon(const QIcon &icon); void setIcon(const QVariant &icon);
QIcon icon() const; QIcon icon() const;
void setSmooth(const bool smooth); void setSmooth(const bool smooth);

View File

@ -24,7 +24,8 @@
QImageItem::QImageItem(QDeclarativeItem *parent) QImageItem::QImageItem(QDeclarativeItem *parent)
: QDeclarativeItem(parent), : QDeclarativeItem(parent),
m_smooth(false) m_smooth(false),
m_fillMode(QImageItem::Stretch)
{ {
setFlag(QGraphicsItem::ItemHasNoContents, false); setFlag(QGraphicsItem::ItemHasNoContents, false);
} }
@ -71,6 +72,22 @@ int QImageItem::nativeHeight() const
return m_image.size().height(); 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) void QImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
Q_UNUSED(option); Q_UNUSED(option);
@ -79,15 +96,51 @@ void QImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
if (m_image.isNull()) { if (m_image.isNull()) {
return; return;
} }
//do without painter save, faster and the support can be compiled out painter->save();
const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing);
const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform);
painter->setRenderHint(QPainter::Antialiasing, m_smooth); painter->setRenderHint(QPainter::Antialiasing, m_smooth);
painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
painter->drawImage(boundingRect(), m_image, m_image.rect()); QRect destRect;
painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); switch (m_fillMode) {
painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); 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(bool smooth READ smooth WRITE setSmooth)
Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged) Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged)
Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged) Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged)
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_ENUMS(FillMode)
public: 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(QDeclarativeItem *parent=0);
~QImageItem(); ~QImageItem();
@ -44,15 +55,20 @@ public:
int nativeWidth() const; int nativeWidth() const;
int nativeHeight() const; int nativeHeight() const;
FillMode fillMode() const;
void setFillMode(FillMode mode);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
Q_SIGNALS: Q_SIGNALS:
void nativeWidthChanged(); void nativeWidthChanged();
void nativeHeightChanged(); void nativeHeightChanged();
void fillModeChanged();
private: private:
QImage m_image; QImage m_image;
bool m_smooth; bool m_smooth;
FillMode m_fillMode;
}; };
#endif #endif

View File

@ -24,7 +24,8 @@
QPixmapItem::QPixmapItem(QDeclarativeItem *parent) QPixmapItem::QPixmapItem(QDeclarativeItem *parent)
: QDeclarativeItem(parent), : QDeclarativeItem(parent),
m_smooth(false) m_smooth(false),
m_fillMode(QPixmapItem::Stretch)
{ {
setFlag(QGraphicsItem::ItemHasNoContents, false); setFlag(QGraphicsItem::ItemHasNoContents, false);
} }
@ -71,6 +72,22 @@ int QPixmapItem::nativeHeight() const
return m_pixmap.size().height(); 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) void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
Q_UNUSED(option); Q_UNUSED(option);
@ -79,15 +96,51 @@ void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
if (m_pixmap.isNull()) { if (m_pixmap.isNull()) {
return; return;
} }
//do without painter save, faster and the support can be compiled out painter->save();
const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing);
const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform);
painter->setRenderHint(QPainter::Antialiasing, m_smooth); painter->setRenderHint(QPainter::Antialiasing, m_smooth);
painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
painter->drawPixmap(boundingRect(), m_pixmap, m_pixmap.rect()); QRect destRect;
painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); switch (m_fillMode) {
painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); 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(bool smooth READ smooth WRITE setSmooth)
Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged) Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged)
Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged) Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged)
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_ENUMS(FillMode)
public: 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(QDeclarativeItem *parent=0);
~QPixmapItem(); ~QPixmapItem();
@ -44,15 +55,20 @@ public:
int nativeWidth() const; int nativeWidth() const;
int nativeHeight() const; int nativeHeight() const;
FillMode fillMode() const;
void setFillMode(FillMode mode);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
Q_SIGNALS: Q_SIGNALS:
void nativeWidthChanged(); void nativeWidthChanged();
void nativeHeightChanged(); void nativeHeightChanged();
void fillModeChanged();
private: private:
QPixmap m_pixmap; QPixmap m_pixmap;
bool m_smooth; bool m_smooth;
FillMode m_fillMode;
}; };
#endif #endif

View File

@ -20,6 +20,22 @@
import QtQuick 1.0 import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1 as PlasmaComponents
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.ProgressBar {
value: 0.3
}
PlasmaComponents.TextField {
text: "Busy widgets"
}
}
Column { Column {
spacing: 20 spacing: 20
@ -76,3 +92,4 @@ Column {
} }
} }
} }
}

View File

@ -20,6 +20,19 @@
import QtQuick 1.0 import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1 as PlasmaComponents
PlasmaComponents.Page {
height: childrenRect.height
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.Button {
text: "Button"
}
PlasmaComponents.Button {
text: "toolbar of the Buttons page"
}
PlasmaComponents.TextField {}
}
Column { Column {
spacing: 20 spacing: 20
@ -97,3 +110,4 @@ Column {
enabled: false enabled: false
} }
} }
}

View File

@ -20,6 +20,23 @@
import QtQuick 1.0 import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1 as PlasmaComponents
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.CheckBox {
text: "Checkbox in the toolbar"
}
PlasmaComponents.TextField {
text: "hello"
}
}
Column { Column {
spacing: 20 spacing: 20
@ -105,3 +122,4 @@ Column {
} }
} }
}

View File

@ -18,14 +18,14 @@
*/ */
import QtQuick 1.0 import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1
Rectangle { Rectangle {
width: 1000 width: 1000
height: 800 height: 800
color: "lightgrey" color: "lightgrey"
PlasmaComponents.ToolBar { ToolBar {
id: toolBar id: toolBar
z: 10 z: 10
anchors { anchors {
@ -33,76 +33,88 @@ Rectangle {
left: parent.left left: parent.left
right: parent.right right: parent.right
} }
tools: toolbarA
} }
Row {
id: toolbarA
visible: false ListView {
spacing: 5 id: pageSelector
PlasmaComponents.ToolButton { width: 200
text: "Switch toolbar" anchors {
onClicked: toolBar.setTools(toolbarB, "push") top: toolBar.bottom
bottom: parent.bottom
} }
PlasmaComponents.ToolButton { model: ListModel {
text: "button on first toolbar" id: pagesModel
ListElement {
page: "Buttons.qml"
title: "Buttons"
}
ListElement {
page: "CheckableButtons.qml"
title: "Checkable buttons"
}
ListElement {
page: "Busy.qml"
title: "Busy indicators"
}
ListElement {
page: "Sliders.qml"
title: "Sliders"
}
ListElement {
page: "Scrollers.qml"
title: "Scrollers"
}
ListElement {
page: "Texts.qml"
title: "Text elements"
}
ListElement {
page: "Misc.qml"
title: "Misc stuff"
} }
} }
Row { delegate: ListItem {
id: toolbarB enabled: true
visible: false Column {
spacing: 5 Label {
PlasmaComponents.ToolButton { text: title
text: "Switch toolbar"
onClicked: toolBar.setTools(toolbarA, "pop")
} }
PlasmaComponents.ToolButton {
flat: false
text: "button on second toolbar"
} }
PlasmaComponents.TextField {} onClicked: pageStack.replace(Qt.createComponent(page))
} }
}
Flickable { Flickable {
id: page id: page
anchors { anchors {
top: toolBar.bottom top: toolBar.bottom
left: parent.left left: pageSelector.right
right: parent.right right: parent.right
bottom: parent.bottom bottom: parent.bottom
} }
contentWidth: 2200 contentWidth: pageStack.currentPage.implicitWidth
contentHeight: 1000 contentHeight: pageStack.currentPage.implicitHeight
Row { PageStack {
x: 30 id: pageStack
anchors { toolBar: toolBar
top: parent.top width: page.width
bottom: parent.bottom height: currentPage.implicitHeight
margins: 20 initialPage: Qt.createComponent("Buttons.qml")
}
spacing: 30
Buttons{ }
CheckableButtons { }
Busy { }
Sliders { }
Scrollers { }
Texts { }
}
} }
PlasmaComponents.ScrollBar { }
ScrollBar {
id: horizontalScrollBar id: horizontalScrollBar
stepSize: 30 stepSize: 30
flickableItem: page flickableItem: page
animated: true orientation: Qt.Horizontal
anchors { anchors {
left: parent.left left: parent.left
right: verticalScrollBar.left right: verticalScrollBar.left
@ -110,14 +122,13 @@ Rectangle {
} }
} }
PlasmaComponents.ScrollBar { ScrollBar {
id: verticalScrollBar id: verticalScrollBar
stepSize: 30 stepSize: 30
orientation: Qt.Vertical orientation: Qt.Vertical
flickableItem: page flickableItem: page
animated: true
anchors { anchors {
top: toolBar.bottom top: toolBar.bottom
right: parent.right 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,6 +20,25 @@
import QtQuick 1.0 import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1 as PlasmaComponents
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.ScrollBar {
orientation: Qt.Horizontal
interactive: true
flickableItem: scrollArea
width: 200
}
PlasmaComponents.TextField {
text: "hello"
}
}
Column { Column {
spacing: 20 spacing: 20
@ -52,7 +71,6 @@ Column {
id: scrollBar id: scrollBar
orientation: Qt.Vertical orientation: Qt.Vertical
flickableItem: scrollList flickableItem: scrollList
animated: true
stepSize: 40 stepSize: 40
scrollButtonInterval: 50 scrollButtonInterval: 50
anchors { anchors {
@ -102,7 +120,7 @@ Column {
} }
// Scroll Decorators // Scroll Decorators
PlasmaComponents.ScrollDecorator { PlasmaComponents.ScrollBar {
orientation: Qt.Vertical orientation: Qt.Vertical
flickableItem: scrollArea flickableItem: scrollArea
inverted: true inverted: true
@ -118,7 +136,7 @@ Column {
text: "inverted" text: "inverted"
} }
} }
PlasmaComponents.ScrollDecorator { PlasmaComponents.ScrollBar {
orientation: Qt.Horizontal orientation: Qt.Horizontal
flickableItem: scrollArea flickableItem: scrollArea
anchors { anchors {
@ -129,3 +147,4 @@ Column {
} }
} }
} }
}

View File

@ -20,6 +20,24 @@
import QtQuick 1.0 import QtQuick 1.0
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1 as PlasmaComponents
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.Slider {
width: 140
animated: true
enabled: true
}
PlasmaComponents.TextField {
text: "hello"
}
}
Column { Column {
spacing: 20 spacing: 20
@ -49,7 +67,6 @@ Column {
minimumValue: 0 minimumValue: 0
maximumValue: 255 maximumValue: 255
stepSize: 10 stepSize: 10
animated: true
Keys.onTabPressed: greenSlider.forceActiveFocus() Keys.onTabPressed: greenSlider.forceActiveFocus()
} }
@ -77,7 +94,6 @@ Column {
minimumValue: 0 minimumValue: 0
maximumValue: 255 maximumValue: 255
stepSize: 10 stepSize: 10
animated: true
Keys.onTabPressed: redSlider.forceActiveFocus() Keys.onTabPressed: redSlider.forceActiveFocus()
} }
@ -130,3 +146,4 @@ Column {
} }
} }
}

View File

@ -20,6 +20,25 @@
import QtQuick 1.1 import QtQuick 1.1
import org.kde.plasma.components 0.1 as PlasmaComponents import org.kde.plasma.components 0.1 as PlasmaComponents
PlasmaComponents.Page {
height: childrenRect.height
property int implicitHeight: childrenRect.height
tools: PlasmaComponents.ToolBarLayout {
spacing: 5
PlasmaComponents.Label {
text: "Text label:"
}
PlasmaComponents.ToolButton {
text: "ToolButton"
}
PlasmaComponents.TextField {
placeholderText: "Place holder text"
}
PlasmaComponents.TextField {
text: "Text fields page"
}
}
Column { Column {
spacing: 30 spacing: 30
Text { Text {
@ -97,3 +116,4 @@ Column {
text: "Disabled Text Area" text: "Disabled Text Area"
} }
} }
}

View File

@ -463,6 +463,11 @@ void PopupAppletInterface::showPopup()
popupApplet()->showPopup(); popupApplet()->showPopup();
} }
void PopupAppletInterface::showPopup(int timeout)
{
popupApplet()->showPopup(timeout);
}
void PopupAppletInterface::setPopupWidget(QGraphicsWidget *widget) void PopupAppletInterface::setPopupWidget(QGraphicsWidget *widget)
{ {
popupApplet()->setGraphicsWidget(widget); popupApplet()->setGraphicsWidget(widget);

View File

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

View File

@ -82,7 +82,7 @@ bool DeclarativeAppletScript::init()
{ {
m_declarativeWidget = new Plasma::DeclarativeWidget(applet()); m_declarativeWidget = new Plasma::DeclarativeWidget(applet());
m_declarativeWidget->setInitializationDelayed(true); m_declarativeWidget->setInitializationDelayed(true);
KGlobal::locale()->insertCatalog(description().pluginName()); KGlobal::locale()->insertCatalog("plasma_applet_" % description().pluginName());
//make possible to import extensions from the package //make possible to import extensions from the package
//FIXME: probably to be removed, would make possible to use native code from within 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*))); this, SLOT(extenderItemRestored(Plasma::ExtenderItem*)));
connect(applet(), SIGNAL(activate()), connect(applet(), SIGNAL(activate()),
this, SLOT(activate())); this, SLOT(activate()));
KGlobal::locale()->insertCatalog(description().pluginName()); KGlobal::locale()->insertCatalog("plasma_applet_" % description().pluginName());
setupObjects(); setupObjects();
AppletAuthorization auth(this); AppletAuthorization auth(this);

View File

@ -39,7 +39,7 @@
#include <Plasma/PackageMetadata> #include <Plasma/PackageMetadata>
static const char description[] = I18N_NOOP("Install, list, remove Plasma packages"); 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) void output(const QString &msg)
{ {
@ -180,6 +180,8 @@ int main(int argc, char **argv)
KCmdLineArgs::init( argc, argv, &aboutData ); KCmdLineArgs::init( argc, argv, &aboutData );
KCmdLineOptions options; 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("g");
options.add("global", ki18n("For install or remove, operates on packages installed for all users.")); options.add("global", ki18n("For install or remove, operates on packages installed for all users."));
options.add("t"); options.add("t");
@ -206,6 +208,26 @@ int main(int argc, char **argv)
KApplication app; KApplication app;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); 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 type = args->getOption("type");
QString packageRoot = type; QString packageRoot = type;
QString servicePrefix; QString servicePrefix;
@ -214,11 +236,6 @@ int main(int argc, char **argv)
QString package; QString package;
QString packageFile; QString packageFile;
if (args->isSet("list-types")) {
listTypes();
exit(0);
}
if (args->isSet("remove")) { if (args->isSet("remove")) {
package = args->getOption("remove"); package = args->getOption("remove");
} else if (args->isSet("upgrade")) { } else if (args->isSet("upgrade")) {