diff --git a/.gitignore b/.gitignore
index 005acb4..f950fa0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
-build/
+build*
update-translations.sh
+*.kdev4
diff --git a/generate_code.sh b/generate_code.sh
new file mode 100755
index 0000000..9c85fc9
--- /dev/null
+++ b/generate_code.sh
@@ -0,0 +1,65 @@
+#!/usr/bin/bash
+
+itemTitles=("Buttons" "Icon" "Title" "Menu")
+
+settingsLines=""
+for name in ${itemTitles[@]}; do
+ settingsLines="$settingsLines\n property alias cfg_controlPart${name}Position: controlPart${name}Position.currentIndex"
+ settingsLines="$settingsLines\n property alias cfg_controlPart${name}ShowOnMouseIn: controlPart${name}ShowOnMouseIn.checked"
+ settingsLines="$settingsLines\n property alias cfg_controlPart${name}ShowOnMouseOut: controlPart${name}ShowOnMouseOut.checked"
+ settingsLines="$settingsLines\n property alias cfg_controlPart${name}HorizontalAlignment: controlPart${name}HorizontalAlignment.currentIndex\n"
+done
+
+echo -e "$settingsLines"
+
+controlLines=""
+for name in ${itemTitles[@]}; do
+ controlLines="$controlLines
+ Item {
+ width: 2
+ height: units.smallSpacing
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('${name}')
+ font.bold: true
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Position:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPart${name}Position
+ model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
+ }
+
+ CheckBox {
+ id: controlPart${name}ShowOnMouseIn
+ text: i18n('Show on mouse in')
+ Layout.columnSpan: 2
+ }
+
+ CheckBox {
+ id: controlPart${name}ShowOnMouseOut
+ text: i18n('Show on mouse out')
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Horizontal alignment:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPart${name}HorizontalAlignment
+ model: [i18n('Left'), i18n('Right')]
+ }
+
+"
+done
+
+echo -e "$controlLines"
diff --git a/package/contents/config/config.qml b/package/contents/config/config.qml
index f798d17..1966dd9 100644
--- a/package/contents/config/config.qml
+++ b/package/contents/config/config.qml
@@ -1,30 +1,35 @@
import QtQuick 2.2
import org.kde.plasma.configuration 2.0
ConfigModel {
+ ConfigCategory {
+ name: i18n("Layout")
+ icon: "preferences-desktop-color"
+ source: "config/ConfigLayout.qml"
+ }
ConfigCategory {
name: i18n("Appearance")
icon: "preferences-desktop-color"
source: "config/ConfigAppearance.qml"
}
ConfigCategory {
name: i18n("Behaviour")
icon: "preferences-desktop"
source: "config/ConfigBehaviour.qml"
}
ConfigCategory {
name: i18n("Buttons")
icon: "preferences-activities"
source: "config/ConfigButtons.qml"
}
ConfigCategory {
name: i18n("Mouse Control")
icon: "preferences-desktop-mouse"
source: "config/ConfigMouseControl.qml"
}
ConfigCategory {
name: i18n("Application Menu")
icon: "application-menu"
source: "config/ConfigAppMenu.qml"
}
}
diff --git a/package/contents/config/main.xml b/package/contents/config/main.xml
index fae991c..d1559e2 100644
--- a/package/contents/config/main.xml
+++ b/package/contents/config/main.xml
@@ -1,207 +1,275 @@
+
+
+ buttons|icon|title|menu
+
+
+ 5.0
+
+
+ 0
+
+
+ true
+
+
+ true
+
+
+ 0
+
+
+ 0
+
+
+ true
+
+
+ true
+
+
+ 0
+
+
+ 0
+
+
+ true
+
+
+ true
+
+
+ 0
+
+
+ 0
+
+
+ true
+
+
+ true
+
+
+ 0
+
+
+
+
true
false
false
false
close|maximize|minimize|pin
true
false
false
false
false
false
false
0
false
0.5
10
false
0.2
0.0
true
0
0
0
false
^(.*)\s*[—–\-:]\s*(Mozilla )?([^—–\-:]+)$
$3 — $1
Plasma Desktop :: %activity%
false
1000
true
false
false
5
1
false
false
false
false
false
false
false
false
true
false
0
0.1
1.0
true
0
0
false
0
diff --git a/package/contents/ui/AppMenu.qml b/package/contents/ui/AppMenu.qml
index 35dcd79..eb4df62 100644
--- a/package/contents/ui/AppMenu.qml
+++ b/package/contents/ui/AppMenu.qml
@@ -1,176 +1,179 @@
import QtQuick 2.2
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 2.0 as PlasmaComponents
Item {
id: appmenu
anchors.fill: parent
+ property bool mouseInWidget: false
+
property bool appmenuEnabled: plasmoid.configuration.appmenuEnabled
property bool appmenuNextToButtons: plasmoid.configuration.appmenuNextToButtons
property bool appmenuFillHeight: plasmoid.configuration.appmenuFillHeight
property bool appmenuFontBold: plasmoid.configuration.appmenuFontBold
property bool appmenuDoNotHide: plasmoid.configuration.appmenuDoNotHide
property bool appmenuEnabledAndNonEmpty: appmenuEnabled && appMenuModel !== null && appMenuModel.menuAvailable
property bool appmenuOpened: appmenuEnabled && plasmoid.nativeInterface.currentIndex > -1
property var appMenuModel: null
property bool appmenuButtonsOffsetEnabled: !buttonsStandalone && appmenuNextToButtons && childrenRect.width > 0
property double appmenuOffsetWidth: visible && appmenuNextToIconAndText && !appmenuSwitchSidesWithIconAndText
- ? appmenu.childrenRect.width + (appmenuButtonsOffsetEnabled ? controlButtonsArea.width : 0) + appmenuSideMargin*2
+ ? appmenu.childrenRect.width + (appmenuButtonsOffsetEnabled ? buttonsItem.width : 0) + appmenuSideMargin*2
: 0
- visible: appmenuEnabledAndNonEmpty && !noWindowActive && (appmenuDoNotHide || mouseHover || appmenuOpened)
+ visible: appmenuEnabledAndNonEmpty && !noWindowActive && (appmenuDoNotHide || main.mouseHover || appmenuOpened)
GridLayout {
id: buttonGrid
Layout.minimumWidth: implicitWidth
Layout.minimumHeight: implicitHeight
flow: GridLayout.LeftToRight
rowSpacing: 0
columnSpacing: 0
anchors.top: parent.top
anchors.left: parent.left
- property double placementOffsetButtons: appmenuNextToButtons && controlButtonsArea.visible ? controlButtonsArea.width + appmenuSideMargin : 0
+ property double placementOffsetButtons: appmenuNextToButtons && buttonsItem.visible ? buttonsItem.width + appmenuSideMargin : 0
property double placementOffset: appmenuNextToIconAndText && appmenuSwitchSidesWithIconAndText
- ? activeWindowListView.anchors.leftMargin + windowTitleText.anchors.leftMargin + windowTitleText.contentWidth + appmenuSideMargin
+ //? activeWindowListView.anchors.leftMargin + windowTitle.anchors.leftMargin +
+ ? windowTitle.anchors.leftMargin + windowTitle.contentWidthwindowTitle.contentWidth + appmenuSideMargin
: placementOffsetButtons
anchors.leftMargin: (bp === 1 || bp === 3) ? parent.width - width - placementOffset : placementOffset
anchors.topMargin: (bp === 2 || bp === 3) ? 0 : parent.height - height
Component.onCompleted: {
plasmoid.nativeInterface.buttonGrid = buttonGrid
plasmoid.nativeInterface.enabled = appmenuEnabled
}
Connections {
target: plasmoid.nativeInterface
onRequestActivateIndex: {
var idx = Math.max(0, Math.min(buttonRepeater.count - 1, index))
var button = buttonRepeater.itemAt(index)
if (button) {
button.clicked(null)
}
}
}
Repeater {
id: buttonRepeater
model: null
MouseArea {
id: appmenuButton
hoverEnabled: true
readonly property int buttonIndex: index
property bool menuOpened: plasmoid.nativeInterface.currentIndex === index
Layout.preferredWidth: appmenuButtonBackground.width
Layout.preferredHeight: appmenuButtonBackground.height
Rectangle {
id: appmenuButtonBackground
border.color: 'transparent'
width: appmenuButtonTitle.implicitWidth + units.smallSpacing * 3
height: appmenuFillHeight ? appmenu.height : appmenuButtonTitle.implicitHeight + units.smallSpacing
color: menuOpened ? theme.highlightColor : 'transparent'
radius: units.smallSpacing / 2
}
PlasmaComponents.Label {
id: appmenuButtonTitle
anchors.top: appmenuButtonBackground.top
anchors.bottom: appmenuButtonBackground.bottom
verticalAlignment: Text.AlignVCenter
anchors.horizontalCenter: appmenuButtonBackground.horizontalCenter
font.pixelSize: fontPixelSize * plasmoid.configuration.appmenuButtonTextSizeScale
text: activeMenu.replace('&', '')
font.weight: appmenuFontBold ? Font.Bold : theme.defaultFont.weight
}
onClicked: {
plasmoid.nativeInterface.trigger(this, index)
}
onEntered: {
appmenuButtonBackground.border.color = theme.highlightColor
}
onExited: {
appmenuButtonBackground.border.color = 'transparent'
}
}
}
}
Rectangle {
id: separator
anchors.left: buttonGrid.left
anchors.leftMargin: appmenuSwitchSidesWithIconAndText ? - appmenuSideMargin * 0.5 : buttonGrid.width + appmenuSideMargin * 0.5
anchors.verticalCenter: buttonGrid.verticalCenter
height: 0.8 * parent.height
width: 1
visible: appmenuNextToIconAndText && plasmoid.configuration.appmenuSeparatorEnabled
color: theme.textColor
opacity: 0.4
}
function initializeAppModel() {
if (appMenuModel !== null) {
return
}
print('initializing appMenuModel...')
try {
appMenuModel = Qt.createQmlObject(
'import QtQuick 2.2;\
import org.kde.plasma.plasmoid 2.0;\
import org.kde.private.activeWindowControl 1.0 as ActiveWindowControlPrivate;\
ActiveWindowControlPrivate.AppMenuModel {\
id: appMenuModel;\
Component.onCompleted: {\
plasmoid.nativeInterface.model = appMenuModel\
}\
}', main)
} catch (e) {
print('appMenuModel failed to initialize: ' + e)
}
print('initializing appmenu...DONE ' + appMenuModel)
if (appMenuModel !== null) {
resetAppmenuModel()
}
}
function resetAppmenuModel() {
if (appmenuEnabled) {
initializeAppModel()
if (appMenuModel === null) {
return
}
print('setting model in QML: ' + appMenuModel)
for (var key in appMenuModel) {
print(' ' + key + ' -> ' + appMenuModel[key])
}
plasmoid.nativeInterface.model = appMenuModel
buttonRepeater.model = appMenuModel
} else {
plasmoid.nativeInterface.model = null
buttonRepeater.model = null
}
}
onAppmenuEnabledChanged: {
appmenu.resetAppmenuModel()
if (appMenuModel !== null) {
plasmoid.nativeInterface.enabled = appmenuEnabled
}
}
}
\ No newline at end of file
diff --git a/package/contents/ui/ControlButton.qml b/package/contents/ui/ControlButton.qml
index cb87f03..9458eaa 100644
--- a/package/contents/ui/ControlButton.qml
+++ b/package/contents/ui/ControlButton.qml
@@ -1,69 +1,74 @@
/*
* Copyright 2015 Martin Kotelnik
*
* This program 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; either version 2 of
* the License, or (at your option) any later version.
*
* This program 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 .
*/
import QtQuick 2.2
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
MouseArea {
id: controlButton
- height: controlButtonsArea.height
- width: controlButtonsArea.controlButtonsHeight
+ height: controlButtons.height
+ width: controlButtons.controlButtonsHeight
property bool mouseInside: false
property bool iconActive: (iconName !== 'alldesktops' && iconName !== 'maximize') || (iconName === 'alldesktops' && main.isActiveWindowPinned) || (iconName === 'maximize' && main.currentWindowMaximized)
property string themeName: textColorLight ? 'breeze-dark' : 'default'
property string customAuroraeThemePath: main.automaticButtonThemeEnabled ? plasmoid.nativeInterface.auroraeThemePath : manualAuroraeThemePathResolved
property string customAuroraeImageExt: main.automaticButtonThemeEnabled ? plasmoid.nativeInterface.auroraeThemeType : manualAuroraeThemeExtension
property bool usingAuroraeTheme: customAuroraeThemePath ? true : false
property string buttonImagePath: customAuroraeThemePath ? customAuroraeThemePath + '/' + iconName + '.' + customAuroraeImageExt : Qt.resolvedUrl('../icons/' + themeName + '/' + iconName + '.svg')
property string svgElementId: usingAuroraeTheme
? (iconActive && iconName === 'alldesktops') ? (mouseInside ? 'pressed-center' : 'pressed-center') : (mouseInside ? 'hover-center' : 'active-center')
: iconActive ? (mouseInside ? 'active-hover' : 'active-idle') : (mouseInside ? 'inactive-hover' : 'inactive-idle')
PlasmaCore.Svg {
id: buttonSvg
imagePath: buttonImagePath
}
// icon
PlasmaCore.SvgItem {
id: svgItem
width: parent.width
height: width
svg: buttonSvg
elementId: svgElementId
anchors.verticalCenter: parent.verticalCenter
}
hoverEnabled: true
onEntered: {
mouseInside = true
+ controlButtons.mouseInWidget = true
}
onExited: {
mouseInside = false
+ controlButtons.mouseInWidget = false
}
// trigger active window action
onClicked: {
- controlButtonsArea.mouseInWidget = true
+ if (!controlButtons.showItem) {
+ return;
+ }
+ controlButtons.mouseInWidget = true
main.performActiveWindowAction(windowOperation)
}
}
diff --git a/package/contents/ui/ControlButtons.qml b/package/contents/ui/ControlButtons.qml
new file mode 100644
index 0000000..4599e53
--- /dev/null
+++ b/package/contents/ui/ControlButtons.qml
@@ -0,0 +1,37 @@
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Layouts 1.1
+import org.kde.plasma.plasmoid 2.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+
+Item {
+ id: controlButtons
+
+ property bool mouseInWidget: false
+ property var controlButtonsModel
+
+ property double controlButtonsHeight: parent.height * plasmoid.configuration.buttonSize
+ property bool showItem
+
+ opacity: showItem ? 1 : 0
+
+ height: main.buttonsVerticalCenter ? parent.height : controlButtonsHeight
+ width: controlButtonsHeight + ((model.count - 1) * (controlButtonsHeight + main.controlButtonsSpacing))
+
+ ListView {
+
+ orientation: ListView.Horizontal
+
+ spacing: main.controlButtonsSpacing
+
+ visible: true
+
+ model: controlButtonsModel
+
+ anchors.fill: parent
+
+ delegate: ControlButton { }
+
+ }
+}
+
diff --git a/package/contents/ui/WindowIcon.qml b/package/contents/ui/WindowIcon.qml
new file mode 100644
index 0000000..554fcae
--- /dev/null
+++ b/package/contents/ui/WindowIcon.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Layouts 1.1
+import org.kde.plasma.plasmoid 2.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+
+PlasmaCore.IconItem {
+ id: iconItem
+
+ width: parent.height
+ height: parent.height
+
+ source: plasmoid.configuration.noWindowIcon
+ visible: plasmoid.configuration.showWindowIcon
+}
diff --git a/package/contents/ui/WindowTitle.qml b/package/contents/ui/WindowTitle.qml
new file mode 100644
index 0000000..5e246d1
--- /dev/null
+++ b/package/contents/ui/WindowTitle.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Layouts 1.1
+import org.kde.plasma.plasmoid 2.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+import org.kde.plasma.components 2.0 as PlasmaComponents
+
+PlasmaComponents.Label {
+ id: titleItem
+
+ property double iconMargin: (plasmoid.configuration.showWindowIcon ? iconItem.width : 0)
+ property double properWidth: parent.width - iconMargin - iconAndTextSpacing
+ property double properHeight: parent.height
+ property bool noElide: fitText === 2 || (fitText === 1 && mouseHover)
+ property int allowFontSizeChange: 3
+ property int minimumPixelSize: 8
+ property bool limitTextWidth: plasmoid.configuration.limitTextWidth
+ property int textWidthLimit: plasmoid.configuration.textWidthLimit
+ property double computedWidth: (limitTextWidth ? (implicitWidth > textWidthLimit ? textWidthLimit : implicitWidth) : properWidth)// - activeWindowListView.buttonsBetweenAddition
+
+ verticalAlignment: Text.AlignVCenter
+ text: plasmoid.configuration.noWindowText
+ wrapMode: Text.Wrap
+ width: computedWidth
+ elide: noElide ? Text.ElideNone : Text.ElideRight
+ visible: plasmoid.configuration.showWindowTitle
+ font.pixelSize: fontPixelSize
+ font.pointSize: -1
+ font.weight: fontBold || (appmenuBoldTitleWhenMenuDisplayed && appmenu.visible) ? Font.Bold : theme.defaultFont.weight
+ font.family: fontFamily || theme.defaultFont.family
+
+ onTextChanged: {
+ font.pixelSize = fontPixelSize
+ allowFontSizeChange = 3
+ }
+
+ onNoElideChanged: {
+ font.pixelSize = fontPixelSize
+ allowFontSizeChange = 3
+ }
+
+ onPaintedHeightChanged: {
+ if (allowFontSizeChange > 0 && noElide && paintedHeight > properHeight) {
+ var newPixelSize = (properHeight / paintedHeight) * fontPixelSize
+ font.pixelSize = newPixelSize < minimumPixelSize ? minimumPixelSize : newPixelSize
+ }
+ allowFontSizeChange--
+ }
+}
\ No newline at end of file
diff --git a/package/contents/ui/config/ConfigButtons.qml b/package/contents/ui/config/ConfigButtons.qml
index b9ae6aa..787bc47 100644
--- a/package/contents/ui/config/ConfigButtons.qml
+++ b/package/contents/ui/config/ConfigButtons.qml
@@ -1,313 +1,317 @@
import QtQuick 2.2
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import QtQml.Models 2.1
Item {
property alias cfg_showControlButtons: showControlButtons.checked
property alias cfg_doNotHideControlButtons: doNotHideControlButtons.checked
property int cfg_buttonsPosition
property alias cfg_buttonsVerticalCenter: buttonsVerticalCenter.checked
property alias cfg_buttonsStandalone: buttonsStandalone.checked
property alias cfg_buttonsBetweenIconAndText: buttonsBetweenIconAndText.checked
property alias cfg_buttonsDynamicWidth: buttonsDynamicWidth.checked
property alias cfg_slidingIconAndText: slidingIconAndText.checked
property alias cfg_showButtonOnlyWhenMaximized: showButtonOnlyWhenMaximized.checked
property alias cfg_showMinimize: showMinimize.checked
property alias cfg_showMaximize: showMaximize.checked
property alias cfg_showPinToAllDesktops: showPinToAllDesktops.checked
property alias cfg_buttonSize: buttonSize.value
property alias cfg_controlButtonsSpacing: controlButtonsSpacing.value
property string cfg_buttonOrder
property alias cfg_automaticButtonThemeEnabled: automaticButtonThemeEnabled.checked
property alias cfg_customAuroraeThemePath: customAuroraeThemePath.text
onCfg_buttonsPositionChanged: {
switch (cfg_buttonsPosition) {
case 0:
buttonsPositionGroup.current = upperLeftRadio;
break;
case 1:
buttonsPositionGroup.current = upperRightRadio;
break;
case 2:
buttonsPositionGroup.current = bottomLeftRadio;
break;
case 3:
buttonsPositionGroup.current = bottomRightRadio;
break;
default:
buttonsPositionGroup.current = upperLeftRadio;
}
}
Component.onCompleted: {
cfg_buttonsPositionChanged()
sortButtonOrder()
}
ListModel {
id: buttonsToSpend
ListElement {
- text: "close"
+ name: 'close'
+ iconName: 'close'
}
ListElement {
- text: "minimize"
+ name: 'minimize'
+ iconName: 'minimize'
}
ListElement {
- text: "maximize"
+ name: 'maximize'
+ iconName: 'maximize'
}
ListElement {
- text: "alldesktops"
+ name: 'alldesktops'
+ iconName: 'alldesktops'
}
}
function sortButtonOrder() {
- cfg_buttonOrder.split('|').forEach(function (buttonName, index) {
- if (buttonName === 'close') {
- print('adding ' + buttonName);
+ cfg_buttonOrder.split('|').forEach(function (itemId, index) {
+ if (itemId === 'close') {
+ print('adding ' + itemId);
buttonOrder.model.insert(index, buttonsToSpend.get(0));
- } else if (buttonName === 'minimize') {
+ } else if (itemId === 'minimize') {
buttonOrder.model.insert(index, buttonsToSpend.get(1));
- print('adding ' + buttonName);
- } else if (buttonName === 'maximize') {
+ print('adding ' + itemId);
+ } else if (itemId === 'maximize') {
buttonOrder.model.insert(index, buttonsToSpend.get(2));
- print('adding ' + buttonName);
- } else if (buttonName === 'pin' || buttonName === 'alldesktops') {
+ print('adding ' + itemId);
+ } else if (itemId === 'pin' || itemId === 'alldesktops') {
buttonOrder.model.insert(index, buttonsToSpend.get(3));
- print('adding ' + buttonName);
+ print('adding ' + itemId);
}
});
}
ExclusiveGroup {
id: buttonsPositionGroup
}
GroupBox {
id: showControlButtons
title: i18n("Enable Control Buttons")
checkable: true
flat: true
GridLayout {
columns: 2
Item {
width: 2
height: 10
Layout.columnSpan: 2
}
Item {
width: 2
height: 2
Layout.rowSpan: 3
}
CheckBox {
id: showMinimize
text: i18n("Show minimize button")
}
CheckBox {
id: showMaximize
text: i18n("Show maximize button")
}
CheckBox {
id: showPinToAllDesktops
text: i18n("Show pin to all desktops")
}
Item {
width: 2
height: 10
Layout.columnSpan: 2
}
Label {
text: i18n("Button order:")
Layout.alignment: Qt.AlignVCenter|Qt.AlignRight
}
OrderableListView {
id: buttonOrder
height: units.gridUnit * 2
width: height * 4
model: ListModel {
// will be filled initially by sortButtonOrder() method
}
orientation: ListView.Horizontal
itemWidth: width / 4
itemHeight: itemWidth
onModelOrderChanged: {
var orderStr = '';
for (var i = 0; i < model.count; i++) {
var item = model.get(i)
if (orderStr.length > 0) {
orderStr += '|';
}
- orderStr += item.text;
+ orderStr += item.name;
}
cfg_buttonOrder = orderStr;
print('written: ' + cfg_buttonOrder);
}
}
Item {
width: 2
height: 10
Layout.columnSpan: 2
}
Label {
text: i18n("Behaviour:")
Layout.alignment: Qt.AlignVCenter|Qt.AlignRight
}
CheckBox {
id: doNotHideControlButtons
text: i18n("Do not hide on mouse out")
}
Item {
width: 2
height: 2
Layout.rowSpan: 5
}
CheckBox {
id: showButtonOnlyWhenMaximized
text: i18n("Show only when maximized")
}
CheckBox {
id: buttonsStandalone
text: i18n("Buttons next to icon and text")
}
CheckBox {
id: buttonsBetweenIconAndText
text: i18n("Buttons between icon and text")
enabled: buttonsStandalone.checked
}
CheckBox {
id: buttonsDynamicWidth
text: i18n("Dynamic width")
enabled: buttonsStandalone.checked
}
CheckBox {
id: slidingIconAndText
text: i18n("Sliding icon and text")
enabled: buttonsStandalone.checked
}
Item {
width: 2
height: 10
Layout.columnSpan: 2
}
Label {
text: i18n("Position:")
Layout.alignment: Qt.AlignVCenter|Qt.AlignRight
}
RadioButton {
id: upperLeftRadio
exclusiveGroup: buttonsPositionGroup
text: i18n("Upper left")
onCheckedChanged: if (checked) cfg_buttonsPosition = 0;
}
Item {
width: 2
height: 2
Layout.rowSpan: 4
}
RadioButton {
id: upperRightRadio
exclusiveGroup: buttonsPositionGroup
text: i18n("Upper right")
onCheckedChanged: if (checked) cfg_buttonsPosition = 1;
}
RadioButton {
id: bottomLeftRadio
exclusiveGroup: buttonsPositionGroup
text: i18n("Bottom left")
onCheckedChanged: if (checked) cfg_buttonsPosition = 2;
}
RadioButton {
id: bottomRightRadio
exclusiveGroup: buttonsPositionGroup
text: i18n("Bottom right")
onCheckedChanged: if (checked) cfg_buttonsPosition = 3;
}
CheckBox {
id: buttonsVerticalCenter
text: i18n("Vertical center")
}
Item {
width: 2
height: 10
Layout.columnSpan: 2
}
Label {
text: i18n("Button size:")
Layout.alignment: Qt.AlignVCenter|Qt.AlignRight
}
Slider {
id: buttonSize
stepSize: 0.1
minimumValue: 0.1
tickmarksEnabled: true
width: parent.width
}
Label {
text: i18n("Buttons spacing:")
Layout.alignment: Qt.AlignVCenter|Qt.AlignRight
}
Slider {
id: controlButtonsSpacing
stepSize: 1
minimumValue: 0
maximumValue: 20
tickmarksEnabled: true
width: parent.width
}
Item {
width: 2
height: 10
Layout.columnSpan: 2
}
Label {
text: i18n("Theme")
Layout.columnSpan: parent.columns
font.bold: true
}
CheckBox {
id: automaticButtonThemeEnabled
text: i18n("Automatic")
}
TextField {
id: customAuroraeThemePath
placeholderText: i18n("Absolute path to aurorae button theme folder")
Layout.preferredWidth: 350
onTextChanged: cfg_customAuroraeThemePath = text
enabled: !automaticButtonThemeEnabled.checked
}
}
}
}
diff --git a/package/contents/ui/config/ConfigLayout.qml b/package/contents/ui/config/ConfigLayout.qml
new file mode 100644
index 0000000..c29784c
--- /dev/null
+++ b/package/contents/ui/config/ConfigLayout.qml
@@ -0,0 +1,318 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.3
+import QtQuick.Layouts 1.1
+import QtQml.Models 2.1
+
+Item {
+
+ property string cfg_controlPartOrder
+ property alias cfg_controlPartSpacing: controlPartSpacing.value
+
+ // GENERATED config (start)
+ property alias cfg_controlPartButtonsPosition: controlPartButtonsPosition.currentIndex
+ property alias cfg_controlPartButtonsShowOnMouseIn: controlPartButtonsShowOnMouseIn.checked
+ property alias cfg_controlPartButtonsShowOnMouseOut: controlPartButtonsShowOnMouseOut.checked
+ property alias cfg_controlPartButtonsHorizontalAlignment: controlPartButtonsHorizontalAlignment.currentIndex
+
+ property alias cfg_controlPartIconPosition: controlPartIconPosition.currentIndex
+ property alias cfg_controlPartIconShowOnMouseIn: controlPartIconShowOnMouseIn.checked
+ property alias cfg_controlPartIconShowOnMouseOut: controlPartIconShowOnMouseOut.checked
+ property alias cfg_controlPartIconHorizontalAlignment: controlPartIconHorizontalAlignment.currentIndex
+
+ property alias cfg_controlPartTitlePosition: controlPartTitlePosition.currentIndex
+ property alias cfg_controlPartTitleShowOnMouseIn: controlPartTitleShowOnMouseIn.checked
+ property alias cfg_controlPartTitleShowOnMouseOut: controlPartTitleShowOnMouseOut.checked
+ property alias cfg_controlPartTitleHorizontalAlignment: controlPartTitleHorizontalAlignment.currentIndex
+
+ property alias cfg_controlPartMenuPosition: controlPartMenuPosition.currentIndex
+ property alias cfg_controlPartMenuShowOnMouseIn: controlPartMenuShowOnMouseIn.checked
+ property alias cfg_controlPartMenuShowOnMouseOut: controlPartMenuShowOnMouseOut.checked
+ property alias cfg_controlPartMenuHorizontalAlignment: controlPartMenuHorizontalAlignment.currentIndex
+ // GENERATED config (end)
+
+ ListModel {
+ id: partsToSpend
+ ListElement {
+ name: 'icon'
+ text: 'Icon'
+ }
+ ListElement {
+ name: 'title'
+ text: 'Title'
+ }
+ ListElement {
+ name: 'buttons'
+ text: 'Buttons'
+ }
+ ListElement {
+ name: 'menu'
+ text: 'Menu'
+ }
+ }
+
+ function sortPartOrder() {
+ buttonOrder.model.clear()
+ cfg_controlPartOrder.split('|').forEach(function (itemId, index) {
+ var partIndex = -1
+ print('adding ' + itemId);
+ if (itemId === 'icon') {
+ partIndex = 0
+ } else if (itemId === 'title') {
+ partIndex = 1
+ } else if (itemId === 'buttons') {
+ partIndex = 2
+ } else if (itemId === 'menu') {
+ partIndex = 3
+ }
+ if (partIndex >= 0) {
+ buttonOrder.model.append(partsToSpend.get(partIndex));
+ }
+ });
+ print('model count: ' + buttonOrder.model.count)
+ }
+
+ GridLayout {
+ columns: 3
+
+ Label {
+ text: i18n("Item order:")
+ }
+
+ OrderableListView {
+ id: buttonOrder
+ Layout.columnSpan: 2
+ itemHeight: units.gridUnit * 2
+ itemWidth: units.gridUnit * 4
+ height: itemHeight
+ width: itemWidth * 4
+ model: ListModel {
+ // will be filled initially by sortButtonOrder() method
+ }
+ orientation: ListView.Horizontal
+
+ onModelOrderChanged: {
+ var orderStr = '';
+ for (var i = 0; i < model.count; i++) {
+ var item = model.get(i)
+ if (orderStr.length > 0) {
+ orderStr += '|';
+ }
+ orderStr += item.name;
+ }
+ cfg_controlPartOrder = orderStr;
+ print('written: ' + cfg_controlPartOrder);
+ }
+ }
+
+ Label {
+ text: i18n("Item spacing:")
+ }
+ SpinBox {
+ id: controlPartSpacing
+ decimals: 1
+ stepSize: 0.5
+ minimumValue: 0.5
+ maximumValue: 300
+ Layout.columnSpan: 2
+ }
+
+ // GENERATED controls (start)
+ GridLayout {
+ columns: 2
+
+ Item {
+ width: 2
+ height: units.largeSpacing
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Buttons')
+ font.bold: true
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Position:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartButtonsPosition
+ model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
+ }
+
+ CheckBox {
+ id: controlPartButtonsShowOnMouseIn
+ text: i18n('Show on mouse in')
+ Layout.columnSpan: 2
+ }
+
+ CheckBox {
+ id: controlPartButtonsShowOnMouseOut
+ text: i18n('Show on mouse out')
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Horizontal alignment:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartButtonsHorizontalAlignment
+ model: [i18n('Left'), i18n('Right')]
+ }
+
+
+ Item {
+ width: 2
+ height: units.largeSpacing
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Icon')
+ font.bold: true
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Position:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartIconPosition
+ model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
+ }
+
+ CheckBox {
+ id: controlPartIconShowOnMouseIn
+ text: i18n('Show on mouse in')
+ Layout.columnSpan: 2
+ }
+
+ CheckBox {
+ id: controlPartIconShowOnMouseOut
+ text: i18n('Show on mouse out')
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Horizontal alignment:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartIconHorizontalAlignment
+ model: [i18n('Left'), i18n('Right')]
+ }
+ }
+
+ Item {
+ width: units.largeSpacing
+ height: units.largeSpacing
+ }
+
+ GridLayout {
+ columns: 2
+
+ Item {
+ width: 2
+ height: units.largeSpacing
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Title')
+ font.bold: true
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Position:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartTitlePosition
+ model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
+ }
+
+ CheckBox {
+ id: controlPartTitleShowOnMouseIn
+ text: i18n('Show on mouse in')
+ Layout.columnSpan: 2
+ }
+
+ CheckBox {
+ id: controlPartTitleShowOnMouseOut
+ text: i18n('Show on mouse out')
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Horizontal alignment:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartTitleHorizontalAlignment
+ model: [i18n('Left'), i18n('Right')]
+ }
+
+
+ Item {
+ width: 2
+ height: units.largeSpacing
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Menu')
+ font.bold: true
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Position:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartMenuPosition
+ model: [i18n('Occupy'), i18n('Floating layer'), i18n('Absolute')]
+ }
+
+ CheckBox {
+ id: controlPartMenuShowOnMouseIn
+ text: i18n('Show on mouse in')
+ Layout.columnSpan: 2
+ }
+
+ CheckBox {
+ id: controlPartMenuShowOnMouseOut
+ text: i18n('Show on mouse out')
+ Layout.columnSpan: 2
+ }
+
+ Label {
+ text: i18n('Horizontal alignment:')
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ }
+
+ ComboBox {
+ id: controlPartMenuHorizontalAlignment
+ model: [i18n('Left'), i18n('Right')]
+ }
+ }
+ // GENERATED controls (end)
+
+ }
+
+ Component.onCompleted: {
+ sortPartOrder()
+ }
+
+}
diff --git a/package/contents/ui/config/OrderableListView.qml b/package/contents/ui/config/OrderableListView.qml
index 2ffa887..01b44d7 100644
--- a/package/contents/ui/config/OrderableListView.qml
+++ b/package/contents/ui/config/OrderableListView.qml
@@ -1,63 +1,87 @@
import QtQuick 2.6
import QtQuick.Controls 1.3
+import QtQuick.Layouts 1.1
import org.kde.plasma.core 2.0 as PlasmaCore
Item {
id: mainContent
property var model
property int orientation
property double itemWidth
property double itemHeight
property bool interactive
width: itemWidth * (orientation == ListView.Vertical ? 1 : model.count)
height: itemHeight * (orientation == ListView.Horizontal ? 1 : model.count)
SystemPalette {
id: palette
}
// theme + svg
property bool textColorLight: ((palette.text.r + palette.text.g + palette.text.b) / 3) > 0.5
property string themeName: textColorLight ? 'breeze-dark' : 'default'
signal modelOrderChanged()
ListView {
id: listView
anchors.fill: parent
model: mainContent.model
orientation: mainContent.orientation
delegate: OrderableItem {
listViewParent: listView.parent
Item {
- height: itemWidth
- width: itemHeight
+ height: itemHeight
+ width: itemWidth
PlasmaCore.Svg {
id: buttonSvg
- imagePath: Qt.resolvedUrl('../../icons/' + themeName + '/' + model.text + '.svg')
+ imagePath: Qt.resolvedUrl('../../icons/' + themeName + '/' + model.iconName + '.svg')
+ }
+
+ // item border
+ Rectangle {
+ border.width: 1
+ border.color: theme.textColor
+ radius: units.gridUnit / 4
+ color: 'transparent'
+ opacity: 0.5
+ anchors.fill: parent
}
// icon
PlasmaCore.SvgItem {
id: svgItem
- anchors.fill: parent
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
width: parent.width
height: width
svg: buttonSvg
elementId: 'active-idle'
+ visible: !!model.iconName
+ }
+
+ // text
+ Label {
+ text: model.text
+ anchors.fill: parent
+ anchors.leftMargin: svgItem.visible ? svgItem.width + units.smallSpacing : 0
+ visible: !!model.text
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
}
}
onMoveItemRequested: {
mainContent.model.move(from, to, 1);
mainContent.modelOrderChanged()
}
}
}
}
diff --git a/package/contents/ui/main.qml b/package/contents/ui/main.qml
index 2014542..abc1c3a 100644
--- a/package/contents/ui/main.qml
+++ b/package/contents/ui/main.qml
@@ -1,632 +1,696 @@
/*
* Copyright 2015 Martin Kotelnik
*
* This program 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; either version 2 of
* the License, or (at your option) any later version.
*
* This program 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 .
*/
import QtQuick 2.2
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.activities 0.1 as Activities
Item {
id: main
property bool vertical: (plasmoid.formFactor == PlasmaCore.Types.Vertical)
property double horizontalScreenWidthPercent: plasmoid.configuration.horizontalScreenWidthPercent
- property double buttonSize: plasmoid.configuration.buttonSize
+// property double buttonSize: plasmoid.configuration.buttonSize
property bool autoFillWidth: plasmoid.configuration.autoFillWidth
- property double widthForHorizontalPanel: (Screen.width * horizontalScreenWidthPercent + plasmoid.configuration.widthFineTuning) - ((!controlButtonsArea.visible && buttonsStandalone && plasmoid.configuration.buttonsDynamicWidth) ? controlButtonsArea.width : 0)
+ property double widthForHorizontalPanel: (Screen.width * horizontalScreenWidthPercent + plasmoid.configuration.widthFineTuning) - ((!buttonsItem.visible && buttonsStandalone && plasmoid.configuration.buttonsDynamicWidth) ? buttonsItem.width : 0)
anchors.fill: parent
Layout.fillWidth: plasmoid.configuration.autoFillWidth
Layout.preferredWidth: autoFillWidth ? -1 : (vertical ? parent.width : (widthForHorizontalPanel > 0 ? widthForHorizontalPanel : 0.0001))
Layout.minimumWidth: Layout.preferredWidth
Layout.maximumWidth: Layout.preferredWidth
Layout.preferredHeight: parent === null ? 0 : vertical ? Math.min(theme.defaultFont.pointSize * 4, parent.width) : parent.height
Layout.minimumHeight: Layout.preferredHeight
Layout.maximumHeight: Layout.preferredHeight
property int textType: plasmoid.configuration.textType
property int fitText: plasmoid.configuration.fitText
property int tooltipTextType: plasmoid.configuration.tooltipTextType
property string tooltipText: ''
property bool windowIconOnTheRight: plasmoid.configuration.windowIconOnTheRight
property double iconAndTextSpacing: plasmoid.configuration.iconAndTextSpacing
property bool slidingIconAndText: plasmoid.configuration.slidingIconAndText
property double fontPixelSize: theme.defaultFont.pixelSize * plasmoid.configuration.fontSizeScale
property bool fontBold: plasmoid.configuration.boldFontWeight
property string fontFamily: plasmoid.configuration.fontFamily
property bool noWindowActive: true
property bool currentWindowMaximized: false
property bool canShowButtonsAccordingMaximized: showButtonOnlyWhenMaximized ? currentWindowMaximized : true
property int controlButtonsSpacing: plasmoid.configuration.controlButtonsSpacing
property int bp: plasmoid.configuration.buttonsPosition;
property bool buttonsVerticalCenter: plasmoid.configuration.buttonsVerticalCenter
property bool showControlButtons: plasmoid.configuration.showControlButtons
property bool showButtonOnlyWhenMaximized: plasmoid.configuration.showButtonOnlyWhenMaximized
property bool showMinimize: showControlButtons && plasmoid.configuration.showMinimize
property bool showMaximize: showControlButtons && plasmoid.configuration.showMaximize
property bool showPinToAllDesktops: showControlButtons && plasmoid.configuration.showPinToAllDesktops
property string buttonOrder: plasmoid.configuration.buttonOrder
property bool doubleClickMaximizes: plasmoid.configuration.doubleClickMaximizes
property int leftClickAction: plasmoid.configuration.leftClickAction
property string chosenLeftClickSource: leftClickAction === 1 ? shortcutDS.presentWindows : leftClickAction === 2 ? shortcutDS.presentWindowsAll : leftClickAction === 3 ? shortcutDS.presentWindowsClass : ''
property bool middleClickClose: plasmoid.configuration.middleClickAction === 1
property bool middleClickFullscreen: plasmoid.configuration.middleClickAction === 2
property bool wheelUpMaximizes: plasmoid.configuration.wheelUpMaximizes
property bool wheelDownMinimizes: plasmoid.configuration.wheelDownAction === 1
property bool wheelDownUnmaximizes: plasmoid.configuration.wheelDownAction === 2
property bool buttonsStandalone: showControlButtons && plasmoid.configuration.buttonsStandalone
property bool buttonsBetweenIconAndText: buttonsStandalone && plasmoid.configuration.buttonsBetweenIconAndText
property bool doNotHideControlButtons: showControlButtons && plasmoid.configuration.doNotHideControlButtons
property bool textColorLight: ((theme.textColor.r + theme.textColor.g + theme.textColor.b) / 3) > 0.5
property bool mouseHover: false
property bool isActiveWindowPinned: false
property bool isActiveWindowMaximized: false
property bool appmenuNextToIconAndText: plasmoid.configuration.appmenuNextToIconAndText
property double appmenuSideMargin: plasmoid.configuration.appmenuOuterSideMargin
property bool appmenuSwitchSidesWithIconAndText: plasmoid.configuration.appmenuSwitchSidesWithIconAndText
property bool appmenuBoldTitleWhenMenuDisplayed: plasmoid.configuration.appmenuBoldTitleWhenMenuDisplayed
property var activeTaskLocal: null
property int activityActionCount: 0
property bool automaticButtonThemeEnabled: plasmoid.configuration.automaticButtonThemeEnabled
property string manualAuroraeThemePath: plasmoid.configuration.customAuroraeThemePath
property string manualAuroraeThemePathResolved: ''
property string manualAuroraeThemeExtension: 'svg'
+ property var itemPartOrder: []
+
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
Plasmoid.status: {
- if (appmenu.appmenuOpened) {
+ if (menuItem.appmenuOpened) {
return PlasmaCore.Types.NeedsAttentionStatus;
- } else if (!appmenu.appmenuOpened && appmenu.appmenuEnabledAndNonEmpty){
+ } else if (!menuItem.appmenuOpened && menuItem.appmenuEnabledAndNonEmpty){
return PlasmaCore.Types.ActiveStatus;
} else {
return PlasmaCore.Types.PassiveStatus;
}
}
//
// MODEL
//
TaskManager.TasksModel {
id: tasksModel
sortMode: TaskManager.TasksModel.SortVirtualDesktop
groupMode: TaskManager.TasksModel.GroupDisabled
screenGeometry: plasmoid.screenGeometry
filterByScreen: plasmoid.configuration.showForCurrentScreenOnly
onActiveTaskChanged: {
updateActiveWindowInfo()
}
onDataChanged: {
updateActiveWindowInfo()
}
onCountChanged: {
updateActiveWindowInfo()
}
}
TaskManager.ActivityInfo {
id: activityInfo
onCurrentActivityChanged: {
if (noWindowActive) {
updateActiveWindowInfo();
}
reAddActivityActions()
}
onNumberOfRunningActivitiesChanged: {
reAddActivityActions()
}
}
Activities.ActivityModel {
id: activityModel
}
function activeTask() {
return activeTaskLocal
}
function activeTaskExists() {
return activeTaskLocal.display !== undefined
}
onTooltipTextTypeChanged: updateTooltip()
function updateTooltip() {
if (tooltipTextType === 1) {
tooltipText = replaceTitle(activeTask().display || '')
} else if (tooltipTextType === 2) {
tooltipText = activeTask().AppName || ''
} else {
tooltipText = ''
}
}
function composeNoWindowText() {
return plasmoid.configuration.noWindowText.replace('%activity%', activityInfo.activityName(activityInfo.currentActivity))
}
function updateActiveWindowInfo() {
var activeTaskIndex = tasksModel.activeTask
// fallback for Plasma 5.8
var abstractTasksModel = TaskManager.AbstractTasksModel || {}
var isActive = abstractTasksModel.IsActive || 271
var appName = abstractTasksModel.AppName || 258
var isMaximized = abstractTasksModel.IsMaximized || 276
var virtualDesktop = abstractTasksModel.VirtualDesktop || 286
- if (!tasksModel.data(activeTaskIndex, isActive)) {
- activeTaskLocal = {}
- } else {
+ activeTaskLocal = {}
+ if (tasksModel.data(activeTaskIndex, isActive)) {
activeTaskLocal = {
display: tasksModel.data(activeTaskIndex, Qt.DisplayRole),
decoration: tasksModel.data(activeTaskIndex, Qt.DecorationRole),
AppName: tasksModel.data(activeTaskIndex, appName),
IsMaximized: tasksModel.data(activeTaskIndex, isMaximized),
VirtualDesktop: tasksModel.data(activeTaskIndex, virtualDesktop)
}
}
var actTask = activeTask()
noWindowActive = !activeTaskExists()
currentWindowMaximized = !noWindowActive && actTask.IsMaximized === true
isActiveWindowPinned = actTask.VirtualDesktop === -1;
if (noWindowActive) {
- windowTitleText.text = composeNoWindowText()
+ titleItem.text = composeNoWindowText()
iconItem.source = plasmoid.configuration.noWindowIcon
} else {
- windowTitleText.text = (textType === 1 ? actTask.AppName : null) || replaceTitle(actTask.display)
+ titleItem.text = (textType === 1 ? actTask.AppName : null) || replaceTitle(actTask.display)
iconItem.source = actTask.decoration
}
updateTooltip()
}
function toggleMaximized() {
tasksModel.requestToggleMaximized(tasksModel.activeTask);
}
function toggleMinimized() {
tasksModel.requestToggleMinimized(tasksModel.activeTask);
}
function toggleClose() {
tasksModel.requestClose(tasksModel.activeTask);
}
function toggleFullscreen() {
tasksModel.requestToggleFullScreen(tasksModel.activeTask);
}
function togglePinToAllDesktops() {
tasksModel.requestVirtualDesktop(tasksModel.activeTask, 0);
}
function setMaximized(maximized) {
if ((maximized && !activeTask().IsMaximized)
|| (!maximized && activeTask().IsMaximized)) {
print('toggle maximized')
toggleMaximized()
}
}
function setMinimized() {
if (!activeTask().IsMinimized) {
toggleMinimized()
}
}
//
// ACTIVE WINDOW INFO
//
- Item {
- id: activeWindowListView
-
- anchors.top: parent.top
- anchors.bottom: parent.bottom
-
- property double appmenuOffsetLeft: (bp === 0 || bp === 2) ? appmenu.appmenuOffsetWidth : 0
- property double appmenuOffsetRight: (bp === 1 || bp === 3) ? appmenu.appmenuOffsetWidth : 0
- property double controlButtonsAreaWidth: noWindowActive ? 0 : controlButtonsArea.width
- property bool buttonsVisible: buttonsStandalone && (!slidingIconAndText || controlButtonsArea.mouseInWidget || doNotHideControlButtons) && (canShowButtonsAccordingMaximized || !slidingIconAndText)
- property double buttonsBetweenAddition: buttonsVisible && buttonsBetweenIconAndText ? controlButtonsAreaWidth + iconAndTextSpacing : 0
-
- anchors.left: parent.left
- anchors.leftMargin: buttonsVisible && (bp === 0 || bp === 2) && !buttonsBetweenIconAndText ? controlButtonsAreaWidth + iconAndTextSpacing + appmenuOffsetLeft : 0 + appmenuOffsetLeft
- anchors.right: parent.right
- anchors.rightMargin: buttonsVisible && (bp === 1 || bp === 3) && !buttonsBetweenIconAndText ? controlButtonsAreaWidth + iconAndTextSpacing + appmenuOffsetRight : 0 + appmenuOffsetRight
-
- Behavior on anchors.leftMargin {
- NumberAnimation {
- duration: 150
- easing.type: Easing.Linear
- }
+// Item {
+// id: activeWindowListView
+//
+// anchors.top: parent.top
+// anchors.bottom: parent.bottom
+//
+// property double appmenuOffsetLeft: (bp === 0 || bp === 2) ? appmenu.appmenuOffsetWidth : 0
+// property double appmenuOffsetRight: (bp === 1 || bp === 3) ? appmenu.appmenuOffsetWidth : 0
+// property double controlButtonsAreaWidth: noWindowActive ? 0 : buttonsItem.width
+// property bool buttonsVisible: buttonsStandalone && (!slidingIconAndText || buttonsItem.mouseInWidget || doNotHideControlButtons) && (canShowButtonsAccordingMaximized || !slidingIconAndText)
+// property double buttonsBetweenAddition: buttonsVisible && buttonsBetweenIconAndText ? controlButtonsAreaWidth + iconAndTextSpacing : 0
+//
+// anchors.left: parent.left
+// anchors.leftMargin: buttonsVisible && (bp === 0 || bp === 2) && !buttonsBetweenIconAndText ? controlButtonsAreaWidth + iconAndTextSpacing + appmenuOffsetLeft : 0 + appmenuOffsetLeft
+// anchors.right: parent.right
+// anchors.rightMargin: buttonsVisible && (bp === 1 || bp === 3) && !buttonsBetweenIconAndText ? controlButtonsAreaWidth + iconAndTextSpacing + appmenuOffsetRight : 0 + appmenuOffsetRight
+//
+// Behavior on anchors.leftMargin {
+// NumberAnimation {
+// duration: 150
+// easing.type: Easing.Linear
+// }
+// }
+// Behavior on anchors.rightMargin {
+// NumberAnimation {
+// duration: 150
+// easing.type: Easing.Linear
+// }
+// }
+//
+// width: parent.width - anchors.leftMargin - anchors.rightMargin
+//
+// opacity: appmenu.visible && !appmenuNextToIconAndText ? plasmoid.configuration.appmenuIconAndTextOpacity : 1
+//
+// Item {
+// width: parent.width
+// height: main.height
+//
+// WindowIcon {
+// id: iconItem
+//
+// anchors.left: parent.left
+// anchors.leftMargin: windowIconOnTheRight ? parent.width - iconItem.width : 0
+// }
+//
+// WindowTitle {
+// id: titleItem
+//
+// property double iconMarginForAnchor: noWindowActive && plasmoid.configuration.noWindowIcon === '' ? 0 : iconMargin
+//
+// anchors.left: parent.left
+// anchors.leftMargin: windowIconOnTheRight ? 0 : iconMarginForAnchor + iconAndTextSpacing + activeWindowListView.buttonsBetweenAddition
+// anchors.top: parent.top
+// anchors.bottom: parent.bottom
+// }
+//
+// }
+// }
+
+ function getConfigName(itemName) {
+ return itemName.substring(0, 1).toUpperCase() + itemName.substring(1)
+ }
+
+ function getPosition(itemName) {
+ var configName = getConfigName(itemName)
+ print('getPosition: ' + configName)
+ print('POS: ' + plasmoid.configuration['controlPart' + configName + 'Position'])
+ return plasmoid.configuration['controlPart' + configName + 'Position']
+ }
+
+ function isRelevant(itemName) {
+ var configName = getConfigName(itemName)
+ print('isRelevant: ' + configName)
+ print('1IR: ' + plasmoid.configuration['controlPart' + configName + 'ShowOnMouseIn'])
+ print('2IR: ' + plasmoid.configuration['controlPart' + configName + 'ShowOnMouseOut'])
+ var result = plasmoid.configuration['controlPart' + configName + 'ShowOnMouseIn'] || plasmoid.configuration['controlPart' + configName + 'ShowOnMouseOut']
+ print('res: ' + result)
+ return result
+ }
+
+ function getItem(itemName) {
+ if (itemName === 'icon') {
+ return iconItem
}
- Behavior on anchors.rightMargin {
- NumberAnimation {
- duration: 150
- easing.type: Easing.Linear
- }
+ if (itemName === 'title') {
+ return titleItem
}
+ if (itemName === 'menu') {
+ return menuItem
+ }
+ if (itemName === 'buttons') {
+ return buttonsItem
+ }
+ return null
+ }
- width: parent.width - anchors.leftMargin - anchors.rightMargin
-
- opacity: appmenu.visible && !appmenuNextToIconAndText ? plasmoid.configuration.appmenuIconAndTextOpacity : 1
-
- Item {
- width: parent.width
- height: main.height
-
- // window icon
- PlasmaCore.IconItem {
- id: iconItem
-
- anchors.left: parent.left
- anchors.leftMargin: windowIconOnTheRight ? parent.width - iconItem.width : 0
-
- width: parent.height
- height: parent.height
+ function getItemWidth(itemName) {
+ return getItem().width
+ }
- source: plasmoid.configuration.noWindowIcon
- visible: plasmoid.configuration.showWindowIcon
+ function anchorsLeftMargin(itemName) {
+ var itemPosition = getPosition(itemName)
+ print('position of ' + itemName + ' is ' + itemPosition)
+ if (itemPosition === 2) {
+ return 0
+ }
+ var anchorSize = 0
+ itemPartOrder.some(function (iName, index) {
+ print('iterating: ' + iName)
+ if (iName === itemName) {
+ return true
}
-
- // window title
- PlasmaComponents.Label {
- id: windowTitleText
-
- property double iconMargin: (plasmoid.configuration.showWindowIcon ? iconItem.width : 0)
- property double properWidth: parent.width - iconMargin - iconAndTextSpacing
- property double properHeight: parent.height
- property bool noElide: fitText === 2 || (fitText === 1 && mouseHover)
- property int allowFontSizeChange: 3
- property int minimumPixelSize: 8
- property double iconMarginForAnchor: noWindowActive && plasmoid.configuration.noWindowIcon === '' ? 0 : iconMargin
- property bool limitTextWidth: plasmoid.configuration.limitTextWidth
- property int textWidthLimit: plasmoid.configuration.textWidthLimit
- property double computedWidth: (limitTextWidth ? (implicitWidth > textWidthLimit ? textWidthLimit : implicitWidth) : properWidth) - activeWindowListView.buttonsBetweenAddition
-
- anchors.left: parent.left
- anchors.leftMargin: windowIconOnTheRight ? 0 : iconMarginForAnchor + iconAndTextSpacing + activeWindowListView.buttonsBetweenAddition
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- verticalAlignment: Text.AlignVCenter
- text: plasmoid.configuration.noWindowText
- wrapMode: Text.Wrap
- width: computedWidth
- elide: noElide ? Text.ElideNone : Text.ElideRight
- visible: plasmoid.configuration.showWindowTitle
- font.pixelSize: fontPixelSize
- font.pointSize: -1
- font.weight: fontBold || (appmenuBoldTitleWhenMenuDisplayed && appmenu.visible) ? Font.Bold : theme.defaultFont.weight
- font.family: fontFamily || theme.defaultFont.family
-
- onTextChanged: {
- font.pixelSize = fontPixelSize
- allowFontSizeChange = 3
- }
-
- onNoElideChanged: {
- font.pixelSize = fontPixelSize
- allowFontSizeChange = 3
- }
-
- onPaintedHeightChanged: {
- if (allowFontSizeChange > 0 && noElide && paintedHeight > properHeight) {
- var newPixelSize = (properHeight / paintedHeight) * fontPixelSize
- font.pixelSize = newPixelSize < minimumPixelSize ? minimumPixelSize : newPixelSize
- }
- allowFontSizeChange--
- }
+ if (getPosition(iName) === itemPosition && isRelevant(iName)) {
+ var currentItemWidth = getItemWidth(iName)
+ print('width of ' + iName + ' is ' + currentItemWidth)
+ anchorSize += currentItemWidth
+ anchorSize += plasmoid.configuration.controlPartSpacing
}
+ });
+ print('leftMargin of ' + itemName + ' is ' + anchorSize)
+ return anchorSize
+ }
- }
+ function refreshItemMargin() {
+ iconItem.anchors.leftMargin = anchorsLeftMargin('icon')
+ titleItem.anchors.leftMargin = anchorsLeftMargin('title')
+ menuItem.anchors.leftMargin = anchorsLeftMargin('menu')
+ buttonsItem.anchors.leftMargin = anchorsLeftMargin('buttons')
}
function replaceTitle(title) {
if (!plasmoid.configuration.useWindowTitleReplace) {
return title
}
return title.replace(new RegExp(plasmoid.configuration.replaceTextRegex), plasmoid.configuration.replaceTextReplacement);
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
onEntered: {
mouseHover = true
- controlButtonsArea.mouseInWidget = showControlButtons && !noWindowActive
+ buttonsItem.mouseInWidget = showControlButtons && !noWindowActive
}
onExited: {
mouseHover = false
- controlButtonsArea.mouseInWidget = false
+ buttonsItem.mouseInWidget = false
}
onWheel: {
if (wheel.angleDelta.y > 0) {
if (wheelUpMaximizes) {
setMaximized(true)
}
} else {
if (wheelDownMinimizes) {
setMinimized()
} else if (wheelDownUnmaximizes) {
setMaximized(false)
}
}
}
onDoubleClicked: {
if (doubleClickMaximizes && mouse.button == Qt.LeftButton) {
toggleMaximized()
}
}
onClicked: {
if (chosenLeftClickSource !== '' && !doubleClickMaximizes && mouse.button == Qt.LeftButton) {
shortcutDS.connectedSources.push(chosenLeftClickSource)
- controlButtonsArea.mouseInWidget = false
+ buttonsItem.mouseInWidget = false
return
}
if (mouse.button == Qt.MiddleButton) {
if (middleClickFullscreen) {
toggleFullscreen()
} else if (middleClickClose) {
toggleClose()
}
}
}
PlasmaCore.ToolTipArea {
anchors.fill: parent
active: tooltipTextType > 0 && tooltipText !== ''
interactive: true
location: plasmoid.location
mainItem: Row {
spacing: 0
Layout.minimumWidth: fullText.width + units.largeSpacing
Layout.minimumHeight: childrenRect.height
Layout.maximumWidth: Layout.minimumWidth
Layout.maximumHeight: Layout.minimumHeight
Item {
width: units.largeSpacing / 2
height: 2
}
PlasmaComponents.Label {
id: fullText
text: tooltipText
}
}
}
+ }
+
+ ListModel {
+ id: controlButtonsModel
+ }
+
+ WindowIcon {
+ id: iconItem
- AppMenu {
- id: appmenu
- }
+ x: anchorsLeftMargin('icon')
- ListView {
- id: controlButtonsArea
+ visible: ((mouseHover && plasmoid.configuration.controlPartIconShowOnMouseIn)
+ || (!mouseHover && plasmoid.configuration.controlPartIconShowOnMouseOut))
- property bool mouseInWidget: false
- property double controlButtonsHeight: parent.height * buttonSize
- property double buttonsBetweenMargin: buttonsBetweenIconAndText ? activeWindowListView.appmenuOffsetLeft + activeWindowListView.appmenuOffsetRight + iconItem.width + iconAndTextSpacing : 0
+ onWidthChanged: refreshItemMargin()
+ }
- orientation: ListView.Horizontal
- visible: showControlButtons && (doNotHideControlButtons || mouseInWidget || appmenu.appmenuOpened) && (currentWindowMaximized || !showButtonOnlyWhenMaximized) && !noWindowActive
+ WindowTitle {
+ id: titleItem
- spacing: controlButtonsSpacing
+ x: anchorsLeftMargin('title')
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
- height: buttonsVerticalCenter ? parent.height : controlButtonsHeight
- width: controlButtonsHeight + ((controlButtonsModel.count - 1) * (controlButtonsHeight + controlButtonsSpacing))
+ visible: ((mouseHover && plasmoid.configuration.controlPartTitleShowOnMouseIn)
+ || (!mouseHover && plasmoid.configuration.controlPartTitleShowOnMouseOut))
+ }
+
+ AppMenu {
+ id: menuItem
- anchors.top: parent.top
- anchors.left: parent.left
+ x: anchorsLeftMargin('menu')
- anchors.leftMargin: buttonsBetweenIconAndText ? (windowIconOnTheRight ? parent.width - width - buttonsBetweenMargin : buttonsBetweenMargin) : ((bp === 1 || bp === 3) ? parent.width - width : 0)
- anchors.topMargin: (bp === 2 || bp === 3) ? parent.height - height : 0
+ visible: ((mouseHover && plasmoid.configuration.controlPartMenuShowOnMouseIn)
+ || (!mouseHover && plasmoid.configuration.controlPartMenuShowOnMouseOut))
+ }
- model: controlButtonsModel
+ ControlButtons {
+ id: buttonsItem
- delegate: ControlButton { }
- }
+ x: anchorsLeftMargin('buttons')
+
+ visible: true
+
+ controlButtonsModel: controlButtonsModel
+
+ showItem: ((mouseInWidget && plasmoid.configuration.controlPartButtonsShowOnMouseIn)
+ || (!mouseInWidget && plasmoid.configuration.controlPartButtonsShowOnMouseOut))
}
- ListModel {
- id: controlButtonsModel
+ property bool mouseInWidget: mouseHover || buttonsItem.mouseInWidget || menuItem.mouseInWidget
+
+ onMouseHoverChanged: {
+ print('mouse hover changed: ' + mouseHover);
+ }
+
+ onMouseInWidgetChanged: {
+ print('mouseInWidget: ' + mouseInWidget);
}
onManualAuroraeThemePathChanged: {
manualAuroraeThemeExtension = plasmoid.nativeInterface.extensionForTheme(manualAuroraeThemePath);
manualAuroraeThemePathResolved = plasmoid.nativeInterface.translateThemePath(manualAuroraeThemePath);
print('manualAuroraeThemePath=' + manualAuroraeThemePath)
print('manualAuroraeThemePathResolved=' + manualAuroraeThemePathResolved)
print('manualAuroraeThemeExtension=' + manualAuroraeThemeExtension)
}
function addButton(preparedArray, buttonName) {
if (buttonName === 'close') {
preparedArray.push({
iconName: 'close',
windowOperation: 'close'
});
} else if (buttonName === 'maximize' && showMaximize) {
preparedArray.push({
iconName: 'maximize',
windowOperation: 'toggleMaximized'
});
} else if (buttonName === 'minimize' && showMinimize) {
preparedArray.push({
iconName: 'minimize',
windowOperation: 'toggleMinimized'
});
} else if ((buttonName === 'pin' || buttonName === 'alldesktops') && showPinToAllDesktops) {
preparedArray.push({
iconName: 'alldesktops',
windowOperation: 'togglePinToAllDesktops'
});
}
}
function initializeControlButtonsModel() {
var preparedArray = []
buttonOrder.split('|').forEach(function (buttonName) {
addButton(preparedArray, buttonName);
});
controlButtonsModel.clear()
- if (bp === 1 || bp === 3) {
- for (var i = preparedArray.length - 1; i >= 0; i--) {
- controlButtonsModel.append(preparedArray[i])
- }
- } else {
- for (var i = 0; i < preparedArray.length; i++) {
- controlButtonsModel.append(preparedArray[i])
- }
- }
+ preparedArray.forEach(function (item) {
+ print('adding item to buttons: ' + item.iconName);
+ controlButtonsModel.append(item);
+ });
}
function performActiveWindowAction(windowOperation) {
- if (bp === 4 || !controlButtonsArea.visible) {
+ if (bp === 4) {
return;
}
if (windowOperation === 'close') {
toggleClose()
} else if (windowOperation === 'toggleMaximized') {
toggleMaximized()
} else if (windowOperation === 'toggleMinimized') {
toggleMinimized()
} else if (windowOperation === 'togglePinToAllDesktops') {
togglePinToAllDesktops()
}
}
function action_close() {
toggleClose()
}
function action_maximise() {
toggleMaximized()
}
function action_minimise() {
toggleMinimized()
}
function action_pinToAllDesktops() {
togglePinToAllDesktops()
}
function action_reloadTheme() {
plasmoid.nativeInterface.refreshAuroraeTheme();
}
function actionTriggered(actionName) {
if (actionName.indexOf("switchToActivity_") == 0) {
var activityIndex = actionName.replace("switchToActivity_", "")
var activityId = activityInfo.runningActivities()[activityIndex]
activityModel.setCurrentActivity(activityId, function() {});
}
}
function reAddActivityActions() {
plasmoid.removeAction("separator1")
for (var i = 0; i < activityActionCount; i++) {
plasmoid.removeAction('switchToActivity_' + i)
}
plasmoid.removeAction("separator2")
var runningActivities = activityInfo.runningActivities()
activityActionCount = runningActivities.length
if (activityActionCount === 0) {
return
}
plasmoid.setActionSeparator("separator1")
activityInfo.runningActivities().forEach(function (activityId, index) {
if (activityId === activityInfo.currentActivity) {
return;
}
var activityName = activityInfo.activityName(activityId)
plasmoid.setAction('switchToActivity_' + index, i18n('Switch to activity: %1', activityName), 'preferences-activities')
})
plasmoid.setActionSeparator("separator2")
}
+ property string controlPartOrder: plasmoid.configuration.controlPartOrder
+
+ onControlPartOrderChanged: refreshControlPartOrder()
+
+ function refreshControlPartOrder() {
+ itemPartOrder.length = 0
+ plasmoid.configuration.controlPartOrder.split('|').forEach(function (itemName, index) {
+ print('itemOrder: ' + itemName)
+ itemPartOrder.push(itemName)
+ print('itemZ: ' + index)
+ getItem(itemName).z = index
+ });
+ print('itemPartOrder initialized: ' + itemPartOrder)
+ }
+
Component.onCompleted: {
+ refreshControlPartOrder()
+ refreshItemMargin()
initializeControlButtonsModel()
updateActiveWindowInfo()
plasmoid.setAction('close', i18n('Close'), 'window-close');
plasmoid.setAction('maximise', i18n('Toggle Maximise'), 'arrow-up-double');
plasmoid.setAction('minimise', i18n('Minimise'), 'draw-arrow-down');
plasmoid.setAction('pinToAllDesktops', i18n('Toggle Pin To All Desktops'), 'window-pin');
plasmoid.setActionSeparator("separator0")
plasmoid.setAction('reloadTheme', i18n('Reload Theme'), 'system-reboot');
reAddActivityActions()
}
onShowMaximizeChanged: initializeControlButtonsModel()
onShowMinimizeChanged: initializeControlButtonsModel()
onShowPinToAllDesktopsChanged: initializeControlButtonsModel()
onBpChanged: initializeControlButtonsModel()
onButtonOrderChanged: initializeControlButtonsModel()
PlasmaCore.DataSource {
id: shortcutDS
engine: 'executable'
property string presentWindows: 'qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "Expose"'
property string presentWindowsAll: 'qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "ExposeAll"'
property string presentWindowsClass: 'qdbus org.kde.kglobalaccel /component/kwin invokeShortcut "ExposeClass"'
connectedSources: []
onNewData: {
connectedSources.length = 0
}
}
}