aboutsummaryrefslogtreecommitdiff
path: root/src/widgets
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-03-09 19:47:50 +0530
committerAkshay Nair <phenax5@gmail.com>2025-03-09 19:47:50 +0530
commit61f99089288138989cf244d174882aa5088b738b (patch)
treeea1202b098b92e85b16e670d1c3ea1b86fcaef58 /src/widgets
parent1e2302be2b47fbeb340db7482ed8476c829a7f66 (diff)
downloadnull-browser-61f99089288138989cf244d174882aa5088b738b.tar.gz
null-browser-61f99089288138989cf244d174882aa5088b738b.zip
Refactor directory structure
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/BrowserManager.cpp124
-rw-r--r--src/widgets/CommandInput.cpp50
-rw-r--r--src/widgets/MainWindow.cpp76
3 files changed, 250 insertions, 0 deletions
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 <QStackedLayout>
+#include <QWebEngineNewWindowRequest>
+#include <QWebEngineView>
+
+#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<QUrl> BrowserManager::webViewUrls() {
+ std::vector<QUrl> 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 <QHBoxLayout>
+#include <QKeyEvent>
+#include <QLineEdit>
+#include <QVBoxLayout>
+#include <QWidget>
+#include <QWindow>
+
+#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 <QKeyEvent>
+#include <QStackedLayout>
+#include <QVBoxLayout>
+#include <QWebEngineView>
+
+#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();
+}