Merge panel-layout code: choose where to place sidebar + nav

main
Adriaan de Groot 5 years ago
commit 59ef307af2

@ -16,6 +16,9 @@ This release contains contributions from (alphabetically by first name):
Calamares). The example QML that is compiled into Calamares has
been improved. To use your own QML, put files `calamares-sidebar.qml`
or `calamares-navigation.qml` into the branding directory.
- The sidebar and navigation can now be placed on any side of the
main window. This is probably only useful for QML-based UIs.
See `branding.desc` for details.
## Modules ##
- The *welcomeq* module has been improved with better layout and

@ -45,12 +45,25 @@ windowPlacement: center
# - "widget" or unset, use traditional sidebar (logo, items)
# - "none", hide it entirely
# - "qml", use calamares-sidebar.qml from branding folder
# In addition, you **may** specify a side, separated by a comma,
# from the kind. Valid sides are:
# - "left" (if not specified, uses this)
# - "right"
# - "top"
# - "bottom"
# For instance, "widget,right" is valid; so is "qml", which defaults
# to putting the sidebar on the left. Also valid is "qml,top".
# While "widget,top" is valid, the widgets code is **not** flexible
# and results will be terrible.
sidebar: widget
# Kind of navigation (button panel on the bottom).
# - "widget" or unset, use traditional navigation
# - "none", hide it entirely
# - "qml", use calamares-navigation.qml from branding folder
# In addition, you **may** specify a side, separated by a comma,
# from the kind. The same sides are valid as for *sidebar*,
# except the default is *bottom*.
navigation: widget
# These are strings shown to the user in the user interface.

