Clean up code

Create separate re-usable component for `MaterialBrandSubMenu`

CURA-9522
This commit is contained in:
c.lamboo 2022-12-23 19:40:27 +01:00
parent 20fdf22e35
commit e490250d9d
3 changed files with 291 additions and 258 deletions

View File

@ -17,7 +17,11 @@ UM.MainWindow
{
id: base
readonly property var mainWindow: base
Item
{
id: mainWindow
anchors.fill: parent
}
// Cura application window title
title:

View File

@ -1,4 +1,4 @@
// Copyright (c) 2022 Ultimaker B.V.
// Copyright (c) 2022 UltiMaker
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
@ -85,35 +85,15 @@ Cura.MenuItem
onTriggered: menuPopup.close()
}
Popup
MaterialBrandSubMenu
{
id: menuPopup
width: materialTypesList.width + padding * 2
height: materialTypesList.height + padding * 2
property var flipped: false
onOpened:
{
var popupHeight = materialTypesModel.material_types.count * UM.Theme.getSize("menu").height
var parentGlobalY = parent.mapToItem(null, 0, 0).y
var overflowY = (parentGlobalY + popupHeight) - mainWindow.height
menuPopup.y = overflowY > 0 ? -overflowY : 0
var defaultX = parent.width - UM.Theme.getSize("default_lining").width
var parentGlobalX = parent.mapToItem(null, 0, 0).x
var overflowX = (parentGlobalX + defaultX + menuPopup.width) - mainWindow.width
menuPopup.x = overflowX > 0 ? overflowX : defaultX
scrollViewMaterialType.height = popupHeight > mainWindow.height ? mainWindow.height : popupHeight
menuPopup.height = popupHeight > mainWindow.height ? mainWindow.heigh : popupHeight
}
padding: background.border.width
// Nasty hack to ensure that we can keep track if the popup contains the mouse.
// Since we also want a hover for the sub items (and these events are sent async)
// We have to keep a count of itemHovered (instead of just a bool)
property int itemHovered: 0
MouseArea
{
id: submenuArea
@ -123,33 +103,11 @@ Cura.MenuItem
onEntered: hideTimer.restartTimer()
}
background: Rectangle
{
color: UM.Theme.getColor("main_background")
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
}
ScrollView
{
id: scrollViewMaterialType
width: UM.Theme.getSize("menu").width + scrollbar.width
height: parent.height
clip: true
ScrollBar.vertical: UM.ScrollBar
{
id: scrollbar
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
}
Column
{
id: materialTypesList
width: UM.Theme.getSize("menu").width
height: parent.height
height: childrenRect.height
spacing: 0
property var brandMaterials: materialTypesModel.material_types
@ -168,8 +126,6 @@ Cura.MenuItem
color: materialTypeButton.containsMouse ? UM.Theme.getColor("background_2") : "transparent"
property bool isFlipped: menuPopup.flipped
RowLayout
{
spacing: 0
@ -256,58 +212,17 @@ Cura.MenuItem
onTriggered: colorPopup.close()
}
Popup
MaterialBrandSubMenu
{
id: colorPopup
width: materialColorsList.width + padding * 2
height: materialColorsList.height + padding * 2
onOpened:
{
// This will be resolved before opening the popup if directly assigned to the properties
// This forces these values to update whenever a popup is opened
var popupHeight = model.colors.count * UM.Theme.getSize("menu").height
var parentGlobalY = parent.mapToItem(null, 0, 0).y
var overflowY = (parentGlobalY + popupHeight) - mainWindow.height
colorPopup.y = overflowY > 0 ? - overflowY - UM.Theme.getSize("default_lining").height : -UM.Theme.getSize("default_lining").height
var parentGlobalX = materialTypesList.mapToItem(null, 0, 0).x
var overflowX = (parentGlobalX + parent.width + colorPopup.width) - mainWindow.width
colorPopup.x = overflowX > 0 ? parent.width - overflowX : parent.width
scrollView.height = popupHeight > mainWindow.height ? mainWindow.height : popupHeight
colorPopup.height = popupHeight > mainWindow.height ? mainWindow.height : popupHeight
}
property int itemHovered: 0
padding: background.border.width
background: Rectangle
{
color: UM.Theme.getColor("main_background")
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
}
ScrollView
{
id: scrollView
width: UM.Theme.getSize("menu").width + scrollbar.width
height: parent.height
clip: true
ScrollBar.vertical: UM.ScrollBar
{
id: scrollbar
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
}
Column
{
id: materialColorsList
property var brandColors: model.colors
width: UM.Theme.getSize("menu").width
height: parent.height
height: childrenRect.height
spacing: 0
Repeater
@ -319,7 +234,31 @@ Cura.MenuItem
height: UM.Theme.getSize("menu").height
width: parent.width
color: materialColorButton.containsMouse ? UM.Theme.getColor("background_2") : "transparent"
color: materialColorButton.containsMouse ? UM.Theme.getColor("background_2") : UM.Theme.getColor("main_background")
MouseArea
{
id: materialColorButton
anchors.fill: parent
hoverEnabled: true
onClicked:
{
Cura.MachineManager.setMaterial(extruderIndex, model.container_node);
menuPopup.close();
colorPopup.close();
materialMenu.close();
}
onEntered:
{
menuPopup.itemHovered += 1;
colorPopup.itemHovered += 1;
}
onExited:
{
menuPopup.itemHovered -= 1;
colorPopup.itemHovered -= 1;
}
}
Item
{
@ -355,33 +294,6 @@ Cura.MenuItem
wrapMode: Text.NoWrap
}
}
MouseArea
{
id: materialColorButton
anchors.fill: parent
hoverEnabled: true
onClicked:
{
Cura.MachineManager.setMaterial(extruderIndex, model.container_node);
menuPopup.close();
colorPopup.close();
materialMenu.close();
}
onEntered:
{
menuPopup.itemHovered += 1;
colorPopup.itemHovered += 1;
}
onExited:
{
menuPopup.itemHovered -= 1;
colorPopup.itemHovered -= 1;
}
}
}
}
}
}
}

