From c49135247a9899a6c04da34948c92ff363902307 Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Wed, 8 Jan 2025 09:54:13 +0100 Subject: [PATCH] Add TimelineDayRow and set it as header of timeline list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the equivalent control to Qt Quick Controls’ own DayOfWeekRow, but for the number of each day in the visible range, instead of day of the week. Qt Quick Controls has this component written in C++, and also has a separate, internal, model for the days in different formats, but i had to implement the control in QML, because QtQuickControl is private. However, as far as i understand, it is not much more than a container for the delegate and the model that is used as a template. --- src/CMakeLists.txt | 2 + src/ReservationsPage.qml | 21 +++++++--- src/TimelineDayRow.qml | 35 ++++++++++++++++ src/calendarlistmodel.cpp | 86 --------------------------------------- src/calendarlistmodel.h | 40 ------------------ src/timelinedaymodel.cpp | 65 +++++++++++++++++++++++++++++ src/timelinedaymodel.h | 38 +++++++++++++++++ 7 files changed, 156 insertions(+), 131 deletions(-) create mode 100644 src/TimelineDayRow.qml delete mode 100644 src/calendarlistmodel.cpp delete mode 100644 src/calendarlistmodel.h create mode 100644 src/timelinedaymodel.cpp create mode 100644 src/timelinedaymodel.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04c0481..edab1bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ qt_add_qml_module(${PROJECT_NAME} calendarlistmodel.cpp calendarlistmodel.h database.cpp database.h mnemonicattached.cpp mnemonicattached.h + timelinedaymodel.cpp timelinedaymodel.h timelineview.cpp timelineview.h QML_FILES ErrorNotification.qml @@ -22,6 +23,7 @@ qt_add_qml_module(${PROJECT_NAME} MnemonicLabel.qml ReservationsPage.qml SelectableLabel.qml + TimelineDayRow.qml ) set_target_properties(${PROJECT_NAME} PROPERTIES diff --git a/src/ReservationsPage.qml b/src/ReservationsPage.qml index 006d802..0e8f0a6 100644 --- a/src/ReservationsPage.qml +++ b/src/ReservationsPage.qml @@ -5,6 +5,12 @@ import QtQuick.Layouts import Camper Page { + id: page + + property real dayWidth: 24 + property date fromDate: "2024-11-01" + property date toDate: "2025-01-31" + title: qsTr("Reservations") header: ToolBar { @@ -50,7 +56,7 @@ Page { anchors.right: parent.right anchors.top: parent.top clip: true - contentWidth: 2184 + contentWidth: headerItem.implicitWidth flickableDirection: Flickable.AutoFlickDirection headerPositioning: ListView.OverlayHeader model: calendarList @@ -62,9 +68,10 @@ Page { } delegate: TimelineView { - fromDate: "2024-11-01" + dayWidth: page.dayWidth + fromDate: page.fromDate height: 16 - toDate: "2025-01-31" + toDate: page.toDate viewportWidth: ListView.view.width viewportX: ListView.view.contentX @@ -75,10 +82,14 @@ Page { } } header: Pane { + leftPadding: 0 + rightPadding: 0 z: 2 - Label { - text: qsTr("Calendar") + TimelineDayRow { + dayWidth: page.dayWidth + fromDate: page.fromDate + toDate: page.toDate } } } diff --git a/src/TimelineDayRow.qml b/src/TimelineDayRow.qml new file mode 100644 index 0000000..26f029c --- /dev/null +++ b/src/TimelineDayRow.qml @@ -0,0 +1,35 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls + +Control { + id: control + + property real dayWidth: 24 + property alias fromDate: model.fromDate + property alias toDate: model.toDate + + contentItem: Row { + Repeater { + model: model + + delegate: Label { + required property string display + + text: display + width: control.dayWidth + + background: Rectangle { + border.color: "red" + border.width: 1 + color: "yellow" + } + } + } + } + + TimelineDayModel { + id: model + + } +} diff --git a/src/calendarlistmodel.cpp b/src/calendarlistmodel.cpp deleted file mode 100644 index 60faf1e..0000000 --- a/src/calendarlistmodel.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "calendarlistmodel.h" -#include -#include -#include "database.h" - -struct CalendarListModel::Calendar -{ - QString name; -}; - -CalendarListModel::CalendarListModel(QObject *parent) - : QAbstractListModel{parent} - , m_calendars{} -{ - fetch(); -} - -CalendarListModel::~CalendarListModel() -{ - qDeleteAll(m_calendars); -} - -QVariant CalendarListModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) { - return {}; - } - return section; -} - -int CalendarListModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) { - return 0; - } - - return m_calendars.count(); -} - -QHash CalendarListModel::roleNames() const -{ - QHash roles = QAbstractItemModel::roleNames(); - roles[Name] = "name"; - return roles; -} - -void CalendarListModel::fetch() -{ - Database::query([]() { - QSqlQuery query("select label from campsite order by label"); - QVector calendars; - while (query.next()) { - Calendar calendar{query.value(0).toString()}; - calendars.append(calendar); - } - return calendars; - }).then([this](const QVector &calendars) { - if (calendars.empty()) { - return; - } - beginInsertRows(QModelIndex(), 0, calendars.count() - 1); - for (const Calendar &calendar : calendars) { - m_calendars.append(new Calendar(calendar)); - } - endInsertRows(); - }); -} - -QVariant CalendarListModel::data(const QModelIndex &index, int role) const -{ - if (!checkIndex(index, - QAbstractItemModel::CheckIndexOption::IndexIsValid - | QAbstractItemModel::CheckIndexOption::ParentIsInvalid)) { - return {}; - } - - Calendar *calendar = m_calendars.at(index.row()); - switch (role) { - case Name: - return calendar->name; - } - - return {}; -} - -#include "moc_calendarlistmodel.cpp" diff --git a/src/calendarlistmodel.h b/src/calendarlistmodel.h deleted file mode 100644 index 7b32c51..0000000 --- a/src/calendarlistmodel.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef CALENDARLISTMODEL_H -#define CALENDARLISTMODEL_H - -#include -#include - -class CalendarListModel : public QAbstractListModel -{ - Q_OBJECT - QML_ELEMENT - -public: - enum Roles { - Name = Qt::UserRole, - }; - - explicit CalendarListModel(QObject *parent = nullptr); - ~CalendarListModel() override; - - QVariant headerData(int section, - Qt::Orientation orientation, - int role = Qt::DisplayRole) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - QHash roleNames() const override; - -private: - struct Calendar; - - Q_DISABLE_COPY_MOVE(CalendarListModel) - - void fetch(); - - QVector m_calendars; -}; - -#endif // CALENDARLISTMODEL_H diff --git a/src/timelinedaymodel.cpp b/src/timelinedaymodel.cpp new file mode 100644 index 0000000..21758c6 --- /dev/null +++ b/src/timelinedaymodel.cpp @@ -0,0 +1,65 @@ +#include "timelinedaymodel.h" +#include + +TimelineDayModel::TimelineDayModel(QObject *parent) + : QAbstractListModel(parent) + , m_fromDate() + , m_toDate() +{} + +int TimelineDayModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) { + return 0; + } + return m_fromDate.daysTo(m_toDate) + 1; +} + +QVariant TimelineDayModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return {}; + } + + QDate date = m_fromDate.addDays(index.row()); + switch (role) { + case Qt::DisplayRole: + return QString::number(date.day()); + } + + return {}; +} + +QDate TimelineDayModel::fromDate() const +{ + return m_fromDate; +} + +void TimelineDayModel::setFromDate(QDate date) +{ + if (date == m_fromDate) { + return; + } + beginResetModel(); + m_fromDate = date; + endResetModel(); + emit fromDateChanged(m_fromDate); +} + +QDate TimelineDayModel::toDate() const +{ + return m_toDate; +} + +void TimelineDayModel::setToDate(QDate date) +{ + if (date == m_toDate) { + return; + } + beginResetModel(); + m_toDate = date; + endResetModel(); + emit toDateChanged(m_toDate); +} + +#include "moc_timelinedaymodel.cpp" diff --git a/src/timelinedaymodel.h b/src/timelinedaymodel.h new file mode 100644 index 0000000..09a6c1c --- /dev/null +++ b/src/timelinedaymodel.h @@ -0,0 +1,38 @@ +#ifndef TIMELINEDAYMODEL_H +#define TIMELINEDAYMODEL_H + +#include +#include + +class TimelineDayModel : public QAbstractListModel +{ + Q_OBJECT + QML_ELEMENT + + Q_PROPERTY(QDate fromDate READ fromDate WRITE setFromDate NOTIFY fromDateChanged) + Q_PROPERTY(QDate toDate READ toDate WRITE setToDate NOTIFY toDateChanged) + +public: + explicit TimelineDayModel(QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + QDate fromDate() const; + void setFromDate(QDate date); + + QDate toDate() const; + void setToDate(QDate date); + +signals: + void fromDateChanged(QDate date); + void toDateChanged(QDate date); + +private: + Q_DISABLE_COPY_MOVE(TimelineDayModel) + + QDate m_fromDate; + QDate m_toDate; +}; + +#endif // TIMELINEDAYMODEL_H