You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
5.1 KiB
204 lines
5.1 KiB
/*
|
|
* Copyright 2024 Vincent Sanders <vince@netsurf-browser.org>
|
|
*
|
|
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
|
*
|
|
* NetSurf is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* NetSurf is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
* Implementation of netsurf scaffolding (widget) for qt.
|
|
*/
|
|
|
|
#include <QTabBar>
|
|
#include <QProxyStyle>
|
|
|
|
extern "C" {
|
|
#include "utils/log.h"
|
|
#include "utils/messages.h"
|
|
|
|
#include "netsurf/content.h"
|
|
}
|
|
|
|
#include "qt/application.cls.h"
|
|
#include "qt/scaffolding.cls.h"
|
|
#include "qt/scaffoldstyle.cls.h"
|
|
#include "qt/window.cls.h"
|
|
|
|
static NS_Scaffold *current = nullptr; /**< currently selected scaffold */
|
|
|
|
ScaffoldStyle::ScaffoldStyle(QObject *parent)
|
|
: QProxyStyle()
|
|
{
|
|
setParent(parent);
|
|
}
|
|
|
|
/**
|
|
* proxy style for sub element rect for TabWidgetRightCorner
|
|
*
|
|
* move the right corner widget to just after the tabbar area. padding is added
|
|
* horizontaly and verticaly. padding size is derived from vertical gap to
|
|
* center of the tabbar.
|
|
*
|
|
* \todo cope with reverse layout
|
|
*/
|
|
QRect ScaffoldStyle::subElementRect(SubElement subElement,
|
|
const QStyleOption *option,
|
|
const QWidget *widget) const
|
|
{
|
|
if (subElement == QStyle::SE_TabWidgetRightCorner) {
|
|
QRect tabRect = QProxyStyle::subElementRect(QStyle::SE_TabWidgetTabBar, option, widget);
|
|
QRect rightCornerRect = QProxyStyle::subElementRect(QStyle::SE_TabWidgetRightCorner, option, widget);
|
|
|
|
int padding = (tabRect.height() - rightCornerRect.height()) / 2;
|
|
int x = qMin(tabRect.left() + tabRect.width() + padding,
|
|
rightCornerRect.x());
|
|
return QRect(x,
|
|
rightCornerRect.y() - padding,
|
|
rightCornerRect.width(),
|
|
rightCornerRect.height());
|
|
|
|
}
|
|
|
|
return QProxyStyle::subElementRect(subElement, option, widget);
|
|
}
|
|
|
|
|
|
NS_Scaffold::NS_Scaffold(QWidget *parent)
|
|
: QTabWidget(parent),
|
|
m_newtab(new QAction("+", this))
|
|
{
|
|
setStyle (new ScaffoldStyle(this));
|
|
|
|
m_newtab->setToolTip(messages_get("NewTab"));
|
|
m_newtab->setShortcut(QKeySequence::AddTab);
|
|
connect(m_newtab, &QAction::triggered,
|
|
this, &NS_Scaffold::newtab_slot);
|
|
|
|
QToolButton *addbutton = new QToolButton(this);
|
|
addbutton->setDefaultAction(m_newtab);
|
|
addbutton->setStyleSheet("QToolButton {border:0} QToolButton:hover {background-color: rgba(255, 255, 255, 0.5);}");
|
|
setCornerWidget(addbutton, Qt::TopRightCorner);
|
|
|
|
connect(tabBar(), &QTabBar::tabCloseRequested,
|
|
this, &NS_Scaffold::destroyTab);
|
|
connect(this, &QTabWidget::currentChanged,
|
|
this, &NS_Scaffold::changeTab);
|
|
setTabsClosable(true);
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
}
|
|
|
|
/**
|
|
* close event destroys all tabs
|
|
*/
|
|
void NS_Scaffold::closeEvent(QCloseEvent *event)
|
|
{
|
|
/* build a list of the window objects and iterate it to call destroy */
|
|
QList<NS_Window *> pages;
|
|
for (int idx = 0; idx < count();idx++) {
|
|
pages.append((NS_Window *)widget(idx));
|
|
}
|
|
for (int idx = 0; idx < pages.size(); idx++) {
|
|
pages.at(idx)->destroy();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* destroy tab slot
|
|
*/
|
|
void NS_Scaffold::destroyTab(int index)
|
|
{
|
|
NS_Window *page;
|
|
page = (NS_Window *)widget(index);
|
|
page->destroy();
|
|
}
|
|
|
|
/**
|
|
* changed tab slot
|
|
*/
|
|
void NS_Scaffold::changeTab(int index)
|
|
{
|
|
if (index == -1) {
|
|
this->deleteLater();
|
|
}
|
|
}
|
|
|
|
void NS_Scaffold::newtab_slot(bool checked)
|
|
{
|
|
current = this;
|
|
NS_Application::create_browser_widget(NULL, NULL, true);
|
|
}
|
|
|
|
void NS_Scaffold::changeTabTitle(const char *title)
|
|
{
|
|
QObject *tabsender = sender();
|
|
QWidget *tabwidget;
|
|
|
|
for (int index=0 ;
|
|
(tabwidget=(NS_Window *)widget(index)) != nullptr;
|
|
index++) {
|
|
if (tabwidget == tabsender) {
|
|
setTabText(index, title);
|
|
if (isTabVisible(index)) {
|
|
setWindowTitle(title);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void NS_Scaffold::changeTabIcon(const QIcon &icon)
|
|
{
|
|
QObject *tabsender = sender();
|
|
QWidget *tabwidget;
|
|
|
|
for (int index=0 ;
|
|
(tabwidget=(NS_Window *)widget(index)) != nullptr;
|
|
index++) {
|
|
if (tabwidget == tabsender) {
|
|
setTabIcon(index, icon);
|
|
if (isTabVisible(index)) {
|
|
setWindowIcon(icon);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* get a scaffolding widget
|
|
*
|
|
* \param page An existing page widget or NULL if not present
|
|
* \param use_current True if an current scaffold should be used
|
|
*/
|
|
NS_Scaffold *
|
|
NS_Scaffold::get_scaffold(QWidget *page, bool use_current)
|
|
{
|
|
NS_Scaffold *scaffold = nullptr;
|
|
if (use_current && (page != nullptr)) {
|
|
/* todo check page parent is actually a scaffold */
|
|
scaffold = qobject_cast<NS_Scaffold *>(page->parentWidget()->parentWidget());
|
|
} else if ((use_current) && (current != nullptr)) {
|
|
scaffold = current;
|
|
} else {
|
|
scaffold = new NS_Scaffold(nullptr);
|
|
|
|
}
|
|
NSLOG(netsurf, DEBUG, "page:%p use_current:%d current:%p scaffold:%p",
|
|
page, use_current, current, scaffold);
|
|
current = scaffold;
|
|
return scaffold;
|
|
}
|