diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3e1c35aa..daa9d382 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,123 +1,124 @@ project(kirigami) if (NOT STATIC_LIBRARY) ecm_create_qm_loader(kirigami_QM_LOADER libkirigami2plugin_qt) else() set(KIRIGAMI_STATIC_FILES libkirigami/basictheme.cpp libkirigami/platformtheme.cpp libkirigami/tabletmodewatcher.cpp libkirigami/kirigamipluginfactory.cpp) endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libkirigami ${CMAKE_CURRENT_BINARY_DIR}/libkirigami) set(kirigami_SRCS kirigamiplugin.cpp + columnsview.cpp enums.cpp delegaterecycler.cpp desktopicon.cpp settings.cpp formlayoutattached.cpp scenepositionattached.cpp mnemonicattached.cpp ${kirigami_QM_LOADER} ${KIRIGAMI_STATIC_FILES} ) add_subdirectory(libkirigami) if(STATIC_LIBRARY) # Set some variables to insert the right files in the QRC if(Qt5Qml_VERSION VERSION_LESS 5.10) set(kirigami_ActionMenuItem ActionMenuItemQt59.qml) else() set(kirigami_ActionMenuItem ActionMenuItemQt510.qml) endif() # `rcc` is a bit dumb and isn't designed to use auto generated files, to # avoid poluting the source directory, use absolute paths set(kirigami_QML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../) # First, pre-process the QRC to add the files associated with the right Qt # version. configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../kirigami.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/../kirigami.qrc @ONLY ) # When using the static library, all QML files need to be shipped within the # .a file. qt5_add_resources( RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/../kirigami.qrc ) endif(STATIC_LIBRARY) add_library(kirigamiplugin ${kirigami_SRCS} ${RESOURCES}) if(STATIC_LIBRARY) SET_TARGET_PROPERTIES(kirigamiplugin PROPERTIES AUTOMOC_MOC_OPTIONS -Muri=org.kde.kirigami) if (UNIX AND NOT CMAKE_SYSTEM_NAME STREQUAL "Android" AND NOT(APPLE) AND NOT(DISABLE_DBUS)) set(Kirigami_EXTRA_LIBS Qt5::DBus) else() set(Kirigami_EXTRA_LIBS "") endif() else(STATIC_LIBRARY) set(Kirigami_EXTRA_LIBS KF5::Kirigami2) endif(STATIC_LIBRARY) target_link_libraries(kirigamiplugin PUBLIC Qt5::Core PRIVATE ${Kirigami_EXTRA_LIBS} Qt5::Qml Qt5::Quick Qt5::QuickControls2 ) if (NOT STATIC_LIBRARY) add_custom_target(copy) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/org/kde/kirigami.2) add_custom_command(TARGET copy PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/controls ${CMAKE_BINARY_DIR}/bin/org/kde/kirigami.2/) add_custom_command(TARGET copy PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/styles ${CMAKE_BINARY_DIR}/bin/org/kde/kirigami.2/styles) add_dependencies(kirigamiplugin copy) install(DIRECTORY controls/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2) if(Qt5Qml_VERSION VERSION_LESS 5.10) install(FILES controls/private/ActionMenuItemQt59.qml DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2/private RENAME ActionMenuItem.qml) else() install(FILES controls/private/ActionMenuItemQt510.qml DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2/private RENAME ActionMenuItem.qml) endif() if (PLASMA_ENABLED) install(DIRECTORY styles/Plasma DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2/styles) endif() if (DESKTOP_ENABLED) install(DIRECTORY styles/org.kde.desktop DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2/styles) endif() if (PLASMA_ENABLED AND DESKTOP_ENABLED) install(DIRECTORY styles/org.kde.desktop.plasma DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2/styles) endif() install(DIRECTORY styles/Material DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2/styles) install(FILES ${platformspecific} DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2) include(ECMGeneratePriFile) ecm_generate_pri_file(BASE_NAME Kirigami2 LIB_NAME KF5Kirigami2 DEPS "core qml quick svg" FILENAME_VAR PRI_FILENAME ) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) endif(NOT STATIC_LIBRARY) install(TARGETS kirigamiplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kirigami.2) diff --git a/src/columnsview.cpp b/src/columnsview.cpp new file mode 100644 index 00000000..fddd71d3 --- /dev/null +++ b/src/columnsview.cpp @@ -0,0 +1,150 @@ +/* + * Copyright 2019 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "columnsview.h" +#include "columnsview_p.h" + +#include +#include +#include +#include + +ContentItem::ContentItem(QQuickItem *parent) + : QQuickItem(parent) +{} + +ContentItem::~ContentItem() +{} + +qreal ContentItem::childWidth(QQuickItem *child) +{ + if (m_resizeMode == ColumnsView::SingleColumn + || parentItem()->width() < m_columnWidth * 2) { + return parentItem()->width(); + + } else if (m_resizeMode == ColumnsView::Fixed) { + if (child == m_expandedItem) { + return qBound(m_columnWidth, (parentItem()->width() - m_columnWidth * m_reservedColumns), parentItem()->width()); + } else { + return qMin(parentItem()->width(), m_columnWidth); + } + + } else { + //TODO:look for Layout size hints + if (child->implicitWidth() > 0) { + return qMin(parentItem()->width(), child->implicitWidth()); + } + return qMin(parentItem()->width(), child->width()); + } +} + +void ContentItem::layoutItems() +{ + qreal partialWidth = 0; + for (QQuickItem *child : childItems()) { + child->setSize(QSizeF(childWidth(child), height())); + child->setPosition(QPointF(partialWidth, 0.0)); + partialWidth += child->width(); + } + setWidth(partialWidth); + + setPosition(QPointF(m_firstVisibleItem ? -m_firstVisibleItem->x() : 0.0, 0.0)); +} + +void ContentItem::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + switch (change) { + case QQuickItem::ItemChildAddedChange: + connect(value.item, &QQuickItem::widthChanged, this, &ContentItem::layoutItems); + layoutItems(); + break; + case QQuickItem::ItemChildRemovedChange: + disconnect(value.item, nullptr, this, nullptr); + layoutItems(); + break; + default: + break; + } + QQuickItem::itemChange(change, value); +} + + + + + + + +ColumnsView::ColumnsView(QQuickItem *parent) + : QQuickItem(parent) +{ + m_contentItem = new ContentItem(this); +} + +ColumnsView::~ColumnsView() +{ +} + +QQuickItem *ColumnsView::contentItem() const +{ + return m_contentItem; +} + +void ColumnsView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_UNUSED(oldGeometry); + + m_contentItem->layoutItems(); + m_contentItem->setHeight(newGeometry.height()); +} + +void ColumnsView::mousePressEvent(QMouseEvent *event) +{ + m_oldMouseX = event->localPos().x(); + event->accept(); +} + +void ColumnsView::mouseMoveEvent(QMouseEvent *event) +{ + m_contentItem->setX(m_contentItem->x() + event->pos().x() - m_oldMouseX); + m_oldMouseX = event->pos().x(); + event->accept(); +} + +void ColumnsView::mouseReleaseEvent(QMouseEvent *event) +{ + //TODO: animate + QQuickItem *firstItem = m_contentItem->childAt(-m_contentItem->x(), 0); + if (!firstItem) { + return; + } + QQuickItem *nextItem = m_contentItem->childAt(firstItem->x() + firstItem->width() + 1, 0); + + if (-m_contentItem->x() <= firstItem->x() + firstItem->width()/2 || !nextItem) { + m_contentItem->m_expandedItem = firstItem; + m_contentItem->setX(-firstItem->x()); + } else { + m_contentItem->m_expandedItem = nextItem; + m_contentItem->setX(-nextItem->x()); + } + + event->accept(); +} + + +#include "moc_columnsview.cpp" diff --git a/src/columnsview.h b/src/columnsview.h new file mode 100644 index 00000000..d87110ac --- /dev/null +++ b/src/columnsview.h @@ -0,0 +1,61 @@ +/* + * Copyright 2019 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include +#include + +class ContentItem; + +class ColumnsView : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT) + Q_ENUMS(ChildResizeMode) +public: + enum ChildResizeMode{ + Fixed = 0, + Dynamic, + SingleColumn + }; + ColumnsView(QQuickItem *parent = nullptr); + ~ColumnsView(); + + QQuickItem *contentItem() const; + +protected: + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + +Q_SIGNALS: + + +private: + ContentItem *m_contentItem; + QPointer m_currentItem; + + qreal m_oldMouseX; + int m_currentIndex = -1; +}; + diff --git a/src/columnsview_p.h b/src/columnsview_p.h new file mode 100644 index 00000000..bb6baec9 --- /dev/null +++ b/src/columnsview_p.h @@ -0,0 +1,50 @@ +/* + * Copyright 2019 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "columnsview.h" + +#include +#include + + +class ContentItem : public QQuickItem { + Q_OBJECT + +public: + ContentItem(QQuickItem *parent = nullptr); + ~ContentItem(); + + qreal childWidth(QQuickItem *child); + void layoutItems(); + +protected: + void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override; + +private: + QPointer m_firstVisibleItem; + QPointer m_expandedItem; + + qreal m_columnWidth = 200; + int m_reservedColumns = 1; + ColumnsView::ChildResizeMode m_resizeMode = ColumnsView::Fixed; + friend class ColumnsView; +}; +