Add Cell, CellModel
diff --git a/ide/Cell.cpp b/ide/Cell.cpp
new file mode 100644
index 0000000..2fd964b
--- /dev/null
+++ b/ide/Cell.cpp
@@ -0,0 +1,49 @@
+#include "Cell.h"
+
+Cell::Cell(QObject *parent) : QObject(parent)
+{
+
+}
+
+Cell::Cell(const Cell ©, QObject *parent)
+ : Cell(parent)
+{
+ *this = copy;
+}
+
+Cell::Cell(QString code, QString result, QObject *parent)
+ : Cell(parent)
+{
+ setCode(code);
+ setResult(result);
+}
+
+Cell &Cell::operator =(const Cell ©)
+{
+ setCode(copy.code());
+ setResult(copy.result());
+
+ return *this;
+}
+
+QString Cell::code() const
+{
+ return _code;
+}
+
+QString Cell::result() const
+{
+ return _result;
+}
+
+void Cell::setCode(QString code)
+{
+ _code = code;
+ emit codeChanged(code);
+}
+
+void Cell::setResult(QString result)
+{
+ _result = result;
+ emit resultChanged(result);
+}
diff --git a/ide/Cell.h b/ide/Cell.h
new file mode 100644
index 0000000..e3d1f9d
--- /dev/null
+++ b/ide/Cell.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <QObject>
+#include <qqml.h>
+
+class Cell : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+ Q_PROPERTY(QString code READ code WRITE setCode NOTIFY codeChanged)
+ Q_PROPERTY(QString result READ result WRITE setResult NOTIFY resultChanged)
+
+public:
+ explicit Cell(QObject *parent = nullptr);
+ Cell(const Cell ©, QObject *parent = nullptr);
+ Cell(QString code, QString result, QObject *parent = nullptr);
+
+ Cell &operator =(const Cell ©);
+
+ QString code() const;
+ QString result() const;
+
+ void setCode(QString code);
+ void setResult(QString result);
+
+signals:
+ void codeChanged(QString code);
+ void resultChanged(QString result);
+
+private:
+ QString _code, _result;
+};
+
+Q_DECLARE_METATYPE(Cell)
diff --git a/ide/CellModel.cpp b/ide/CellModel.cpp
new file mode 100644
index 0000000..911c9a9
--- /dev/null
+++ b/ide/CellModel.cpp
@@ -0,0 +1,117 @@
+#include "CellModel.h"
+
+CellModel::CellModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+}
+
+CellModel::CellModel(const CellModel &model, QObject *parent)
+ : CellModel(parent)
+{
+ _cells = model._cells;
+}
+
+int CellModel::rowCount(const QModelIndex &parent) const
+{
+ // For list models only the root node (an invalid parent) should return the list's size. For all
+ // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
+ if (parent.isValid())
+ return 0;
+
+ return _cells.size();
+}
+
+QVariant CellModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ switch (role)
+ {
+ case CodeRole:
+ return _cells[index.row()].code();
+ case ResultRole:
+ return _cells[index.row()].result();
+ default:
+ return QVariant();
+ }
+}
+
+bool CellModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (data(index, role) != value)
+ {
+ switch (role)
+ {
+ case CodeRole:
+ _cells[index.row()].setCode(value.toString());
+ break;
+ case ResultRole:
+ _cells[index.row()].setResult(value.toString());
+ break;
+ default:
+ return false;
+ }
+
+ emit dataChanged(index, index, QVector<int>() << role);
+
+ return true;
+ }
+
+ return false;
+}
+
+Qt::ItemFlags CellModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return Qt::NoItemFlags;
+
+ return Qt::ItemIsEditable; // FIXME: Implement me!
+}
+
+bool CellModel::insertRows(int row, int count, const QModelIndex &parent)
+{
+ beginInsertRows(parent, row, row + count - 1);
+
+ for (int i = 0; i < count; i++)
+ _cells.insert(row, Cell());
+
+ endInsertRows();
+
+ return false;
+}
+
+bool CellModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+ beginRemoveRows(parent, row, row + count - 1);
+
+ for (int i = 0; i < count; i++)
+ _cells.removeAt(row);
+
+ endRemoveRows();
+
+ return true;
+}
+
+QHash<int, QByteArray> CellModel::roleNames() const
+{
+ return {
+ {CodeRole, "code"},
+ {ResultRole, "result"},
+ };
+}
+
+void CellModel::addCell(const Cell &cell)
+{
+ int i = _cells.size();
+
+ insertRows(i, 1, QModelIndex());
+
+ _cells[i] = cell;
+ emit dataChanged(index(i), index(i), {CodeRole, ResultRole});
+}
+
+void CellModel::addCell(QString code, QString result)
+{
+ addCell(Cell(code, result));
+}
diff --git a/ide/CellModel.h b/ide/CellModel.h
new file mode 100644
index 0000000..3920e38
--- /dev/null
+++ b/ide/CellModel.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <QAbstractListModel>
+#include <qqml.h>
+
+#include "Cell.h"
+
+class CellModel : public QAbstractListModel
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+public:
+ explicit CellModel(QObject *parent = nullptr);
+ CellModel(const CellModel &model, QObject *parent = nullptr);
+
+ enum CellRoles
+ {
+ CodeRole = Qt::UserRole + 1,
+ ResultRole
+ };
+
+ // Basic functionality:
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+ // Editable:
+ Q_INVOKABLE bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole) override;
+
+ Qt::ItemFlags flags(const QModelIndex& index) const override;
+
+ // Add data:
+ Q_INVOKABLE bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
+
+ // Remove data:
+ Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
+
+ QHash<int, QByteArray> roleNames() const override;
+
+ Q_INVOKABLE void addCell(const Cell &cell);
+ Q_INVOKABLE void addCell(QString code, QString result);
+
+private:
+ QList<Cell> _cells;
+};
+
+Q_DECLARE_METATYPE(CellModel)
diff --git a/ide/IDE.pri b/ide/IDE.pri
index e430568..906b3cb 100644
--- a/ide/IDE.pri
+++ b/ide/IDE.pri
@@ -1,7 +1,7 @@
QT += quick quickcontrols2
QT -= core
-CONFIG +=
+CONFIG += qmltypes
QML_IMPORT_NAME = sh.swisschili.REFAL
QML_IMPORT_MAJOR_VERSION = 1
@@ -14,10 +14,16 @@
QML_DESIGNER_IMPORT_PATH =
SOURCES += \
+ $$PWD/Cell.cpp \
+ $$PWD/CellModel.cpp \
$$PWD/IdeMain.cpp
HEADERS += \
+ $$PWD/Cell.h \
+ $$PWD/CellModel.h \
$$PWD/IdeMain.h
RESOURCES += \
$$PWD/resources.qrc
+
+INCLUDEPATH += $$PWD
diff --git a/ide/qml/InsertRow.qml b/ide/qml/InsertRow.qml
index b12896a..00bad8b 100644
--- a/ide/qml/InsertRow.qml
+++ b/ide/qml/InsertRow.qml
@@ -6,7 +6,7 @@
Rectangle {
id: root
- color: Material.color(Material.Grey, Material.Shade800)
+ color: Material.color(Material.Grey, Material.theme == Material.Dark ? Material.Shade800 : Material.Shade300)
height: 2
Layout.fillWidth: true
Layout.topMargin: 14
@@ -55,7 +55,7 @@
id: addButton
anchors.centerIn: parent
icon.source: "qrc:///icons/add.svg"
- icon.color: Material.color(Material.Grey, Material.Shade400)
+ icon.color: Material.color(Material.Grey, Material.theme == Material.Dark ? Material.Shade400 : Material.Shade600)
flat: true
}
}
diff --git a/ide/qml/Cell.qml b/ide/qml/NotebookCell.qml
similarity index 74%
rename from ide/qml/Cell.qml
rename to ide/qml/NotebookCell.qml
index d060dee..a441b73 100644
--- a/ide/qml/Cell.qml
+++ b/ide/qml/NotebookCell.qml
@@ -6,6 +6,9 @@
ColumnLayout {
id: root
+ required property string code
+ required property string result
+
RowLayout {
Layout.fillWidth: true
@@ -25,15 +28,21 @@
Layout.fillHeight: true
id: code
font.family: "monospace"
- text: "Hello"
+ text: root.code
selectByMouse: true
wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
+
+ Keys.onTabPressed: {
+ var pos = cursorPosition + 4
+ text += " ";
+ cursorPosition = pos
+ }
}
Label {
Layout.fillWidth: true
font.family: "monospace"
- text: "Result\nasdfasdf\nasdad"
+ text: root.result
}
}
}
diff --git a/ide/qml/main.qml b/ide/qml/main.qml
index d3bca25..73a4581 100644
--- a/ide/qml/main.qml
+++ b/ide/qml/main.qml
@@ -3,6 +3,8 @@
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
+import sh.swisschili.REFAL 1.0
+
ApplicationWindow {
id: root
width: 1080
@@ -10,9 +12,19 @@
title: "Notebook"
visible: true
- Material.theme: Material.Dark
+ Material.theme: Material.Light
Material.accent: Material.Orange
+ CellModel {
+ id: model
+ }
+
+ Component.onCompleted: {
+ model.addCell("Refal { = Hi!; }", "");
+ model.addCell("<Refal>", "Hi!");
+ model.addCell("Hello there", "Hello there");
+ }
+
ColumnLayout {
id: column
anchors.fill: parent
@@ -45,10 +57,10 @@
id: codeEditor
SplitView.fillWidth: true
SplitView.minimumWidth: 400
- model: 3
+ model: model
clip: true
- delegate: Cell {
+ delegate: NotebookCell {
width: codeEditor.width - 5
}
}
diff --git a/ide/resources.qrc b/ide/resources.qrc
index bab3643..f48925a 100644
--- a/ide/resources.qrc
+++ b/ide/resources.qrc
@@ -1,7 +1,7 @@
<RCC>
<qresource prefix="/">
<file>qml/main.qml</file>
- <file>qml/Cell.qml</file>
+ <file>qml/NotebookCell.qml</file>
<file>icons/play-circle.svg</file>
<file>icons/add.svg</file>
<file>qml/InsertRow.qml</file>