diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-03-18 21:19:28 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-03-18 21:19:47 +0530 |
| commit | 4c762b2516bc664293c2aec072074f1e34dda8c3 (patch) | |
| tree | ebe441f7af8c1f4c49f04630538312d55f18f63b | |
| parent | 056b0b16947ac19a0c425aa9d2ff8f589378d3bc (diff) | |
| download | null-browser-4c762b2516bc664293c2aec072074f1e34dda8c3.tar.gz null-browser-4c762b2516bc664293c2aec072074f1e34dda8c3.zip | |
Remove all the ui bits because screw it, lets unix a bit more
28 files changed, 24 insertions, 1183 deletions
diff --git a/include/InputMediator.hpp b/include/InputMediator.hpp index 6025536..4aaa6c1 100644 --- a/include/InputMediator.hpp +++ b/include/InputMediator.hpp @@ -5,60 +5,24 @@ #include "LuaRuntime.hpp" #include "utils.hpp" -#include "widgets/InputLine.hpp" #include "widgets/WebViewStack.hpp" -// TODO: Rethink evaluation -class EvaluationType { -public: - EvaluationType() {} - virtual ~EvaluationType() = default; -}; -class NoopEval : public EvaluationType {}; - class InputMediator : public QObject { Q_OBJECT public: - InputMediator(InputLine *inputLine, WebViewStack *webViewStack, - LuaRuntime *luaRuntime); - - void showURLInput(QString url = "", OpenType openType = OpenType::OpenUrl); - void showCommandInput(QString command = ""); - void showTabsInput(QString command = ""); - void hideInputLine(); + InputMediator(WebViewStack *webViewStack, LuaRuntime *luaRuntime); DELEGATE(webViewStack, openUrl, openUrl) DELEGATE(webViewStack, currentUrl, currentUrl) DELEGATE(webViewStack, next, nextWebView) DELEGATE(webViewStack, previous, previousWebView) DELEGATE(webViewStack, closeCurrent, closeCurrentWebView) - DELEGATE(inputLine, getInputText, getInputText) private: - void showInputLine(); void evaluateCommand(QString command); - void setEvaluationType(EvaluationType *); - -private slots: - void onInputSubmit(QString input); private: - InputLine *inputLine; WebViewStack *webViewStack; LuaRuntime *luaRuntime; - EvaluationType *currentEvaluationType = new NoopEval(); -}; - -class UrlEval : public EvaluationType { -public: - UrlEval(OpenType type) : EvaluationType(), openType(type) {} - OpenType type() { return openType; } - -private: - OpenType openType; }; - -class CommandEval : public EvaluationType {}; - -class TabsEval : public EvaluationType {}; diff --git a/include/completion/Adapter.hpp b/include/completion/Adapter.hpp deleted file mode 100644 index 882d457..0000000 --- a/include/completion/Adapter.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include <QWidget> -#include <QtCore> - -#include "completion/Completer.hpp" - -class Adapter : public QObject { -public: - virtual Completer *completer() = 0; - virtual QString prompt() = 0; -}; diff --git a/include/completion/CommandsAdapter.hpp b/include/completion/CommandsAdapter.hpp deleted file mode 100644 index 0a0b61b..0000000 --- a/include/completion/CommandsAdapter.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include <QWidget> -#include <QtCore> - -#include "completion/Adapter.hpp" - -class CommandsAdapter : public Adapter { - Q_OBJECT - -public: - CommandsAdapter(); - ~CommandsAdapter(); - Completer *completer() override; - QString prompt() override; - -private: - Completer *completerInstance; -}; diff --git a/include/completion/CommandsModel.hpp b/include/completion/CommandsModel.hpp deleted file mode 100644 index 4f64654..0000000 --- a/include/completion/CommandsModel.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include <QAbstractListModel> -#include <QWidget> -#include <QtCore> - -struct Command { - QString name; - QString description; -}; - -// TODO: Combine commands model completion and commands evaluation -const QList<Command> commands = { - {.name = "open", .description = "Update current URL"}, - {.name = "tabs", .description = "Select a tab"}, - {.name = "tabopen", .description = "Open a url in a new tab"}, - {.name = "tabnext", .description = "Go to next tab"}, - {.name = "tabprev", .description = "Go to previous tab"}, -}; - -class CommandsModel : public QAbstractListModel { - Q_OBJECT - -public: - CommandsModel(QObject *parent = nullptr); - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QHash<int, QByteArray> roleNames() const override; - QVariant data(const QModelIndex &index, - int role = Qt::DisplayRole) const override; - -private: - QList<Command> items; -}; diff --git a/include/completion/Completer.hpp b/include/completion/Completer.hpp deleted file mode 100644 index c1b77a6..0000000 --- a/include/completion/Completer.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include <QCompleter> -#include <QHBoxLayout> -#include <QSortFilterProxyModel> -#include <QWidget> -#include <QtCore> -#include <QtWidgets/qtreeview.h> -#include <cstdint> - -#include "completion/CompleterDelegate.hpp" -#include "completion/FuzzySearchProxyModel.hpp" -#include "utils.hpp" - -class Completer : public QWidget { - Q_OBJECT - -public: - Completer(QWidget *parentNode = nullptr); - - DELEGATE((&proxyModel), setSourceModel, setSourceModel) - DELEGATE((&proxyModel), sourceModel, sourceModel) - -signals: - void accepted(QString text); - -public slots: - void onTextChange(QString text); - bool onKeyPressEvent(QKeyEvent *event); - -protected: - void setHighlightedRow(uint32_t); - void acceptHighlighted(); - - DELEGATE(this, onKeyPressEvent, keyPressEvent) - -private: - QTreeView *view; - FuzzySearchProxyModel proxyModel; - CompleterDelegate *viewDelegate; - QHBoxLayout *layout; -}; diff --git a/include/completion/CompleterDelegate.hpp b/include/completion/CompleterDelegate.hpp deleted file mode 100644 index 8de22de..0000000 --- a/include/completion/CompleterDelegate.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include <QStyledItemDelegate> -#include <QWidget> -#include <QtCore/qabstractitemmodel.h> -#include <QtCore> -#include <cstdint> - -class CompleterDelegate : public QStyledItemDelegate { - Q_OBJECT - -public: - explicit CompleterDelegate(QObject *parent = nullptr); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const override; - void setCurrentRow(uint32_t); - uint32_t currentRow(); - -private: - uint32_t row; -}; diff --git a/include/completion/FuzzySearchProxyModel.hpp b/include/completion/FuzzySearchProxyModel.hpp deleted file mode 100644 index ee4bfc3..0000000 --- a/include/completion/FuzzySearchProxyModel.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <QWidget> -#include <QtCore> - -class FuzzySearchProxyModel : public QSortFilterProxyModel { - Q_OBJECT - -public: - using QSortFilterProxyModel::QSortFilterProxyModel; - -protected: - bool filterAcceptsRow(int sourceRow, - const QModelIndex &sourceParent) const override; -}; diff --git a/include/completion/TabsAdapter.hpp b/include/completion/TabsAdapter.hpp deleted file mode 100644 index fd47b8b..0000000 --- a/include/completion/TabsAdapter.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <QWidget> -#include <QtCore> - -#include "completion/Adapter.hpp" -#include "completion/TabsModel.hpp" - -class TabsAdapter : public Adapter { - Q_OBJECT - -public: - TabsAdapter(QList<Tab> tabs); - ~TabsAdapter(); - Completer *completer() override; - QString prompt() override; - -private: - Completer *completerInstance; -}; diff --git a/include/completion/TabsModel.hpp b/include/completion/TabsModel.hpp deleted file mode 100644 index 4b4518f..0000000 --- a/include/completion/TabsModel.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <QAbstractListModel> -#include <QWidget> -#include <QtCore> - -struct Tab { - QString url; - QString title; -}; - -class TabsModel : public QAbstractListModel { - Q_OBJECT - -public: - TabsModel(QList<Tab> tabs, QObject *parent = nullptr); - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QHash<int, QByteArray> roleNames() const override; - QVariant data(const QModelIndex &index, - int role = Qt::DisplayRole) const override; - -private: - QList<Tab> items; -}; diff --git a/include/completion/UrlAdapter.hpp b/include/completion/UrlAdapter.hpp deleted file mode 100644 index e89167a..0000000 --- a/include/completion/UrlAdapter.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include <QWidget> -#include <QtCore> - -#include "completion/Adapter.hpp" - -class UrlAdapter : public Adapter { - Q_OBJECT - -public: - UrlAdapter(); - ~UrlAdapter(); - Completer *completer() override; - QString prompt() override; - -private: - Completer *completerInstance; -}; diff --git a/include/completion/UrlModel.hpp b/include/completion/UrlModel.hpp deleted file mode 100644 index e65a86a..0000000 --- a/include/completion/UrlModel.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <QAbstractListModel> -#include <QWidget> -#include <QtCore> - -struct Url { - QString url; - QString description; -}; - -class UrlModel : public QAbstractListModel { - Q_OBJECT - -public: - UrlModel(QObject *parent = nullptr); - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QHash<int, QByteArray> roleNames() const override; - QVariant data(const QModelIndex &index, - int role = Qt::DisplayRole) const override; - -private: - QList<Url> items; -}; diff --git a/include/keymap/KeymapEvaluator.hpp b/include/keymap/KeymapEvaluator.hpp index ed468d2..54409b1 100644 --- a/include/keymap/KeymapEvaluator.hpp +++ b/include/keymap/KeymapEvaluator.hpp @@ -5,7 +5,6 @@ #include <QtCore/qmap.h> #include <QtCore/qnamespace.h> #include <QtCore> -#include <algorithm> struct KeyMap { KeySequence keySequence; diff --git a/include/widgets/InputLine.hpp b/include/widgets/InputLine.hpp deleted file mode 100644 index a382ff8..0000000 --- a/include/widgets/InputLine.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include <QBoxLayout> -#include <QLabel> -#include <QLineEdit> -#include <QWidget> -#include <QtCore> - -#include "completion/Adapter.hpp" -#include "utils.hpp" - -class InputLine : public QWidget { - Q_OBJECT - -public: - InputLine(QString defaultInput = "", QWidget *parentNode = nullptr); - - void setInputFocus(bool focussed); - bool isInputFocussed(); - void setAdapter(Adapter *adapter); - - DELEGATE(input, hasFocus, isInputFocussed) - DELEGATE(input, setText, setInputText) - DELEGATE(input, text, getInputText) - DELEGATE(promptPrefix, text, prompt) - -signals: - void submitted(QString text); - void cancelled(); - -protected: - void keyPressEvent(QKeyEvent *event) override; - void emitSubmit(); - -private: - QLineEdit *input; - QLabel *promptPrefix; - Adapter *adapterInstance = nullptr; - QVBoxLayout *layout; -}; diff --git a/include/widgets/WebViewStack.hpp b/include/widgets/WebViewStack.hpp index c315251..e5b7ecc 100644 --- a/include/widgets/WebViewStack.hpp +++ b/include/widgets/WebViewStack.hpp @@ -5,11 +5,15 @@ #include <sys/types.h> #include "Configuration.hpp" -#include "completion/TabsModel.hpp" #include "widgets/WebView.hpp" enum OpenType { OpenUrl, OpenUrlInTab, OpenUrlInBgTab, OpenUrlInWindow }; +struct Tab { + QString url; + QString title; +}; + class WebViewStack : public QWidget { Q_OBJECT diff --git a/spec/InputLineSpec.cpp b/spec/InputLineSpec.cpp deleted file mode 100644 index db6890c..0000000 --- a/spec/InputLineSpec.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "completion/Adapter.hpp" -#include "completion/Completer.hpp" -#include "testUtils.h" -#include "widgets/InputLine.hpp" -#include <QAbstractItemView> -#include <QtCore/qsharedpointer.h> -#include <QtCore/qstringlistmodel.h> -#include <QtCore> -#include <QtTest/qtestkeyboard.h> - -class InputLineSpec : public QObject { - Q_OBJECT - - class FakeInputAdapter : public Adapter { - public: - FakeInputAdapter() : Adapter() { - completerInstance = new Completer; - QStringList list = {"one", "two", "three"}; - QStringListModel model(list); - completerInstance->setSourceModel(&model); - } - Completer *completer() { return completerInstance; } - QString prompt() { return "fake prompt"; } - - private: - Completer *completerInstance; - }; - -private slots: - void testWithInitialInput() { - context("when initialized with some text"); - it("sets the initial input text") { - InputLine inputWidget("Initial content", new QWidget()); - - QCOMPARE(inputWidget.getInputText(), "Initial content"); - } - } - - void testInputUpdate() { - context("when user types in input"); - it("updates input text") { - InputLine inputWidget("Initial content", new QWidget()); - - auto input = inputWidget.findChild<QLineEdit *>(); - QTest::keyClicks(input, " updated"); - - QCOMPARE(inputWidget.getInputText(), "Initial content updated"); - } - - context("when setInputText is called"); - it("sets input text") { - InputLine inputWidget("Initial content", new QWidget()); - - inputWidget.setInputText("New content"); - - QCOMPARE(inputWidget.getInputText(), "New content"); - } - } - - void testSubmitSignalOnReturnKey() { - context("when user hits return key"); - it("emits the submitted signal with the input text") { - InputLine inputWidget("Initial content", new QWidget()); - QSignalSpy submitSignal(&inputWidget, &InputLine::submitted); - - auto input = inputWidget.findChild<QLineEdit *>(); - QTest::keyClicks(input, " updated"); - QTest::keyClick(&inputWidget, Qt::Key_Return); - - QCOMPARE(submitSignal.count(), 1); - QCOMPARE(submitSignal.takeFirst().at(0).toString(), - QString("Initial content updated")); - } - } - - void testCancelSignalOnEscapeKey() { - context("when user hits escape key"); - it("emits 'cancelled' signal") { - InputLine inputWidget("Initial content", new QWidget()); - QSignalSpy cancelSignal(&inputWidget, &InputLine::cancelled); - - auto input = inputWidget.findChild<QLineEdit *>(); - QTest::keyClick(&inputWidget, Qt::Key_Escape); - - QCOMPARE(cancelSignal.count(), 1); - } - - context("when user hits ctrl+l key"); - it("emits 'cancelled' signal") { - InputLine inputWidget("Initial content", new QWidget()); - QSignalSpy cancelSignal(&inputWidget, &InputLine::cancelled); - - auto input = inputWidget.findChild<QLineEdit *>(); - QTest::keyClick(&inputWidget, Qt::Key_L, Qt::ControlModifier); - - QCOMPARE(cancelSignal.count(), 1); - } - } - - void testSetFocus() { - context("when setInputFocus is called with true"); - xit("focusses input field") { - InputLine inputWidget("Initial content", new QWidget()); - - inputWidget.setInputFocus(true); - QApplication::processEvents(); - - QVERIFY(inputWidget.isInputFocussed()); - } - - context("when setInputFocus is called with false"); - xit("unfocusses input field") { - InputLine inputWidget("Initial content", new QWidget()); - - inputWidget.setInputFocus(false); - QApplication::processEvents(); - - QVERIFY(!inputWidget.isInputFocussed()); - } - } - - void testInputPrompt() { - it("sets the prompt text using the adapter") { - InputLine inputWidget("Initial content", new QWidget()); - FakeInputAdapter inputAdapter; - inputWidget.setAdapter(&inputAdapter); - - QCOMPARE(inputWidget.prompt(), "fake prompt"); - } - } - - // TODO: completions test -}; - -QTEST_REGISTER(InputLineSpec) -#include "InputLineSpec.moc" diff --git a/spec/InputMediatorSpec.cpp b/spec/InputMediatorSpec.cpp index abc2232..b48b008 100644 --- a/spec/InputMediatorSpec.cpp +++ b/spec/InputMediatorSpec.cpp @@ -1,170 +1,12 @@ #include "InputMediator.hpp" #include "LuaRuntime.hpp" #include "testUtils.h" -#include "widgets/InputLine.hpp" #include "widgets/WebViewStack.hpp" class InputMediatorSpec : public QObject { Q_OBJECT private slots: - void testInputTypes() { - context("when showCommandInput is called"); - it("shows url input with default command") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - QCOMPARE(inputLine.isHidden(), true); - - inputMediator.showCommandInput("open"); - - QCOMPARE(inputLine.isHidden(), false); - QCOMPARE(inputLine.prompt(), "[exec]"); - QCOMPARE(inputLine.getInputText(), "open"); - } - - context("when showURLInput is called"); - it("shows url input with default url") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - QCOMPARE(inputLine.isHidden(), true); - - inputMediator.showURLInput("http://a.com"); - - QCOMPARE(inputLine.isHidden(), false); - QCOMPARE(inputLine.prompt(), "[url]"); - QCOMPARE(inputLine.getInputText(), "http://a.com"); - } - } - - void testCommandEvaluationOpen() { - context("when command open is executed"); - context("- without args"); - it("opens url input") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - - inputMediator.showCommandInput(); - emit inputLine.submitted("open"); - - QCOMPARE(inputLine.prompt(), "[url]"); - } - - context("when command open is executed"); - context("- with url as an arg"); - it("opens url in current tab") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - - inputMediator.showCommandInput(); - emit inputLine.submitted("open http://a.com"); - - std::vector<QUrl> urls = {QUrl("http://a.com")}; - QCOMPARE(webViewStack.urls(), urls); - QCOMPARE(webViewStack.currentWebViewIndex(), 0); - } - } - - void testCommandEvaluationTabOpen() { - context("when command tabopen is run"); - context("- without args"); - it("opens url in a new tab") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - - inputMediator.showCommandInput(); - emit inputLine.submitted("tabopen"); - - QCOMPARE(inputLine.prompt(), "[url]"); - } - - context("when command tabopen is executed"); - context("- with url as an arg"); - it("opens url in a new tab") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - - inputMediator.showCommandInput(); - emit inputLine.submitted("tabopen http://a.com"); - - std::vector<QUrl> urls = {QUrl(configuration.newTabUrl), - QUrl("http://a.com")}; - QCOMPARE(webViewStack.urls(), urls); - QCOMPARE(webViewStack.currentWebViewIndex(), 1); - } - } - - void testCommandEvaluationTabNextPrev() { - context("when command tabnext is executed"); - it("jumps to next tab") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - webViewStack.openUrl(QUrl("https://a1.com"), OpenType::OpenUrl); - webViewStack.openUrl(QUrl("https://a2.com"), OpenType::OpenUrlInTab); - webViewStack.openUrl(QUrl("https://a2.com"), OpenType::OpenUrlInBgTab); - QCOMPARE(webViewStack.currentWebViewIndex(), 1); - - inputMediator.showCommandInput(); - emit inputLine.submitted("tabnext"); - - QCOMPARE(webViewStack.currentWebViewIndex(), 2); - } - - context("when command tabprev is executed"); - it("jumps to previous tab") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - webViewStack.openUrl(QUrl("https://a1.com"), OpenType::OpenUrl); - webViewStack.openUrl(QUrl("https://a2.com"), OpenType::OpenUrlInTab); - webViewStack.openUrl(QUrl("https://a2.com"), OpenType::OpenUrlInBgTab); - QCOMPARE(webViewStack.currentWebViewIndex(), 1); - - inputMediator.showCommandInput(); - emit inputLine.submitted("tabprev"); - - QCOMPARE(webViewStack.currentWebViewIndex(), 0); - } - } - - void testHideInputLine() { - context("when hideInputLine is called"); - it("hides input") { - InputLine inputLine; - Configuration configuration; - WebViewStack webViewStack(&configuration); - auto luaRuntime = LuaRuntime::instance(); - InputMediator inputMediator(&inputLine, &webViewStack, luaRuntime); - inputMediator.showURLInput(); - QCOMPARE(inputLine.isHidden(), false); - - inputMediator.hideInputLine(); - - QCOMPARE(inputLine.isHidden(), true); - } - } }; QTEST_REGISTER(InputMediatorSpec) diff --git a/src/InputMediator.cpp b/src/InputMediator.cpp index 6c797a3..350d8ac 100644 --- a/src/InputMediator.cpp +++ b/src/InputMediator.cpp @@ -5,82 +5,14 @@ #include "CommandParser.hpp" #include "InputMediator.hpp" #include "LuaRuntime.hpp" -#include "completion/CommandsAdapter.hpp" -#include "completion/TabsAdapter.hpp" -#include "completion/UrlAdapter.hpp" #include "widgets/WebViewStack.hpp" -InputMediator::InputMediator(InputLine *inputLine, WebViewStack *webViewStack, - LuaRuntime *luaRuntime) - : QObject(), inputLine(inputLine), webViewStack(webViewStack), - luaRuntime(luaRuntime) { - // Inputline - inputLine->setHidden(true); - connect(inputLine, &InputLine::submitted, this, - &InputMediator::onInputSubmit); - connect(inputLine, &InputLine::cancelled, this, - &InputMediator::hideInputLine); - - // Lua runtime +InputMediator::InputMediator(WebViewStack *webViewStack, LuaRuntime *luaRuntime) + : QObject(), webViewStack(webViewStack), luaRuntime(luaRuntime) { connect(luaRuntime, &LuaRuntime::urlOpened, webViewStack, &WebViewStack::openUrl); } -void InputMediator::onInputSubmit(QString input) { - hideInputLine(); - - // Evaluate input from command - if (dynamic_cast<CommandEval *>(currentEvaluationType)) - return evaluateCommand(input); - - // Evaluate input from url - if (auto urlEval = dynamic_cast<UrlEval *>(currentEvaluationType)) - return webViewStack->openUrl(input, urlEval->type()); - - // Evaluate input from tab list - if (dynamic_cast<TabsEval *>(currentEvaluationType)) - return webViewStack->focusWebView(input.toLong()); -} - -void InputMediator::hideInputLine() { - inputLine->setInputFocus(false); - inputLine->setHidden(true); -} - -void InputMediator::showInputLine() { - inputLine->setHidden(false); - inputLine->raise(); - inputLine->setInputFocus(true); -} - -void InputMediator::showCommandInput(QString cmd) { - setEvaluationType(new CommandEval()); - inputLine->setAdapter(new CommandsAdapter); - inputLine->setInputText(cmd); - showInputLine(); -} - -void InputMediator::showTabsInput(QString url) { - setEvaluationType(new TabsEval()); - QList<Tab> tabs = webViewStack->getTabList(); - inputLine->setAdapter(new TabsAdapter(tabs)); - inputLine->setInputText(url); - showInputLine(); -} - -void InputMediator::setEvaluationType(EvaluationType *evalType) { - if (currentEvaluationType) - delete currentEvaluationType; - currentEvaluationType = evalType; -} - -void InputMediator::showURLInput(QString url, OpenType openType) { - setEvaluationType(new UrlEval(openType)); - inputLine->setAdapter(new UrlAdapter); - inputLine->setInputText(url); - showInputLine(); -} - void InputMediator::evaluateCommand(QString command) { CommandParser parser; auto cmd = parser.parse(command); @@ -90,16 +22,10 @@ void InputMediator::evaluateCommand(QString command) { luaRuntime->evaluate(cmd.argsString); break; case CommandType::Open: - if (cmd.argsString.trimmed().isEmpty()) - showURLInput("", OpenType::OpenUrl); - else - openUrl(cmd.argsString, OpenType::OpenUrl); + openUrl(cmd.argsString, OpenType::OpenUrl); break; case CommandType::TabOpen: - if (cmd.argsString.trimmed().isEmpty()) - showURLInput("", OpenType::OpenUrlInTab); - else - openUrl(cmd.argsString, OpenType::OpenUrlInTab); + openUrl(cmd.argsString, OpenType::OpenUrlInTab); break; case CommandType::TabNext: nextWebView(); @@ -108,8 +34,7 @@ void InputMediator::evaluateCommand(QString command) { previousWebView(); break; case CommandType::TabSelect: - showTabsInput(); - // focusWebView(long index) // TODO: parse index and select + webViewStack->focusWebView(cmd.argsString.toLong()); break; case CommandType::Noop: break; diff --git a/src/completion/CommandsAdapter.cpp b/src/completion/CommandsAdapter.cpp deleted file mode 100644 index 020c115..0000000 --- a/src/completion/CommandsAdapter.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include <QWidget> -#include <QtCore> - -#include "completion/CommandsAdapter.hpp" -#include "completion/CommandsModel.hpp" -#include "completion/Completer.hpp" - -const QString cmdPrompt = "[exec]"; - -CommandsAdapter::CommandsAdapter() : Adapter() { - completerInstance = new Completer(); - completerInstance->setSourceModel(new CommandsModel(this)); -} - -Completer *CommandsAdapter::completer() { return completerInstance; } - -QString CommandsAdapter::prompt() { return cmdPrompt; } - -CommandsAdapter::~CommandsAdapter() { - delete completerInstance->sourceModel(); - delete completerInstance; -} diff --git a/src/completion/CommandsModel.cpp b/src/completion/CommandsModel.cpp deleted file mode 100644 index 670c0e8..0000000 --- a/src/completion/CommandsModel.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include <QAbstractListModel> -#include <QWidget> -#include <QtCore> - -#include "completion/CommandsModel.hpp" - -CommandsModel::CommandsModel(QObject *parent) : QAbstractListModel(parent) { - items = commands; -} - -QVariant CommandsModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= items.size()) - return QVariant(); - - const Command &item = items.at(index.row()); - - if (role == Qt::DisplayRole) - return item.name; - else if (role == Qt::UserRole) - return item.description; - else if (role == Qt::AccessibleDescriptionRole) - return item.name + item.description; - - return QVariant(); -} - -QHash<int, QByteArray> CommandsModel::roleNames() const { - QHash<int, QByteArray> roles; - roles[Qt::DisplayRole] = "name"; - roles[Qt::UserRole] = "description"; - roles[Qt::AccessibleDescriptionRole] = "full"; - return roles; -} - -int CommandsModel::rowCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return items.size(); -} - -int CommandsModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return 2; // name + description -} diff --git a/src/completion/Completer.cpp b/src/completion/Completer.cpp deleted file mode 100644 index 95d1dde..0000000 --- a/src/completion/Completer.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include <QAbstractItemView> -#include <QHeaderView> -#include <QKeyEvent> -#include <QLineEdit> -#include <QTreeView> -#include <QWidget> -#include <QtCore/qabstractitemmodel.h> -#include <QtCore/qitemselectionmodel.h> -#include <QtCore/qnamespace.h> -#include <QtCore/qsortfilterproxymodel.h> -#include <QtCore> -#include <QtWidgets/qboxlayout.h> - -#include "completion/Completer.hpp" -#include "completion/CompleterDelegate.hpp" - -const char *completerStyles = R"( - background-color: #111; - color: #fff; - border-radius: 0; -)"; - -Completer::Completer(QWidget *parentNode) : QWidget(parentNode) { - layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - - setLayout(layout); - setStyleSheet(completerStyles); - setContentsMargins(0, 0, 0, 0); - - view = new QTreeView(); - layout->addWidget(view, 0); - viewDelegate = new CompleterDelegate(view); - view->setItemDelegate(viewDelegate); - view->setRootIsDecorated(false); - view->setUniformRowHeights(true); - view->header()->hide(); - view->setColumnWidth(0, 500); - view->setModel(&proxyModel); - view->setFocusPolicy(Qt::NoFocus); - view->setSelectionMode(QAbstractItemView::SingleSelection); - view->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); - view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); - view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -} - -void Completer::acceptHighlighted() { - auto index = proxyModel.index(viewDelegate->currentRow(), 0); - auto text = proxyModel.data(index, Qt::DisplayRole).toString(); - setHighlightedRow(0); - emit accepted(text); -} - -void Completer::onTextChange(QString text) { - setHighlightedRow(0); - proxyModel.setFilterWildcard(text); -} - -bool Completer::onKeyPressEvent(QKeyEvent *event) { - auto combo = event->keyCombination(); - auto row = viewDelegate->currentRow(); - - // If there are no matches, nothing to handle here - if (proxyModel.rowCount() == 0) - return false; - - if (combo.key() == Qt::Key_Up) { - setHighlightedRow(row <= 0 ? proxyModel.rowCount() - 1 : row - 1); - return true; - } - - if (combo.key() == Qt::Key_Down) { - setHighlightedRow((row + 1) % proxyModel.rowCount()); - return true; - } - - if (combo.key() == Qt::Key_Tab) { - acceptHighlighted(); - return true; - } - - if (combo.key() == Qt::Key_Return) { - acceptHighlighted(); - return false; - } - - return false; -} - -void Completer::setHighlightedRow(uint32_t row) { - viewDelegate->setCurrentRow(row); - view->update(); -} diff --git a/src/completion/CompleterDelegate.cpp b/src/completion/CompleterDelegate.cpp deleted file mode 100644 index ce446b2..0000000 --- a/src/completion/CompleterDelegate.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include <QPainter> -#include <QWidget> -#include <QtCore/qlogging.h> -#include <QtCore/qnamespace.h> -#include <QtCore> - -#include "completion/CompleterDelegate.hpp" - -CompleterDelegate::CompleterDelegate(QObject *parent) - : QStyledItemDelegate(parent) {} - -void CompleterDelegate::setCurrentRow(uint32_t r) { row = r; } - -uint32_t CompleterDelegate::currentRow() { return row; } - -void CompleterDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const { - painter->save(); - - bool selected = index.row() == row; - - // Style - if (selected) { - painter->fillRect(option.rect, QColor("#aaa")); - painter->setPen(Qt::black); - } else { - painter->fillRect(option.rect, QColor("#111")); - painter->setPen(Qt::white); - } - - // Draw text - QString text; - QRect rect; - if (index.column() == 0) { - text = index.data(Qt::DisplayRole).toString(); - rect = option.rect.adjusted(5, 0, 0, 0); - painter->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, text); - } else if (index.column() == 1) { - text = index.data(Qt::UserRole).toString(); - rect = option.rect.adjusted(0, 0, -5, 0); - painter->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, text); - } - - painter->restore(); -} diff --git a/src/completion/FuzzySearchProxyModel.cpp b/src/completion/FuzzySearchProxyModel.cpp deleted file mode 100644 index 0c467c6..0000000 --- a/src/completion/FuzzySearchProxyModel.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include <QWidget> -#include <QtCore> - -#include "completion/FuzzySearchProxyModel.hpp" - -bool FuzzySearchProxyModel::filterAcceptsRow( - int sourceRow, const QModelIndex &sourceParent) const { - QAbstractItemModel *model = sourceModel(); - QString filterText = filterRegularExpression().pattern(); - - for (int col = 0; col < model->columnCount(); ++col) { - QModelIndex index = model->index(sourceRow, col, sourceParent); - QString data = model->data(index, Qt::AccessibleDescriptionRole).toString(); - - // TODO: Fuzzy eet up - if (data.contains(filterText, Qt::CaseInsensitive)) { - return true; - } - } - return false; -} diff --git a/src/completion/TabsAdapter.cpp b/src/completion/TabsAdapter.cpp deleted file mode 100644 index d669151..0000000 --- a/src/completion/TabsAdapter.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include <QWidget> -#include <QtCore> - -#include "completion/Completer.hpp" -#include "completion/TabsAdapter.hpp" -#include "completion/TabsModel.hpp" - -TabsAdapter::TabsAdapter(QList<Tab> tabs) : Adapter() { - completerInstance = new Completer(); - completerInstance->setSourceModel(new TabsModel(tabs, this)); -} - -Completer *TabsAdapter::completer() { return completerInstance; } - -QString TabsAdapter::prompt() { return "[tabs]"; } - -TabsAdapter::~TabsAdapter() { - delete completerInstance->sourceModel(); - delete completerInstance; -} diff --git a/src/completion/TabsModel.cpp b/src/completion/TabsModel.cpp deleted file mode 100644 index 6d14b30..0000000 --- a/src/completion/TabsModel.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include <QAbstractListModel> -#include <QWidget> -#include <QtCore> - -#include "completion/TabsModel.hpp" - -TabsModel::TabsModel(QList<Tab> tabs, QObject *parent) - : QAbstractListModel(parent), items(tabs) {} - -QVariant TabsModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= items.size()) - return QVariant(); - - const Tab &item = items.at(index.row()); - - if (role == Qt::DisplayRole) - return index.row(); - else if (role == Qt::UserRole) - return item.title; - else if (role == Qt::AccessibleDescriptionRole) - return item.url + item.title; - - return QVariant(); -} - -QHash<int, QByteArray> TabsModel::roleNames() const { - QHash<int, QByteArray> roles; - roles[Qt::DisplayRole] = "url"; - roles[Qt::UserRole] = "title"; - roles[Qt::AccessibleDescriptionRole] = "full"; - return roles; -} - -int TabsModel::rowCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return items.size(); -} - -int TabsModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return 2; // url + title -} diff --git a/src/completion/UrlAdapter.cpp b/src/completion/UrlAdapter.cpp deleted file mode 100644 index 54caa0d..0000000 --- a/src/completion/UrlAdapter.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include <QWidget> -#include <QtCore> - -#include "completion/Completer.hpp" -#include "completion/UrlAdapter.hpp" -#include "completion/UrlModel.hpp" - -UrlAdapter::UrlAdapter() : Adapter() { - completerInstance = new Completer(); - completerInstance->setSourceModel(new UrlModel(this)); -} - -Completer *UrlAdapter::completer() { return completerInstance; } - -QString UrlAdapter::prompt() { return "[url]"; } - -UrlAdapter::~UrlAdapter() { - delete completerInstance->sourceModel(); - delete completerInstance; -} diff --git a/src/completion/UrlModel.cpp b/src/completion/UrlModel.cpp deleted file mode 100644 index 8c5d75c..0000000 --- a/src/completion/UrlModel.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include <QAbstractListModel> -#include <QWidget> -#include <QtCore/qnamespace.h> -#include <QtCore> - -#include "completion/UrlModel.hpp" - -UrlModel::UrlModel(QObject *parent) : QAbstractListModel(parent) { - items = { - {.url = "https://google.com", .description = "Google"}, - {.url = "https://duckduckgo.com", .description = "DuckDuckGo"}, - {.url = "https://ediblemonad.dev", .description = "EdibleMonad website"}, - {.url = "https://lite.duckduckgo.com", .description = "DDG lite"}, - {.url = "https://github.com/trending", .description = "Github trending"}, - }; -} - -QVariant UrlModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= items.size()) - return QVariant(); - - const Url &item = items.at(index.row()); - - if (role == Qt::DisplayRole) - return item.url; - else if (role == Qt::UserRole) - return item.description; - else if (role == Qt::AccessibleDescriptionRole) - return item.url + " " + item.description; - - return QVariant(); -} - -QHash<int, QByteArray> UrlModel::roleNames() const { - QHash<int, QByteArray> roles; - roles[Qt::DisplayRole] = "url"; - roles[Qt::UserRole] = "description"; - roles[Qt::AccessibleDescriptionRole] = "full"; - return roles; -} - -int UrlModel::rowCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return items.size(); -} - -int UrlModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return 2; // url + description -} diff --git a/src/widgets/InputLine.cpp b/src/widgets/InputLine.cpp deleted file mode 100644 index 81e2bab..0000000 --- a/src/widgets/InputLine.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include <QBoxLayout> -#include <QCompleter> -#include <QHBoxLayout> -#include <QKeyEvent> -#include <QLabel> -#include <QLineEdit> -#include <QStringListModel> -#include <QWidget> -#include <QWidgetAction> -#include <QWindow> -#include <QtCore/qnamespace.h> -#include <QtCore> -#include <QtWidgets/qboxlayout.h> -#include <QtWidgets/qlineedit.h> -#include <QtWidgets/qwidget.h> - -#include "completion/CommandsAdapter.hpp" -#include "widgets/InputLine.hpp" - -const char *rootStyles = R"( - background-color: #000; - color: #fff; - border-radius: 0; -)"; - -const char *promptStyles = R"( - background-color: #222; - color: #fff; - padding: 0 4px; -)"; - -const char *inputStyles = R"( - color: #fff; - padding: 0 4px; -)"; - -InputLine::InputLine(QString defaultInput, QWidget *parentNode) - : QWidget(parentNode) { - setContentsMargins(0, 0, 0, 0); - setStyleSheet(rootStyles); - - layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - setLayout(layout); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - - auto cmdLineBox = new QWidget(); - auto cmdLineLayout = new QHBoxLayout(); - cmdLineLayout->setContentsMargins(0, 0, 0, 0); - cmdLineLayout->setSpacing(0); - cmdLineBox->setLayout(cmdLineLayout); - - promptPrefix = new QLabel(); - promptPrefix->setStyleSheet(promptStyles); - promptPrefix->setContentsMargins(0, 0, 0, 0); - input = new QLineEdit(defaultInput); - input->setStyleSheet(inputStyles); - input->setFocusPolicy(Qt::StrongFocus); - input->setContentsMargins(0, 0, 0, 0); - - cmdLineLayout->addWidget(promptPrefix); - cmdLineLayout->addWidget(input, 1); - cmdLineBox->setFixedHeight(input->sizeHint().height()); - - layout->addWidget(cmdLineBox, 0); - - setAdapter(new CommandsAdapter()); -} - -void InputLine::setAdapter(Adapter *adapter) { - if (this->adapterInstance) { - layout->removeWidget(this->adapterInstance->completer()); - delete this->adapterInstance; - } - this->adapterInstance = adapter; - promptPrefix->setText(adapter->prompt()); - - auto completer = adapter->completer(); - layout->insertWidget(1, completer, 0, Qt::AlignmentFlag::AlignTop); - - connect(input, &QLineEdit::textChanged, completer, &Completer::onTextChange); - connect(completer, &Completer::accepted, input, &QLineEdit::setText); -} - -void InputLine::emitSubmit() { emit submitted(getInputText()); } - -void InputLine::keyPressEvent(QKeyEvent *event) { - auto combo = event->keyCombination(); - - // Forward events to completer first - bool shouldStop = adapterInstance->completer()->onKeyPressEvent(event); - if (shouldStop) - return; - - auto ctrlL = combo.key() == Qt::Key_L && - combo.keyboardModifiers().testFlag(Qt::ControlModifier); - auto esc = combo.key() == Qt::Key_Escape; - auto enter = combo.key() == Qt::Key_Return || combo.key() == Qt::Key_Enter; - if (esc || ctrlL) - emit cancelled(); - else if (enter) - emitSubmit(); -} - -void InputLine::setInputFocus(bool focussed) { - if (focussed) - input->setFocus(Qt::PopupFocusReason); - else - input->clearFocus(); -} diff --git a/src/widgets/MainWindow.cpp b/src/widgets/MainWindow.cpp index 7d045bc..327a77c 100644 --- a/src/widgets/MainWindow.cpp +++ b/src/widgets/MainWindow.cpp @@ -6,7 +6,6 @@ #include <QtWidgets/qapplication.h> #include "InputMediator.hpp" -#include "widgets/InputLine.hpp" #include "widgets/MainWindow.hpp" #include "widgets/WebViewStack.hpp" @@ -28,13 +27,16 @@ MainWindow::MainWindow() { new QWebEngineProfile("null-browser")); layout->addWidget(webViewStack); - // Command input - auto inputLine = new InputLine(); - layout->addWidget(inputLine); + // TODO: remoev + webViewStack->openUrl(QUrl("https://duckduckgo.com"), OpenType::OpenUrl); + webViewStack->openUrl(QUrl("https://ediblemonad.dev"), + OpenType::OpenUrlInBgTab); + webViewStack->openUrl(QUrl("https://github.com/trending"), + OpenType::OpenUrlInBgTab); - inputMediator = - new InputMediator(inputLine, webViewStack, LuaRuntime::instance()); + inputMediator = new InputMediator(webViewStack, LuaRuntime::instance()); + // TODO: remove keymapEvaluator.addKeymap("default", "<c-t>a", "Stuff"); keymapEvaluator.addKeymap("default", "<c-t>b", "Other stuff"); } @@ -42,18 +44,8 @@ MainWindow::MainWindow() { void MainWindow::keyPressEvent(QKeyEvent *event) { auto combo = event->keyCombination(); - if (combo.key() == Qt::Key_L && + if (combo.key() == Qt::Key_J && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - inputMediator->showURLInput(inputMediator->currentUrl().toString(), - OpenType::OpenUrl); - } else if (combo.key() == Qt::Key_Semicolon && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - inputMediator->showCommandInput(""); - } else if (combo.key() == Qt::Key_T && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - inputMediator->showTabsInput(); - } else if (combo.key() == Qt::Key_J && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { inputMediator->nextWebView(); } else if (combo.key() == Qt::Key_K && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { @@ -65,17 +57,11 @@ void MainWindow::keyPressEvent(QKeyEvent *event) { } bool MainWindow::eventFilter(QObject *object, QEvent *event) { - if (event->type() != QEvent::KeyPress && event->type() != QEvent::KeyRelease) + if (event->type() != QEvent::KeyPress) return false; - if (auto keyEvent = dynamic_cast<QKeyEvent *>(event)) { - if (keyEvent->type() == QEvent::KeyPress) - keymapEvaluator.evaluate(keyEvent->modifiers(), (Qt::Key)keyEvent->key()); - - // qDebug() << "EV SELF: " << (object == this) << " | " << event->type(); - // qDebug() << "Key: " << keyEvent->modifiers() << keyEvent->key(); - return true; - } + auto keyEvent = static_cast<QKeyEvent *>(event); + keymapEvaluator.evaluate(keyEvent->modifiers(), (Qt::Key)keyEvent->key()); - return false; + return true; } |