View File

@ -0,0 +1,117 @@
// Copyright (c) 2022 UltiMaker
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 2.4
import QtQuick.Layouts 2.7
import UM 1.5 as UM
import Cura 1.7 as Cura
Popup
{
id: materialBrandSubMenu
bottomPadding: UM.Theme.getSize("thin_margin").height
topPadding: UM.Theme.getSize("thin_margin").height
implicitWidth: scrollViewContent.width + scrollbar.width + leftPadding + rightPadding
implicitHeight: scrollViewContent.height + bottomPadding + topPadding
// offset position relative to the parent
property int implicitX: parent.width
property int implicitY: -UM.Theme.getSize("thin_margin").height
default property alias contents: scrollViewContent.children
x: implicitX
y: implicitY
// needed for the `mapToItem` function to work; apparently a Popup is not an Item
Item
{
id: materialBrandSubMenu
anchors.fill: parent
}
onOpened:
{
// we want to make sure here that the popup never goes out side the window so we adjust the x and y position
// based on the width/height of the mainWindow/popup. QML is a bit weird here though, as the globalPosition
// is in absolute coordinates relative to the origin of the mainWindow while setting the x and y coordinates
// of the popup only changes the position relative to the parent.
// reset position, the remainder of the function asumes this position and size
materialBrandSubMenu.x = implicitX;
materialBrandSubMenu.y = implicitY;
materialBrandSubMenu.width = implicitWidth;
materialBrandSubMenu.height = implicitHeight;
const globalPosition = materialBrandSubMenu.mapToItem(null, 0, 0);
if (globalPosition.y > mainWindow.height - materialBrandSubMenu.height)
{
if (mainWindow.height > materialBrandSubMenu.height)
{
const targetY = mainWindow.height - materialBrandSubMenu.height;
const deltaY = globalPosition.y - targetY;
materialBrandSubMenu.y = implicitY - deltaY;
}
else
{
// if popup is taller then the the component, limit
// the components height and set the position to
// y = 0 (in absolute coordinates)
materialBrandSubMenu.y = implicitY - globalPosition.y;
materialBrandSubMenu.height = mainWindow.height;
}
}
if (globalPosition.x > mainWindow.width - materialBrandSubMenu.width)
{
if (mainWindow.width > materialBrandSubMenu.width)
{
const targetY = mainWindow.width - materialBrandSubMenu.width;
const deltaX = globalPosition.x - targetY;
materialBrandSubMenu.x = implicitX - deltaX;
}
else
{
materialBrandSubMenu.x = implicitX - globalPosition.x;
materialBrandSubMenu.width = mainWindow.width;
}
}
}
padding: background.border.width
background: Rectangle
{
color: UM.Theme.getColor("main_background")
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
}
ScrollView
{
id: scrollView
anchors.fill: parent
contentHeight: scrollViewContent.height
clip: true
ScrollBar.vertical: UM.ScrollBar
{
id: scrollbar
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
}
Rectangle
{
id: scrollViewContent
width: childrenRect.width
height: childrenRect.height
}
}
}