@ -132,11 +132,10 @@ CalamaresWindow::getWidgetSidebar( int desiredWidth )
}
QWidget*
CalamaresWindow::getQmlSidebar( int desiredWidth )
CalamaresWindow::getQmlSidebar( int )
{
CalamaresUtils::registerCalamaresModels();
QQuickWidget* w = new QQuickWidget( this );
w->setFixedWidth( desiredWidth );
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
w->setSource( QUrl(
@ -217,7 +216,6 @@ CalamaresWindow::getQmlNavigation()
{
CalamaresUtils::registerCalamaresModels();
QQuickWidget* w = new QQuickWidget( this );
w->setFixedHeight( 64 );
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
w->setSource( QUrl(
@ -251,6 +249,28 @@ flavoredWidget( Calamares::Branding::PanelFlavor flavor,
NOTREACHED return nullptr; // All enum values handled above
}
/** @brief Adds widgets to @p layout if they belong on this @p side
*/
static inline void
insertIf( QBoxLayout* layout,
Calamares::Branding::PanelSide side,
QWidget* first,
Calamares::Branding::PanelSide firstSide )
{
if ( first && side == firstSide )
{
if ( ( side == Calamares::Branding::PanelSide::Left ) || ( side == Calamares::Branding::PanelSide::Right ) )
{
first->setMinimumWidth( qMax( first->minimumWidth(), 64 ) );
}
else
{
first->setMinimumHeight( qMax( first->minimumHeight(), 64 ) );
}
layout->addWidget( first );
}
}
CalamaresWindow::CalamaresWindow( QWidget* parent )
: QWidget( parent )
, m_debugWindow( nullptr )
@ -273,6 +293,8 @@ CalamaresWindow::CalamaresWindow( QWidget* parent )
using CalamaresUtils::windowPreferredHeight;
using CalamaresUtils::windowPreferredWidth;
using PanelSide = Calamares::Branding::PanelSide;
// Needs to match what's checked in DebugWindow
this->setObjectName( "mainApp" );
@ -292,21 +314,6 @@ CalamaresWindow::CalamaresWindow( QWidget* parent )
resize( w, h );
m_viewManager = Calamares::ViewManager::instance( this );
QBoxLayout* mainLayout = new QHBoxLayout;
setLayout( mainLayout );
QWidget* sideBox = flavoredWidget(
branding->sidebarFlavor(),
this,
&CalamaresWindow::getWidgetSidebar,
&CalamaresWindow::getQmlSidebar,
qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) );
if ( sideBox )
{
mainLayout->addWidget( sideBox );
}
if ( branding->windowExpands() )
{
connect( m_viewManager, &Calamares::ViewManager::enlarge, this, &CalamaresWindow::enlarge );
@ -319,16 +326,35 @@ CalamaresWindow::CalamaresWindow( QWidget* parent )
// and requires an extra show() (at least with KWin/X11) which
// is too annoying. Instead, leave it up to ignoring-the-quit-
// event, which is also the ViewManager's responsibility.
QBoxLayout* mainLayout = new QHBoxLayout;
QBoxLayout* contentsLayout = new QVBoxLayout;
contentsLayout->addWidget( m_viewManager->centralWidget() );
setLayout( mainLayout );
QWidget* sideBox = flavoredWidget(
branding->sidebarFlavor(),
this,
&CalamaresWindow::getWidgetSidebar,
&CalamaresWindow::getQmlSidebar,
qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) );
QWidget* navigation = flavoredWidget(
branding->navigationFlavor(), this, &CalamaresWindow::getWidgetNavigation, &CalamaresWindow::getQmlNavigation );
if ( navigation )
{
contentsLayout->addWidget( navigation );
}
// Build up the contentsLayout (a VBox) top-to-bottom
// .. note that the bottom is mirrored wrt. the top
insertIf( contentsLayout, PanelSide::Top, sideBox, branding->sidebarSide() );
insertIf( contentsLayout, PanelSide::Top, navigation, branding->navigationSide() );
contentsLayout->addWidget( m_viewManager->centralWidget() );
insertIf( contentsLayout, PanelSide::Bottom, navigation, branding->navigationSide() );
insertIf( contentsLayout, PanelSide::Bottom, sideBox, branding->sidebarSide() );
// .. and then the mainLayout left-to-right
insertIf( mainLayout, PanelSide::Left, sideBox, branding->sidebarSide() );
insertIf( mainLayout, PanelSide::Left, navigation, branding->navigationSide() );
mainLayout->addLayout( contentsLayout );
insertIf( mainLayout, PanelSide::Right, navigation, branding->navigationSide() );
insertIf( mainLayout, PanelSide::Right, sideBox, branding->sidebarSide() );
CalamaresUtils::unmarginLayout( mainLayout );
CalamaresUtils::unmarginLayout( contentsLayout );

@ -405,6 +405,79 @@ getString( const YAML::Node& doc, const char* key )
return QString();
}
static inline void
flavorAndSide( const YAML::Node& doc, const char* key, Branding::PanelFlavor& flavor, Branding::PanelSide& side )
{
using PanelFlavor = Branding::PanelFlavor;
using PanelSide = Branding::PanelSide;
// *INDENT-OFF*
// clang-format off
static const NamedEnumTable< PanelFlavor > sidebarFlavorNames {
{ QStringLiteral( "widget" ), PanelFlavor::Widget },
{ QStringLiteral( "none" ), PanelFlavor::None },
{ QStringLiteral( "hidden" ), PanelFlavor::None },
{ QStringLiteral( "qml" ), PanelFlavor::Qml }
};
static const NamedEnumTable< PanelSide > panelSideNames {
{ QStringLiteral( "left" ), PanelSide::Left },
{ QStringLiteral( "right" ), PanelSide::Right },
{ QStringLiteral( "top" ), PanelSide::Top },
{ QStringLiteral( "bottom" ), PanelSide::Bottom }
};
// clang-format on
// *INDENT-ON*
bool ok = false;
QString configValue = getString( doc, key );
if ( configValue.isEmpty() )
{
// Complain with the original values
cWarning() << "Branding setting for" << key << "is missing, using" << sidebarFlavorNames.find( flavor, ok )
<< panelSideNames.find( side, ok );
return;
}
QStringList parts = configValue.split( ',' );
if ( parts.length() == 1 )
{
PanelFlavor f = sidebarFlavorNames.find( configValue, ok );
if ( ok )
{
flavor = f;
}
else
{
// Complain with the original value
cWarning() << "Branding setting for" << key << "interpreted as" << sidebarFlavorNames.find( flavor, ok )
<< panelSideNames.find( side, ok );
}
return;
}
for ( const QString& spart : parts )
{
bool isFlavor = false;
bool isSide = false;
PanelFlavor f = sidebarFlavorNames.find( spart, isFlavor );
PanelSide s = panelSideNames.find( spart, isSide );
if ( isFlavor )
{
flavor = f;
}
else if ( isSide )
{
side = s;
}
else
{
cWarning() << "Branding setting for" << key << "contains unknown" << spart << "interpreted as"
<< sidebarFlavorNames.find( flavor, ok ) << panelSideNames.find( side, ok );
return;
}
}
}
void
Branding::initSimpleSettings( const YAML::Node& doc )
{
@ -419,12 +492,6 @@ Branding::initSimpleSettings( const YAML::Node& doc )
{ QStringLiteral( "free" ), WindowPlacement::Free },
{ QStringLiteral( "center" ), WindowPlacement::Center }
};
static const NamedEnumTable< PanelFlavor > sidebarFlavorNames {
{ QStringLiteral( "widget" ), PanelFlavor::Widget },
{ QStringLiteral( "none" ), PanelFlavor::None },
{ QStringLiteral( "hidden" ), PanelFlavor::None },
{ QStringLiteral( "qml" ), PanelFlavor::Qml }
};
// clang-format on
// *INDENT-ON*
bool ok = false;
@ -443,18 +510,8 @@ Branding::initSimpleSettings( const YAML::Node& doc )
cWarning() << "Branding module-setting *windowPlacement* interpreted as"
<< placementNames.find( m_windowPlacement, ok );
}
m_sidebarFlavor = sidebarFlavorNames.find( getString( doc, "sidebar" ), ok );
if ( !ok )
{
cWarning() << "Branding module-setting *sidebar* interpreted as"
<< sidebarFlavorNames.find( m_sidebarFlavor, ok );
}
m_navigationFlavor = sidebarFlavorNames.find( getString( doc, "navigation" ), ok);
if ( !ok )
{
cWarning() << "Branding module-setting *navigation* interpreted as"
<< sidebarFlavorNames.find( m_navigationFlavor, ok );
}
flavorAndSide( doc, "sidebar", m_sidebarFlavor, m_sidebarSide );
flavorAndSide( doc, "navigation", m_navigationFlavor, m_navigationSide );
QString windowSize = getString( doc, "windowSize" );
if ( !windowSize.isEmpty() )

@ -123,7 +123,7 @@ public:
Free
};
Q_ENUM( WindowPlacement )
///@brief What kind of sidebar to use in the main window
///@brief What kind of panel (sidebar, navigation) to use in the main window
enum class PanelFlavor
{
None,
@ -131,6 +131,16 @@ public:
Qml
};
Q_ENUM( PanelFlavor )
///@brief Where to place a panel (sidebar, navigation)
enum class PanelSide
{
None,
Left,
Right,
Top,
Bottom
};
Q_ENUM( PanelSide )
static Branding* instance();
@ -201,6 +211,9 @@ public slots:
QString styleString( StyleEntry styleEntry ) const;
QString imagePath( ImageEntry imageEntry ) const;
PanelSide sidebarSide() const { return m_sidebarSide; }
PanelSide navigationSide() const { return m_navigationSide; }
private:
static Branding* s_instance;
@ -231,6 +244,8 @@ private:
PanelFlavor m_sidebarFlavor = PanelFlavor::Widget;
PanelFlavor m_navigationFlavor = PanelFlavor::Widget;
PanelSide m_sidebarSide = PanelSide::Left;
PanelSide m_navigationSide = PanelSide::Bottom;
};
template < typename U >

Loading…
Cancel
Save