diff --git a/.gitignore b/.gitignore index 60b59e6829..2ec5af2b9b 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,4 @@ run.sh .scannerwork/ CuraEngine +/.coverage diff --git a/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py index f75082e20d..10ae9dabf5 100644 --- a/cura/UI/WelcomePagesModel.py +++ b/cura/UI/WelcomePagesModel.py @@ -59,6 +59,10 @@ class WelcomePagesModel(ListModel): # Store all the previous page indices so it can go back. self._previous_page_indices_stack = deque() # type: deque + # If the welcome flow should be shown. It can show the complete flow or just the changelog depending on the + # specific case. See initialize() for how this variable is set. + self._should_show_welcome_flow = False + allFinished = pyqtSignal() # emitted when all steps have been finished currentPageIndexChanged = pyqtSignal() @@ -174,6 +178,12 @@ class WelcomePagesModel(ListModel): self.currentPageIndexChanged.emit() + shouldShowWelcomeFlowChanged = pyqtSignal() + + @pyqtProperty(bool, notify = shouldShowWelcomeFlowChanged) + def shouldShowWelcomeFlow(self) -> bool: + return self._should_show_welcome_flow + # Gets the page index with the given page ID. If the page ID doesn't exist, returns None. def getPageIndexById(self, page_id: str) -> Optional[int]: page_idx = None @@ -189,7 +199,35 @@ class WelcomePagesModel(ListModel): return QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, os.path.join("WelcomePages", page_filename))) + # FIXME: HACKs for optimization that we don't update the model every time the active machine gets changed. + def _onActiveMachineChanged(self) -> None: + self._application.getMachineManager().globalContainerChanged.disconnect(self._onActiveMachineChanged) + self._initialize(update_should_show_flag = False) + def initialize(self) -> None: + self._application.getMachineManager().globalContainerChanged.connect(self._onActiveMachineChanged) + self._initialize() + + def _initialize(self, update_should_show_flag: bool = True) -> None: + show_whatsnew_only = False + if update_should_show_flag: + has_active_machine = self._application.getMachineManager().activeMachine is not None + has_app_just_upgraded = self._application.hasJustUpdatedFromOldVersion() + + # Only show the what's new dialog if there's no machine and we have just upgraded + show_complete_flow = not has_active_machine + show_whatsnew_only = has_active_machine and has_app_just_upgraded + + # FIXME: This is a hack. Because of the circular dependency between MachineManager, ExtruderManager, and + # possibly some others, setting the initial active machine is not done when the MachineManager gets initialized. + # So at this point, we don't know if there will be an active machine or not. It could be that the active machine + # files are corrupted so we cannot rely on Preferences either. This makes sure that once the active machine + # gets changed, this model updates the flags, so it can decide whether to show the welcome flow or not. + should_show_welcome_flow = show_complete_flow or show_whatsnew_only + if should_show_welcome_flow != self._should_show_welcome_flow: + self._should_show_welcome_flow = should_show_welcome_flow + self.shouldShowWelcomeFlowChanged.emit() + # All pages all_pages_list = [{"id": "welcome", "page_url": self._getBuiltinWelcomePagePath("WelcomeContent.qml"), @@ -221,7 +259,11 @@ class WelcomePagesModel(ListModel): }, ] - self._pages = all_pages_list + pages_to_show = all_pages_list + if show_whatsnew_only: + pages_to_show = list(filter(lambda x: x["id"] == "whats_new", all_pages_list)) + + self._pages = pages_to_show self.setItems(self._pages) # For convenience, inject the default "next" button text to each item if it's not present. diff --git a/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml index 3287643286..007db41f2b 100644 --- a/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml +++ b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml @@ -57,6 +57,7 @@ Item { text: catalog.i18nc("@title:label", "Printer Settings") font: UM.Theme.getFont("medium_bold") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } @@ -172,6 +173,7 @@ Item { text: catalog.i18nc("@title:label", "Printhead Settings") font: UM.Theme.getFont("medium_bold") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/plugins/UltimakerMachineActions/BedLevelMachineAction.qml b/plugins/UltimakerMachineActions/BedLevelMachineAction.qml index dac545990f..a9f7e93d44 100644 --- a/plugins/UltimakerMachineActions/BedLevelMachineAction.qml +++ b/plugins/UltimakerMachineActions/BedLevelMachineAction.qml @@ -29,7 +29,8 @@ Cura.MachineAction width: parent.width text: catalog.i18nc("@title", "Build Plate Leveling") wrapMode: Text.WordWrap - font.pointSize: 18 + font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } @@ -41,6 +42,8 @@ Cura.MachineAction width: parent.width wrapMode: Text.WordWrap text: catalog.i18nc("@label", "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted.") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } @@ -52,6 +55,8 @@ Cura.MachineAction width: parent.width wrapMode: Text.WordWrap text: catalog.i18nc("@label", "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle.") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml b/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml index 0aef5e08e1..13525f6eb3 100644 --- a/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml +++ b/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml @@ -29,6 +29,7 @@ Cura.MachineAction wrapMode: Text.WordWrap text: catalog.i18nc("@label", "Please select any upgrades made to this Ultimaker 2.") font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml b/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml index b0abad0fcf..565ba2fa0e 100644 --- a/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml +++ b/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml @@ -29,6 +29,7 @@ Cura.MachineAction wrapMode: Text.WordWrap text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker Original") font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index f5cbe8ad53..e640b25b24 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -794,6 +794,7 @@ UM.MainWindow title: catalog.i18nc("@title:window", "Add Printer") model: CuraApplication.getAddPrinterPagesModel() progressBarVisible: false + hasCancelButton: true } Cura.WizardDialog @@ -802,6 +803,7 @@ UM.MainWindow title: catalog.i18nc("@title:window", "What's New") model: CuraApplication.getWhatsNewPagesModel() progressBarVisible: false + hasCancelButton: false } Connections diff --git a/resources/qml/MachineSettings/ComboBoxWithOptions.qml b/resources/qml/MachineSettings/ComboBoxWithOptions.qml index bf56d1d58e..fbb05c23b1 100644 --- a/resources/qml/MachineSettings/ComboBoxWithOptions.qml +++ b/resources/qml/MachineSettings/ComboBoxWithOptions.qml @@ -59,6 +59,7 @@ UM.TooltipArea anchors.verticalCenter: comboBox.verticalCenter visible: text != "" font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/resources/qml/MachineSettings/GcodeTextArea.qml b/resources/qml/MachineSettings/GcodeTextArea.qml index eb20cdc856..d1f8f51f01 100644 --- a/resources/qml/MachineSettings/GcodeTextArea.qml +++ b/resources/qml/MachineSettings/GcodeTextArea.qml @@ -41,6 +41,7 @@ UM.TooltipArea anchors.top: parent.top anchors.left: parent.left font: UM.Theme.getFont("medium_bold") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } @@ -59,13 +60,16 @@ UM.TooltipArea hoverEnabled: true selectByMouse: true + text: (propertyProvider.properties.value) ? propertyProvider.properties.value : "" font: UM.Theme.getFont("fixed") renderType: Text.NativeRendering - text: (propertyProvider.properties.value) ? propertyProvider.properties.value : "" + color: UM.Theme.getColor("text") wrapMode: TextEdit.NoWrap background: Rectangle { + color: UM.Theme.getColor("main_background") + border.color: { if (!gcodeTextArea.enabled) diff --git a/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml b/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml index c6872617bc..5921a39933 100644 --- a/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml +++ b/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml @@ -66,6 +66,7 @@ UM.TooltipArea anchors.verticalCenter: textFieldWithUnit.verticalCenter visible: text != "" font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } @@ -135,6 +136,7 @@ UM.TooltipArea hoverEnabled: true selectByMouse: true font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering // When the textbox gets focused by TAB, select all text diff --git a/resources/qml/MachineSettings/SimpleCheckBox.qml b/resources/qml/MachineSettings/SimpleCheckBox.qml index d2edc28487..49ff9fd6e9 100644 --- a/resources/qml/MachineSettings/SimpleCheckBox.qml +++ b/resources/qml/MachineSettings/SimpleCheckBox.qml @@ -53,6 +53,7 @@ UM.TooltipArea anchors.verticalCenter: checkBox.verticalCenter visible: text != "" font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml b/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml index 2feff668e7..cb0bad67ea 100644 --- a/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml @@ -85,6 +85,8 @@ Item { id: machineList + cacheBuffer: 0 // Workaround for https://bugreports.qt.io/browse/QTBUG-49224 + model: UM.DefinitionContainersModel { id: machineDefinitionsModel @@ -142,6 +144,7 @@ Item verticalAlignment: Text.AlignVCenter text: button.text font: UM.Theme.getFont("default_bold") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } } @@ -200,9 +203,10 @@ Item Label { - text: catalog.i18nc("@label", "Printer Name") + text: catalog.i18nc("@label", "Printer name") anchors.verticalCenter: parent.verticalCenter font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter renderType: Text.NativeRendering } @@ -213,9 +217,12 @@ Item anchors.verticalCenter: parent.verticalCenter width: (parent.width / 2) | 0 placeholderText: catalog.i18nc("@text", "Please give your printer a name") - - // Make sure that the fill is not empty - validator: RegExpValidator { regExp: /.+/ } + maximumLength: 40 + validator: RegExpValidator + { + regExp: printerNameTextField.machineNameValidator.machineNameRegex + } + property var machineNameValidator: Cura.MachineNameValidator { } } } } diff --git a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml index 884bd0a70e..117f8a59d7 100644 --- a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml @@ -72,6 +72,8 @@ Item section.criteria: ViewSection.FullString section.delegate: sectionHeading + cacheBuffer: 0 // Workaround for https://bugreports.qt.io/browse/QTBUG-49224 + Component.onCompleted: { // Select the first one that's not "unknown" by default. diff --git a/resources/qml/WelcomePages/AddPrinterByIpContent.qml b/resources/qml/WelcomePages/AddPrinterByIpContent.qml index 293b8c4e81..f1b315697a 100644 --- a/resources/qml/WelcomePages/AddPrinterByIpContent.qml +++ b/resources/qml/WelcomePages/AddPrinterByIpContent.qml @@ -61,6 +61,7 @@ Item anchors.top: parent.top font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering text: catalog.i18nc("@label", "Enter the IP address or hostname of your printer on the network.") } @@ -129,6 +130,7 @@ Item anchors.top: parent.top anchors.margins: UM.Theme.getSize("default_margin").width font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering visible: @@ -162,6 +164,7 @@ Item id: printerNameLabel anchors.top: parent.top font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering text: "???" @@ -175,14 +178,53 @@ Item columns: 2 columnSpacing: UM.Theme.getSize("default_margin").width - Label { font: UM.Theme.getFont("default"); text: catalog.i18nc("@label", "Type"); renderType: Text.NativeRendering } - Label { id: typeText; font: UM.Theme.getFont("default"); text: "?"; renderType: Text.NativeRendering } + Label + { + text: catalog.i18nc("@label", "Type") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } + Label + { + id: typeText + text: "?" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } - Label { font: UM.Theme.getFont("default"); text: catalog.i18nc("@label", "Firmware version"); renderType: Text.NativeRendering } - Label { id: firmwareText; font: UM.Theme.getFont("default"); text: "0.0.0.0"; renderType: Text.NativeRendering } + Label + { + text: catalog.i18nc("@label", "Firmware version") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } + Label + { + id: firmwareText + text: "0.0.0.0" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } - Label { font: UM.Theme.getFont("default"); text: catalog.i18nc("@label", "Address"); renderType: Text.NativeRendering } - Label { id: addressText; font: UM.Theme.getFont("default"); text: "0.0.0.0"; renderType: Text.NativeRendering } + Label + { + text: catalog.i18nc("@label", "Address") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } + Label + { + id: addressText + text: "0.0.0.0" + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + } Connections { diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml index 6074c06eac..bb1498ebd5 100644 --- a/resources/qml/WelcomePages/CloudContent.qml +++ b/resources/qml/WelcomePages/CloudContent.qml @@ -52,7 +52,6 @@ Item topMargin: UM.Theme.getSize("default_margin").height } - // Pictures and texts are arranged using Columns with spacing. The whole picture and text area is centered in // the cloud contents area. Column @@ -105,6 +104,7 @@ Item } textFormat: Text.RichText font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } } diff --git a/resources/qml/WelcomePages/DataCollectionsContent.qml b/resources/qml/WelcomePages/DataCollectionsContent.qml index 610ce889d6..a2e54c1849 100644 --- a/resources/qml/WelcomePages/DataCollectionsContent.qml +++ b/resources/qml/WelcomePages/DataCollectionsContent.qml @@ -71,6 +71,7 @@ Item textFormat: Text.RichText wrapMode: Text.WordWrap font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering MouseArea diff --git a/resources/qml/WelcomePages/DropDownHeader.qml b/resources/qml/WelcomePages/DropDownHeader.qml index a712382850..88da32c879 100644 --- a/resources/qml/WelcomePages/DropDownHeader.qml +++ b/resources/qml/WelcomePages/DropDownHeader.qml @@ -21,7 +21,7 @@ Cura.RoundedRectangle border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - color: hovered ? UM.Theme.getColor("secondary_button_hover") : UM.Theme.getColor("secondary_button") + color: UM.Theme.getColor("secondary") radius: UM.Theme.getSize("default_radius").width cornerSide: contentShown ? Cura.RoundedRectangle.Direction.Up : Cura.RoundedRectangle.Direction.All diff --git a/resources/qml/WelcomePages/DropDownWidget.qml b/resources/qml/WelcomePages/DropDownWidget.qml index 7251e8c520..a54424b7cf 100644 --- a/resources/qml/WelcomePages/DropDownWidget.qml +++ b/resources/qml/WelcomePages/DropDownWidget.qml @@ -49,7 +49,7 @@ Item anchors.left: parent.left anchors.right: parent.right height: UM.Theme.getSize("expandable_component_content_header").height - rightIconSource: contentShown ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right") + rightIconSource: contentShown ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") contentShown: base.contentShown } diff --git a/resources/qml/WelcomePages/UserAgreementContent.qml b/resources/qml/WelcomePages/UserAgreementContent.qml index 2c8196f0e1..c6fb03ccd4 100644 --- a/resources/qml/WelcomePages/UserAgreementContent.qml +++ b/resources/qml/WelcomePages/UserAgreementContent.qml @@ -44,6 +44,7 @@ Item textFormat: Text.RichText wrapMode: Text.WordWrap font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/resources/qml/WelcomePages/WelcomeContent.qml b/resources/qml/WelcomePages/WelcomeContent.qml index b59c91a0b7..0099c3db3d 100644 --- a/resources/qml/WelcomePages/WelcomeContent.qml +++ b/resources/qml/WelcomePages/WelcomeContent.qml @@ -46,6 +46,7 @@ Item horizontalAlignment: Text.AlignHCenter text: catalog.i18nc("@text", "Please follow these steps to set up\nUltimaker Cura. This will only take a few moments.") font: UM.Theme.getFont("medium") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } diff --git a/resources/qml/WelcomePages/WizardDialog.qml b/resources/qml/WelcomePages/WizardDialog.qml index 4a0867c9a2..31240b1ef5 100644 --- a/resources/qml/WelcomePages/WizardDialog.qml +++ b/resources/qml/WelcomePages/WizardDialog.qml @@ -24,11 +24,14 @@ Window minimumWidth: 580 * screenScaleFactor minimumHeight: 600 * screenScaleFactor + maximumWidth: minimumWidth + maximumHeight: minimumHeight color: UM.Theme.getColor("main_background") property var model: null // Needs to be set by whoever is using this dialog. property alias progressBarVisible: wizardPanel.progressBarVisible + property alias hasCancelButton: cancelButton.visible onVisibilityChanged: { @@ -51,4 +54,20 @@ Window target: model onAllFinished: dialog.hide() } + + Cura.SecondaryButton + { + id: cancelButton + + text: catalog.i18nc("@button", "Cancel") + + visible: false + + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: UM.Theme.getSize("default_margin").width + + enabled: true + onClicked: dialog.visible = false + } } diff --git a/resources/qml/Widgets/CheckBox.qml b/resources/qml/Widgets/CheckBox.qml index c7536da6d3..1de0e4addd 100644 --- a/resources/qml/Widgets/CheckBox.qml +++ b/resources/qml/Widgets/CheckBox.qml @@ -70,6 +70,7 @@ CheckBox leftPadding: control.indicator.width + control.spacing text: control.text font: control.font + color: UM.Theme.getColor("text") renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter } diff --git a/resources/qml/Widgets/RadioButton.qml b/resources/qml/Widgets/RadioButton.qml index b101b3739b..13aee7ba90 100644 --- a/resources/qml/Widgets/RadioButton.qml +++ b/resources/qml/Widgets/RadioButton.qml @@ -49,6 +49,7 @@ RadioButton leftPadding: radioButton.indicator.width + radioButton.spacing text: radioButton.text font: radioButton.font + color: UM.Theme.getColor("text") renderType: Text.NativeRendering } } diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml index 249eca5bd6..b806087f9a 100644 --- a/resources/qml/Widgets/ScrollableTextArea.qml +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -19,6 +19,7 @@ ScrollView background: Rectangle // Border { + color: UM.Theme.getColor("main_background") border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width } @@ -27,6 +28,7 @@ ScrollView { id: _textArea font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") textFormat: TextEdit.PlainText renderType: Text.NativeRendering selectByMouse: true diff --git a/resources/qml/Widgets/TextField.qml b/resources/qml/Widgets/TextField.qml index c15d3d0c2d..28074d4415 100644 --- a/resources/qml/Widgets/TextField.qml +++ b/resources/qml/Widgets/TextField.qml @@ -20,6 +20,7 @@ TextField hoverEnabled: true selectByMouse: true font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") renderType: Text.NativeRendering states: [ @@ -49,6 +50,8 @@ TextField { id: backgroundRectangle + color: UM.Theme.getColor("main_background") + anchors.margins: Math.round(UM.Theme.getSize("default_lining").width) radius: UM.Theme.getSize("setting_control_radius").width diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index a5e35e1c02..84f06bee0e 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -94,8 +94,8 @@ "action_button_active": [39, 44, 48, 30], "action_button_active_text": [255, 255, 255, 255], "action_button_active_border": [255, 255, 255, 100], - "action_button_disabled": [39, 44, 48, 255], - "action_button_disabled_text": [255, 255, 255, 80], + "action_button_disabled": [19, 24, 28, 255], + "action_button_disabled_text": [200, 200, 200, 80], "action_button_disabled_border": [255, 255, 255, 30], "scrollbar_background": [39, 44, 48, 0],