From 61f99089288138989cf244d174882aa5088b738b Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sun, 9 Mar 2025 19:47:50 +0530 Subject: Refactor directory structure --- include/BrowserManager.hpp | 39 ------------ include/CommandInput.hpp | 28 --------- include/MainWindow.hpp | 24 ------- include/widgets/BrowserManager.hpp | 39 ++++++++++++ include/widgets/CommandInput.hpp | 28 +++++++++ include/widgets/MainWindow.hpp | 24 +++++++ spec/BrowserManagerSpec.cpp | 4 +- spec/CommandInputSpec.cpp | 4 +- spec/TestUtils.cpp | 20 ------ spec/TestUtils.h | 40 ------------ spec/main.cpp | 2 +- spec/testUtils.cpp | 20 ++++++ spec/testUtils.h | 40 ++++++++++++ src/BrowserManager.cpp | 124 ------------------------------------- src/CommandInput.cpp | 51 --------------- src/MainWindow.cpp | 76 ----------------------- src/main.cpp | 3 +- src/widgets/BrowserManager.cpp | 124 +++++++++++++++++++++++++++++++++++++ src/widgets/CommandInput.cpp | 50 +++++++++++++++ src/widgets/MainWindow.cpp | 76 +++++++++++++++++++++++ 20 files changed, 407 insertions(+), 409 deletions(-) delete mode 100644 include/BrowserManager.hpp delete mode 100644 include/CommandInput.hpp delete mode 100644 include/MainWindow.hpp create mode 100644 include/widgets/BrowserManager.hpp create mode 100644 include/widgets/CommandInput.hpp create mode 100644 include/widgets/MainWindow.hpp delete mode 100644 spec/TestUtils.cpp delete mode 100644 spec/TestUtils.h create mode 100644 spec/testUtils.cpp create mode 100644 spec/testUtils.h delete mode 100644 src/BrowserManager.cpp delete mode 100644 src/CommandInput.cpp delete mode 100644 src/MainWindow.cpp create mode 100644 src/widgets/BrowserManager.cpp create mode 100644 src/widgets/CommandInput.cpp create mode 100644 src/widgets/MainWindow.cpp diff --git a/include/BrowserManager.hpp b/include/BrowserManager.hpp deleted file mode 100644 index 84d6f6a..0000000 --- a/include/BrowserManager.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -class BrowserManager : public QWidget { - Q_OBJECT - -public: - inline static const QUrl NewtabURL = QUrl("about:blank"); - -public: - BrowserManager(QWebEngineProfile *profile = new QWebEngineProfile); - - QUrl currentUrl(); - void setCurrentUrl(QUrl url); - - QWebEngineView *createNewWebView(QUrl url = BrowserManager::NewtabURL, - bool focus = false); - - std::vector webViewUrls(); - u_int32_t currentWebViewIndex(); - u_int32_t webViewCount(); - void focusWebView(long index); - void nextWebView(); - void previousWebView(); - - void closeWebView(long index); - void closeCurrentWebView(); - - void onNewWebViewRequest(QWebEngineNewWindowRequest &request); - -private: - QWebEngineProfile *profile; - QStackedLayout *layout; - QList webViewList; -}; diff --git a/include/CommandInput.hpp b/include/CommandInput.hpp deleted file mode 100644 index a6ca0ed..0000000 --- a/include/CommandInput.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include -#include - -class CommandInput : public QWidget { - Q_OBJECT - -public: - CommandInput(QString defaultInput = "", QWidget *parentNode = nullptr); - void setInputFocus(bool focussed); - bool isInputFocussed(); - QString getInputCommand(); - void setInputText(QString text); - -signals: - void submitted(QString command); - void cancelled(); - -protected: - void keyPressEvent(QKeyEvent *event) override; - void emitSubmit(); - -private: - QBoxLayout *layout; - QLineEdit *input; -}; diff --git a/include/MainWindow.hpp b/include/MainWindow.hpp deleted file mode 100644 index fde3178..0000000 --- a/include/MainWindow.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "BrowserManager.hpp" -#include "CommandInput.hpp" - -class MainWindow : public QMainWindow { -public: - MainWindow(); - -protected: - void keyPressEvent(QKeyEvent *event) override; - void toggleURLInput(); - void evaluateCommand(QString command); - void hideURLInput(); - void showURLInput(); - -private: - BrowserManager *browserManager; - CommandInput *commandInput; -}; diff --git a/include/widgets/BrowserManager.hpp b/include/widgets/BrowserManager.hpp new file mode 100644 index 0000000..84d6f6a --- /dev/null +++ b/include/widgets/BrowserManager.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include +#include + +class BrowserManager : public QWidget { + Q_OBJECT + +public: + inline static const QUrl NewtabURL = QUrl("about:blank"); + +public: + BrowserManager(QWebEngineProfile *profile = new QWebEngineProfile); + + QUrl currentUrl(); + void setCurrentUrl(QUrl url); + + QWebEngineView *createNewWebView(QUrl url = BrowserManager::NewtabURL, + bool focus = false); + + std::vector webViewUrls(); + u_int32_t currentWebViewIndex(); + u_int32_t webViewCount(); + void focusWebView(long index); + void nextWebView(); + void previousWebView(); + + void closeWebView(long index); + void closeCurrentWebView(); + + void onNewWebViewRequest(QWebEngineNewWindowRequest &request); + +private: + QWebEngineProfile *profile; + QStackedLayout *layout; + QList webViewList; +}; diff --git a/include/widgets/CommandInput.hpp b/include/widgets/CommandInput.hpp new file mode 100644 index 0000000..a6ca0ed --- /dev/null +++ b/include/widgets/CommandInput.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +class CommandInput : public QWidget { + Q_OBJECT + +public: + CommandInput(QString defaultInput = "", QWidget *parentNode = nullptr); + void setInputFocus(bool focussed); + bool isInputFocussed(); + QString getInputCommand(); + void setInputText(QString text); + +signals: + void submitted(QString command); + void cancelled(); + +protected: + void keyPressEvent(QKeyEvent *event) override; + void emitSubmit(); + +private: + QBoxLayout *layout; + QLineEdit *input; +}; diff --git a/include/widgets/MainWindow.hpp b/include/widgets/MainWindow.hpp new file mode 100644 index 0000000..8ba0ed9 --- /dev/null +++ b/include/widgets/MainWindow.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +#include "widgets/BrowserManager.hpp" +#include "widgets/CommandInput.hpp" + +class MainWindow : public QMainWindow { +public: + MainWindow(); + +protected: + void keyPressEvent(QKeyEvent *event) override; + void toggleURLInput(); + void evaluateCommand(QString command); + void hideURLInput(); + void showURLInput(); + +private: + BrowserManager *browserManager; + CommandInput *commandInput; +}; diff --git a/spec/BrowserManagerSpec.cpp b/spec/BrowserManagerSpec.cpp index f4af481..efa1ca3 100644 --- a/spec/BrowserManagerSpec.cpp +++ b/spec/BrowserManagerSpec.cpp @@ -2,8 +2,8 @@ #include #include -#include "BrowserManager.hpp" -#include "TestUtils.h" +#include "testUtils.h" +#include "widgets/BrowserManager.hpp" class BrowserManagerSpec : public QObject { Q_OBJECT diff --git a/spec/CommandInputSpec.cpp b/spec/CommandInputSpec.cpp index 5636a63..e687f70 100644 --- a/spec/CommandInputSpec.cpp +++ b/spec/CommandInputSpec.cpp @@ -1,6 +1,6 @@ -#include "TestUtils.h" +#include "testUtils.h" -#include "CommandInput.hpp" +#include "widgets/CommandInput.hpp" class CommandInputSpec : public QObject { Q_OBJECT diff --git a/spec/TestUtils.cpp b/spec/TestUtils.cpp deleted file mode 100644 index e496a9b..0000000 --- a/spec/TestUtils.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include - -std::vector> &getQTestRegistry() { - static std::vector> registry; - return registry; -} - -int runAllTests() { - int exitCode = 0; - for (const auto &runTest : getQTestRegistry()) { - auto test = runTest(); - // printf(":::: %s\n", test->objectName().toStdString().c_str()); - exitCode |= QTest::qExec(test); - delete test; - } - getQTestRegistry().clear(); - return exitCode; -} diff --git a/spec/TestUtils.h b/spec/TestUtils.h deleted file mode 100644 index 20b3ba8..0000000 --- a/spec/TestUtils.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include - -#define ANSI_BOLD "\x1b[1m" -#define COLOR_CONTEXT "\x1b[32m" ANSI_BOLD -#define COLOR_IT "\x1b[36m" ANSI_BOLD -#define COLOR_SKIP "\x1b[33m" ANSI_BOLD -#define ANSI_RESET "\x1b[0m" - -#define context(msg) printf("⚪" COLOR_CONTEXT "%s" ANSI_RESET "\n", msg); - -#define it(msg) \ - printf(" ⚪" ANSI_BOLD COLOR_IT "it " ANSI_RESET COLOR_IT "%s" ANSI_RESET \ - "\n", \ - msg); \ - if (1) - -#define xit(msg) \ - printf(" ⚪" COLOR_SKIP "SKIPPED it %s" ANSI_RESET "\n", msg); \ - if (0) - -#define STRINGIFY(x) #x - -std::vector> &getQTestRegistry(); -int runAllTests(); - -#define QTEST_REGISTER(klass) \ - namespace { \ - const bool registered__##klass = []() { \ - getQTestRegistry().push_back([]() { \ - auto t = new klass; \ - t->setObjectName(#klass); \ - return t; \ - }); \ - return true; \ - }(); \ - }; diff --git a/spec/main.cpp b/spec/main.cpp index c085886..352ecba 100644 --- a/spec/main.cpp +++ b/spec/main.cpp @@ -1,4 +1,4 @@ -#include "TestUtils.h" +#include "testUtils.h" #include int main(int argc, char **argv) { diff --git a/spec/testUtils.cpp b/spec/testUtils.cpp new file mode 100644 index 0000000..e496a9b --- /dev/null +++ b/spec/testUtils.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +std::vector> &getQTestRegistry() { + static std::vector> registry; + return registry; +} + +int runAllTests() { + int exitCode = 0; + for (const auto &runTest : getQTestRegistry()) { + auto test = runTest(); + // printf(":::: %s\n", test->objectName().toStdString().c_str()); + exitCode |= QTest::qExec(test); + delete test; + } + getQTestRegistry().clear(); + return exitCode; +} diff --git a/spec/testUtils.h b/spec/testUtils.h new file mode 100644 index 0000000..20b3ba8 --- /dev/null +++ b/spec/testUtils.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +#define ANSI_BOLD "\x1b[1m" +#define COLOR_CONTEXT "\x1b[32m" ANSI_BOLD +#define COLOR_IT "\x1b[36m" ANSI_BOLD +#define COLOR_SKIP "\x1b[33m" ANSI_BOLD +#define ANSI_RESET "\x1b[0m" + +#define context(msg) printf("⚪" COLOR_CONTEXT "%s" ANSI_RESET "\n", msg); + +#define it(msg) \ + printf(" ⚪" ANSI_BOLD COLOR_IT "it " ANSI_RESET COLOR_IT "%s" ANSI_RESET \ + "\n", \ + msg); \ + if (1) + +#define xit(msg) \ + printf(" ⚪" COLOR_SKIP "SKIPPED it %s" ANSI_RESET "\n", msg); \ + if (0) + +#define STRINGIFY(x) #x + +std::vector> &getQTestRegistry(); +int runAllTests(); + +#define QTEST_REGISTER(klass) \ + namespace { \ + const bool registered__##klass = []() { \ + getQTestRegistry().push_back([]() { \ + auto t = new klass; \ + t->setObjectName(#klass); \ + return t; \ + }); \ + return true; \ + }(); \ + }; diff --git a/src/BrowserManager.cpp b/src/BrowserManager.cpp deleted file mode 100644 index ddc6105..0000000 --- a/src/BrowserManager.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include - -#include "BrowserManager.hpp" - -BrowserManager::BrowserManager(QWebEngineProfile *profile) : QWidget() { - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - layout = new QStackedLayout(this); - layout->setStackingMode(QStackedLayout::StackAll); - layout->setContentsMargins(0, 0, 0, 0); - - this->profile = profile; - - createNewWebView(BrowserManager::NewtabURL, true); -} - -QWebEngineView *BrowserManager::createNewWebView(QUrl url, bool focus) { - auto webview = new QWebEngineView(profile); - webview->setUrl(url); - layout->addWidget(webview); - webViewList.append(webview); - - connect(webview->page(), &QWebEnginePage::newWindowRequested, this, - &BrowserManager::onNewWebViewRequest); - - if (focus) - focusWebView(webViewList.length() - 1); - - return webview; -} - -void BrowserManager::onNewWebViewRequest(QWebEngineNewWindowRequest &request) { - switch (request.destination()) { - case QWebEngineNewWindowRequest::InNewTab: - createNewWebView(request.requestedUrl(), true); - break; - case QWebEngineNewWindowRequest::InNewBackgroundTab: - createNewWebView(request.requestedUrl(), false); - break; - case QWebEngineNewWindowRequest::InNewWindow: - // TODO: Impl - createNewWebView(request.requestedUrl(), true); - break; - case QWebEngineNewWindowRequest::InNewDialog: - // TODO: Impl - createNewWebView(request.requestedUrl(), true); - break; - } -} - -void BrowserManager::nextWebView() { - if (webViewList.isEmpty()) - return; - auto index = currentWebViewIndex() + 1; - auto total = webViewList.length(); - index = index >= total ? index % total : index; - focusWebView(index); -} - -void BrowserManager::previousWebView() { - if (webViewList.isEmpty()) - return; - auto index = currentWebViewIndex() - 1; - auto total = webViewList.length(); - index = index < 0 ? total + index : index; - focusWebView(index); -} - -void BrowserManager::closeCurrentWebView() { - closeWebView(currentWebViewIndex()); -} - -void BrowserManager::closeWebView(long index) { - if (index < 0 || index >= webViewList.length()) - return; - - auto webview = webViewList.at(index); - layout->removeWidget(webview); - webViewList.removeAt(index); - disconnect(webview->page()); - webview->deleteLater(); - - focusWebView(currentWebViewIndex()); - - if (webViewList.isEmpty()) { - createNewWebView(BrowserManager::NewtabURL, true); - } -} - -std::vector BrowserManager::webViewUrls() { - std::vector urls; - for (auto &view : webViewList) - urls.push_back(view->url()); - return urls; -} - -u_int32_t BrowserManager::currentWebViewIndex() { - return layout->currentIndex(); -} -u_int32_t BrowserManager::webViewCount() { return webViewList.length(); } - -void BrowserManager::focusWebView(long index) { - if (webViewList.isEmpty()) - return; - - index = std::max((long)0, std::min(index, (long)webViewList.length() - 1)); - layout->setCurrentIndex(index); -} - -QUrl BrowserManager::currentUrl() { - if (currentWebViewIndex() >= webViewList.length()) - return QUrl("about:newtab"); - - return webViewList.at(currentWebViewIndex())->url(); -} - -void BrowserManager::setCurrentUrl(QUrl url) { - if (currentWebViewIndex() >= webViewList.length()) - return; - - webViewList.at(currentWebViewIndex())->setUrl(url); -} diff --git a/src/CommandInput.cpp b/src/CommandInput.cpp deleted file mode 100644 index d553d19..0000000 --- a/src/CommandInput.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "CommandInput.hpp" - -CommandInput::CommandInput(QString defaultInput, QWidget *parentNode) - : QWidget(parentNode) { - setContentsMargins(0, 0, 0, 0); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - setStyleSheet("background-color: #000; color: #fff; border-radius: 0;"); - - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - input = new QLineEdit(defaultInput, this); - input->setFocusPolicy(Qt::StrongFocus); - layout->addWidget(input); - setFixedHeight(input->sizeHint().height()); -} - -void CommandInput::emitSubmit() { emit submitted(getInputCommand()); } - -void CommandInput::keyPressEvent(QKeyEvent *event) { - auto combo = event->keyCombination(); - 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 CommandInput::setInputText(QString text) { input->setText(text); } - -bool CommandInput::isInputFocussed() { return input->hasFocus(); } - -void CommandInput::setInputFocus(bool focussed) { - if (focussed) - input->setFocus(Qt::PopupFocusReason); - else - input->clearFocus(); -} - -QString CommandInput::getInputCommand() { return input->text(); } diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp deleted file mode 100644 index ee8d128..0000000 --- a/src/MainWindow.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include - -#include "BrowserManager.hpp" -#include "CommandInput.hpp" -#include "MainWindow.hpp" - -MainWindow::MainWindow() { - setStyleSheet("background-color: #000; color: #fff;"); - setCentralWidget(new QWidget()); - - // Root stacked layout - auto layout = new QStackedLayout(); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - layout->setStackingMode(QStackedLayout::StackAll); - centralWidget()->setLayout(layout); - - // Web engine - browserManager = new BrowserManager(new QWebEngineProfile("web-browser")); - layout->addWidget(browserManager); - - // Command input - commandInput = new CommandInput(browserManager->currentUrl().toString()); - hideURLInput(); - commandInput->move(0, 0); - connect(commandInput, &CommandInput::submitted, this, - &MainWindow::evaluateCommand); - connect(commandInput, &CommandInput::cancelled, this, - &MainWindow::hideURLInput); - layout->addWidget(commandInput); -} - -void MainWindow::hideURLInput() { - commandInput->setInputFocus(false); - commandInput->setHidden(true); -} - -void MainWindow::showURLInput() { - commandInput->setInputText(browserManager->currentUrl().toString()); - commandInput->raise(); - commandInput->setHidden(false); - commandInput->setInputFocus(true); -} - -void MainWindow::evaluateCommand(QString command) { - if (!command.isEmpty()) - browserManager->setCurrentUrl(command); - hideURLInput(); -} - -void MainWindow::keyPressEvent(QKeyEvent *event) { - auto combo = event->keyCombination(); - if (combo.key() == Qt::Key_L && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - toggleURLInput(); - } else if (combo.key() == Qt::Key_T && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->createNewWebView(QUrl("https://duckduckgo.com"), true); - } else if (combo.key() == Qt::Key_J && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->nextWebView(); - } else if (combo.key() == Qt::Key_K && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->previousWebView(); - } else if (combo.key() == Qt::Key_W && - combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->closeCurrentWebView(); - } -} - -void MainWindow::toggleURLInput() { - commandInput->isHidden() ? showURLInput() : hideURLInput(); -} diff --git a/src/main.cpp b/src/main.cpp index 91e605e..3e2e2eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,7 @@ #include #include -#include -#include "MainWindow.hpp" +#include "widgets/MainWindow.hpp" int main(int argc, char *argv[]) { // QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); diff --git a/src/widgets/BrowserManager.cpp b/src/widgets/BrowserManager.cpp new file mode 100644 index 0000000..a2390fc --- /dev/null +++ b/src/widgets/BrowserManager.cpp @@ -0,0 +1,124 @@ +#include +#include +#include + +#include "widgets/BrowserManager.hpp" + +BrowserManager::BrowserManager(QWebEngineProfile *profile) : QWidget() { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + layout = new QStackedLayout(this); + layout->setStackingMode(QStackedLayout::StackAll); + layout->setContentsMargins(0, 0, 0, 0); + + this->profile = profile; + + createNewWebView(BrowserManager::NewtabURL, true); +} + +QWebEngineView *BrowserManager::createNewWebView(QUrl url, bool focus) { + auto webview = new QWebEngineView(profile); + webview->setUrl(url); + layout->addWidget(webview); + webViewList.append(webview); + + connect(webview->page(), &QWebEnginePage::newWindowRequested, this, + &BrowserManager::onNewWebViewRequest); + + if (focus) + focusWebView(webViewList.length() - 1); + + return webview; +} + +void BrowserManager::onNewWebViewRequest(QWebEngineNewWindowRequest &request) { + switch (request.destination()) { + case QWebEngineNewWindowRequest::InNewTab: + createNewWebView(request.requestedUrl(), true); + break; + case QWebEngineNewWindowRequest::InNewBackgroundTab: + createNewWebView(request.requestedUrl(), false); + break; + case QWebEngineNewWindowRequest::InNewWindow: + // TODO: Impl + createNewWebView(request.requestedUrl(), true); + break; + case QWebEngineNewWindowRequest::InNewDialog: + // TODO: Impl + createNewWebView(request.requestedUrl(), true); + break; + } +} + +void BrowserManager::nextWebView() { + if (webViewList.isEmpty()) + return; + auto index = currentWebViewIndex() + 1; + auto total = webViewList.length(); + index = index >= total ? index % total : index; + focusWebView(index); +} + +void BrowserManager::previousWebView() { + if (webViewList.isEmpty()) + return; + auto index = currentWebViewIndex() - 1; + auto total = webViewList.length(); + index = index < 0 ? total + index : index; + focusWebView(index); +} + +void BrowserManager::closeCurrentWebView() { + closeWebView(currentWebViewIndex()); +} + +void BrowserManager::closeWebView(long index) { + if (index < 0 || index >= webViewList.length()) + return; + + auto webview = webViewList.at(index); + layout->removeWidget(webview); + webViewList.removeAt(index); + disconnect(webview->page()); + webview->deleteLater(); + + focusWebView(currentWebViewIndex()); + + if (webViewList.isEmpty()) { + createNewWebView(BrowserManager::NewtabURL, true); + } +} + +std::vector BrowserManager::webViewUrls() { + std::vector urls; + for (auto &view : webViewList) + urls.push_back(view->url()); + return urls; +} + +u_int32_t BrowserManager::currentWebViewIndex() { + return layout->currentIndex(); +} +u_int32_t BrowserManager::webViewCount() { return webViewList.length(); } + +void BrowserManager::focusWebView(long index) { + if (webViewList.isEmpty()) + return; + + index = std::max((long)0, std::min(index, (long)webViewList.length() - 1)); + layout->setCurrentIndex(index); +} + +QUrl BrowserManager::currentUrl() { + if (currentWebViewIndex() >= webViewList.length()) + return QUrl("about:newtab"); + + return webViewList.at(currentWebViewIndex())->url(); +} + +void BrowserManager::setCurrentUrl(QUrl url) { + if (currentWebViewIndex() >= webViewList.length()) + return; + + webViewList.at(currentWebViewIndex())->setUrl(url); +} diff --git a/src/widgets/CommandInput.cpp b/src/widgets/CommandInput.cpp new file mode 100644 index 0000000..464065a --- /dev/null +++ b/src/widgets/CommandInput.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + +#include "widgets/CommandInput.hpp" + +CommandInput::CommandInput(QString defaultInput, QWidget *parentNode) + : QWidget(parentNode) { + setContentsMargins(0, 0, 0, 0); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + setStyleSheet("background-color: #000; color: #fff; border-radius: 0;"); + + auto layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + input = new QLineEdit(defaultInput, this); + input->setFocusPolicy(Qt::StrongFocus); + layout->addWidget(input); + setFixedHeight(input->sizeHint().height()); +} + +void CommandInput::emitSubmit() { emit submitted(getInputCommand()); } + +void CommandInput::keyPressEvent(QKeyEvent *event) { + auto combo = event->keyCombination(); + 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 CommandInput::setInputText(QString text) { input->setText(text); } + +bool CommandInput::isInputFocussed() { return input->hasFocus(); } + +void CommandInput::setInputFocus(bool focussed) { + if (focussed) + input->setFocus(Qt::PopupFocusReason); + else + input->clearFocus(); +} + +QString CommandInput::getInputCommand() { return input->text(); } diff --git a/src/widgets/MainWindow.cpp b/src/widgets/MainWindow.cpp new file mode 100644 index 0000000..e660e52 --- /dev/null +++ b/src/widgets/MainWindow.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include + +#include "widgets/BrowserManager.hpp" +#include "widgets/CommandInput.hpp" +#include "widgets/MainWindow.hpp" + +MainWindow::MainWindow() { + setStyleSheet("background-color: #000; color: #fff;"); + setCentralWidget(new QWidget()); + + // Root stacked layout + auto layout = new QStackedLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->setStackingMode(QStackedLayout::StackAll); + centralWidget()->setLayout(layout); + + // Web engine + browserManager = new BrowserManager(new QWebEngineProfile("web-browser")); + layout->addWidget(browserManager); + + // Command input + commandInput = new CommandInput(browserManager->currentUrl().toString()); + hideURLInput(); + commandInput->move(0, 0); + connect(commandInput, &CommandInput::submitted, this, + &MainWindow::evaluateCommand); + connect(commandInput, &CommandInput::cancelled, this, + &MainWindow::hideURLInput); + layout->addWidget(commandInput); +} + +void MainWindow::hideURLInput() { + commandInput->setInputFocus(false); + commandInput->setHidden(true); +} + +void MainWindow::showURLInput() { + commandInput->setInputText(browserManager->currentUrl().toString()); + commandInput->raise(); + commandInput->setHidden(false); + commandInput->setInputFocus(true); +} + +void MainWindow::evaluateCommand(QString command) { + if (!command.isEmpty()) + browserManager->setCurrentUrl(command); + hideURLInput(); +} + +void MainWindow::keyPressEvent(QKeyEvent *event) { + auto combo = event->keyCombination(); + if (combo.key() == Qt::Key_L && + combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { + toggleURLInput(); + } else if (combo.key() == Qt::Key_T && + combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { + browserManager->createNewWebView(QUrl("https://duckduckgo.com"), true); + } else if (combo.key() == Qt::Key_J && + combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { + browserManager->nextWebView(); + } else if (combo.key() == Qt::Key_K && + combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { + browserManager->previousWebView(); + } else if (combo.key() == Qt::Key_W && + combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { + browserManager->closeCurrentWebView(); + } +} + +void MainWindow::toggleURLInput() { + commandInput->isHidden() ? showURLInput() : hideURLInput(); +} -- cgit v1.3.1