Compare commits
2 Commits
00255f67a0
...
c49135247a
Author | SHA1 | Date |
---|---|---|
|
c49135247a | |
|
accc627ebd |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
#include "calendarlistmodel.h"
|
||||
#include <QSqlQuery>
|
||||
#include <QVariant>
|
||||
#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<int, QByteArray> CalendarListModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
|
||||
roles[Name] = "name";
|
||||
return roles;
|
||||
}
|
||||
|
||||
void CalendarListModel::fetch()
|
||||
{
|
||||
Database::query([]() {
|
||||
QSqlQuery query("select label from campsite order by label");
|
||||
QVector<Calendar> calendars;
|
||||
while (query.next()) {
|
||||
Calendar calendar{query.value(0).toString()};
|
||||
calendars.append(calendar);
|
||||
}
|
||||
return calendars;
|
||||
}).then([this](const QVector<Calendar> &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"
|
|
@ -1,40 +0,0 @@
|
|||
#ifndef CALENDARLISTMODEL_H
|
||||
#define CALENDARLISTMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QtQmlIntegration>
|
||||
|
||||
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<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
struct Calendar;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(CalendarListModel)
|
||||
|
||||
void fetch();
|
||||
|
||||
QVector<Calendar *> m_calendars;
|
||||
};
|
||||
|
||||
#endif // CALENDARLISTMODEL_H
|
|
@ -0,0 +1,65 @@
|
|||
#include "timelinedaymodel.h"
|
||||
#include <QVariant>
|
||||
|
||||
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"
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef TIMELINEDAYMODEL_H
|
||||
#define TIMELINEDAYMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QtQmlIntegration>
|
||||
|
||||
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
|
|
@ -2,9 +2,9 @@
|
|||
#include <QQmlContext>
|
||||
#include <QQmlInfo>
|
||||
|
||||
struct TimelineViewItem
|
||||
struct TimelineView::Item
|
||||
{
|
||||
TimelineViewItem(qint64 day, qint64 len, QQuickItem &qitem, TimelineView &view)
|
||||
Item(qint64 day, qint64 len, QQuickItem &qitem, TimelineView &view)
|
||||
: item(&qitem)
|
||||
, day(day)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ struct TimelineViewItem
|
|||
item->setVisible(true);
|
||||
}
|
||||
|
||||
~TimelineViewItem()
|
||||
~Item()
|
||||
{
|
||||
item->setVisible(false);
|
||||
item->setParent(nullptr);
|
||||
|
@ -150,7 +150,7 @@ void TimelineView::componentComplete()
|
|||
populate();
|
||||
}
|
||||
|
||||
TimelineViewItem *TimelineView::createItem(qint64 day, qint64 len)
|
||||
TimelineView::Item *TimelineView::createItem(qint64 day, qint64 len)
|
||||
{
|
||||
QQuickItem *item = m_reusableItems.isEmpty() ? qobject_cast<QQuickItem *>(m_delegate->create(
|
||||
m_delegate->creationContext()))
|
||||
|
@ -159,11 +159,11 @@ TimelineViewItem *TimelineView::createItem(qint64 day, qint64 len)
|
|||
qmlWarning(m_delegate) << TimelineView::tr("Delegate must be of Item type");
|
||||
return nullptr;
|
||||
}
|
||||
auto *viewItem = new TimelineViewItem(day, len, *item, *this);
|
||||
auto *viewItem = new TimelineView::Item(day, len, *item, *this);
|
||||
return viewItem;
|
||||
}
|
||||
|
||||
void TimelineView::releaseItem(TimelineViewItem *item)
|
||||
void TimelineView::releaseItem(TimelineView::Item *item)
|
||||
{
|
||||
if (!item) {
|
||||
return;
|
||||
|
@ -201,7 +201,7 @@ void TimelineView::populate()
|
|||
if (m_viewportX > m_prevViewportX) {
|
||||
// Delete from the left
|
||||
while (!m_items.isEmpty()) {
|
||||
TimelineViewItem *item = m_items.first();
|
||||
TimelineView::Item *item = m_items.first();
|
||||
if (item->right() >= m_viewportX) {
|
||||
break;
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ void TimelineView::populate()
|
|||
lastDay = qMax(-1, qFloor((m_viewportX - (len * m_dayWidth)) / m_dayWidth));
|
||||
day > lastDay;
|
||||
day -= len) {
|
||||
TimelineViewItem *viewItem = createItem(day, len);
|
||||
TimelineView::Item *viewItem = createItem(day, len);
|
||||
if (!viewItem) {
|
||||
break;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ void TimelineView::populate()
|
|||
if (currentRight < prevRight) {
|
||||
// Delete from the right
|
||||
while (!m_items.isEmpty()) {
|
||||
TimelineViewItem *item = m_items.last();
|
||||
TimelineView::Item *item = m_items.last();
|
||||
if (item->left() < currentRight) {
|
||||
break;
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ void TimelineView::populate()
|
|||
lastDay = qFloor((currentRight + (len * m_dayWidth)) / m_dayWidth);
|
||||
day < lastDay;
|
||||
day += len) {
|
||||
TimelineViewItem *viewItem = createItem(day, len);
|
||||
TimelineView::Item *viewItem = createItem(day, len);
|
||||
if (!viewItem) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <QQmlComponent>
|
||||
#include <QQuickItem>
|
||||
|
||||
struct TimelineViewItem;
|
||||
class TimelineView : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -54,8 +53,10 @@ protected:
|
|||
private:
|
||||
Q_DISABLE_COPY_MOVE(TimelineView)
|
||||
|
||||
TimelineViewItem *createItem(qint64 day, qint64 len);
|
||||
void releaseItem(TimelineViewItem *item);
|
||||
struct Item;
|
||||
|
||||
Item *createItem(qint64 day, qint64 len);
|
||||
void releaseItem(Item *item);
|
||||
void drainItems();
|
||||
|
||||
void clear();
|
||||
|
@ -65,7 +66,7 @@ private:
|
|||
qreal m_dayWidth;
|
||||
QQmlComponent *m_delegate;
|
||||
QDate m_fromDate;
|
||||
QList<TimelineViewItem *> m_items;
|
||||
QList<Item *> m_items;
|
||||
QList<QQuickItem *> m_reusableItems;
|
||||
QDate m_toDate;
|
||||
qreal m_viewportX;
|
||||
|
|
Loading…
Reference in New Issue