diff --git a/applets/kimpanel/package/contents/ui/StatusIcon.qml b/applets/kimpanel/package/contents/ui/StatusIcon.qml deleted file mode 100644 --- a/applets/kimpanel/package/contents/ui/StatusIcon.qml +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2014 Weng Xuetian - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. - */ - -import QtQuick 2.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 -import org.kde.kquickcontrolsaddons 2.0 - -Item { - id: statusIcon - property string icon; - property string label; - property string tip; - property string hint; - signal triggered(variant button); - property int iconSize: units.roundToIconSize(Math.min(parent.width, parent.height)) - - opacity: 'disable' == hint ? 0.3 : 1 - - function extractLabelString(l) { - if (l.length >= 2 && l.charCodeAt(0) < 127 && l.charCodeAt(1) < 127) { - return l.substring(0, 2); - } else { - return l.substring(0, 1); - } - } - - function iconPath(p) { - if (p.length > 0) { - if (p[0] === '/') { - return p; - } else { - return "image://icon/" + p; - } - } - return p; - } - - PlasmaCore.IconItem { - id: imageIcon - anchors.centerIn: parent - width: iconSize - height: iconSize - scale: mouseArea.pressed ? 0.9 : 1 - source: statusIcon.icon - visible: statusIcon.icon.length > 0 - animated: false - // active: mouseArea.containsMouse - } - PlasmaComponents.Label { - id: textIcon - anchors.centerIn: parent - width: iconSize - height: iconSize - scale: (mouseArea.pressed ? 0.9 : 1) - // a reasonable large size to make Text.Fit work - minimumPointSize: 0 - font.pointSize: 1024 - fontSizeMode: Text.Fit - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - text: extractLabelString(label) - visible: icon.length == 0 - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { - statusIcon.triggered(mouse.button); - } - - PlasmaCore.ToolTipArea { - anchors.fill: parent - mainText: statusIcon.label - subText: statusIcon.tip - icon: statusIcon.icon - } - } -} diff --git a/applets/kimpanel/package/contents/ui/StatusPanel.qml b/applets/kimpanel/package/contents/ui/StatusPanel.qml new file mode 100644 --- /dev/null +++ b/applets/kimpanel/package/contents/ui/StatusPanel.qml @@ -0,0 +1,134 @@ +/* + * Copyright 2019 Guo Yunhe + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. + */ + +import QtQuick 2.6 +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 +import org.kde.plasma.extras 2.0 as PlasmaExtras +import org.kde.plasma.private.kimpanel 0.1 as Kimpanel + +// Expanded view after clicking the icon +Column { + anchors.fill: parent + spacing: 10 + + // Status bar icons + Row { + id: statusbar + height: units.iconSizes.medium + width: parent.width + spacing: units.smallSpacing + + PlasmaCore.IconItem { + anchors.verticalCenter: parent.verticalCenter + width: units.iconSizes.medium + height: units.iconSizes.medium + source: "fcitx" + } + + PlasmaComponents.Label { + anchors.verticalCenter: parent.verticalCenter + width: parent.width - units.iconSizes.medium * 5 - parent.spacing * 5 + height: units.iconSizes.medium + text: "Fcitx" + } + + PlasmaCore.IconItem { + anchors.verticalCenter: parent.verticalCenter + width: units.iconSizes.medium + height: units.iconSizes.medium + source: "fcitx-fullwidth-inactive" + } + + PlasmaCore.IconItem { + anchors.verticalCenter: parent.verticalCenter + width: units.iconSizes.medium + height: units.iconSizes.medium + source: "fcitx-punc-active" + } + + PlasmaCore.IconItem { + anchors.verticalCenter: parent.verticalCenter + width: units.iconSizes.medium + height: units.iconSizes.medium + source: "fcitx-chttrans-inactive" + } + + PlasmaCore.IconItem { + anchors.verticalCenter: parent.verticalCenter + width: units.iconSizes.medium + height: units.iconSizes.medium + source: "fcitx-vk-inactive" + } + } + + // List of input methods + PlasmaExtras.ScrollArea { + width: parent.width + height: parent.height - statusbar.height - parent.spacing + + ListView { + id: layoutlist + width: parent.width + height: childrenRect.height + + model: ListModel { + ListElement { + icon: "input-keyboard" + name: "Keyboard (US)" + } + ListElement { + icon: "input-keyboard" + name: "Keyboard (FI)" + } + ListElement { + icon: "fcitx-pinyin" + name: "Pinyin" + } + ListElement { + icon: "fcitx-wubi" + name: "Wubi" + } + ListElement { + icon: "fcitx-erbi" + name: "Erbi" + } + } + + delegate: Row { + width: parent.width + height: units.iconSizes.medium + units.smallSpacing * 2 + spacing: units.smallSpacing + + PlasmaCore.IconItem { + anchors.verticalCenter: parent.verticalCenter + width: units.iconSizes.medium + height: units.iconSizes.medium + source: model.icon + } + + PlasmaComponents.Label { + anchors.verticalCenter: parent.verticalCenter + text: model.name + } + } + } + } +} diff --git a/applets/kimpanel/package/contents/ui/main.qml b/applets/kimpanel/package/contents/ui/main.qml --- a/applets/kimpanel/package/contents/ui/main.qml +++ b/applets/kimpanel/package/contents/ui/main.qml @@ -25,190 +25,79 @@ Item { id: kimpanel - property int visibleButtons: 0 - property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical + property string imIcon: "input-keyboard" + property string imLabel: "" + property string imTip: "" + property string imHint: "" - LayoutMirroring.enabled: !vertical && Qt.application.layoutDirection === Qt.RightToLeft - LayoutMirroring.childrenInherit: true + Layout.minimumWidth: units.iconSizeHints.panel + Layout.minimumHeight: units.iconSizeHints.panel - Layout.minimumWidth: vertical ? units.iconSizes.small : items.implicitWidth - Layout.minimumHeight: !vertical ? units.iconSizes.small : items.implicitHeight - Layout.preferredHeight: Layout.minimumHeight - Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation + Plasmoid.icon: imIcon + Plasmoid.toolTipMainText: imTip + Plasmoid.toolTipSubText: imTip - InputPanel { } + Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation - Flow { - id: items + // Icon view in system tray or panel + Plasmoid.compactRepresentation: PlasmaCore.IconItem { + source: imIcon width: parent.width height: parent.height - x: (parent.width - childrenRect.width) / 2 - y: (parent.height - childrenRect.height) / 2 - flow: kimpanel.vertical ? Flow.LeftToRight : Flow.TopToBottom - - property int iconSize: Math.min(units.iconSizeHints.panel, units.roundToIconSize(Math.min(width, height))) - Repeater { - model: ListModel { - id: list - dynamicRoles: true - } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton - delegate: Item { - id: iconDelegate - width: items.iconSize - height: items.iconSize - StatusIcon { - id: statusIcon - anchors.centerIn: parent - width: items.iconSize - height: items.iconSize - label: model.label - tip: model.tip - icon: model.icon - hint: model.hint - onTriggered : { - if (button === Qt.LeftButton) { - clickHandler(model.key); - // clickHandler will trigger the menu, but we have to wait for - // the menu data. So we have to set the visual parent ahead. - actionMenu.visualParent = statusIcon; - } else { - contextMenu.open(statusIcon, {key: model.key, label: model.label}); - } - } - } + onClicked: { + plasmoid.expanded = !plasmoid.expanded } } } - function clickHandler(key) { - var service = dataEngine.serviceForSource("statusbar"); - var operation = service.operationDescription("TriggerProperty"); - operation.key = key; - service.startOperationCall(operation); - } - - function action(key) { - var service = dataEngine.serviceForSource("statusbar"); - var operation = service.operationDescription(key); - service.startOperationCall(operation); - } - - function hideAction(key) { - // We must use assignment to change the configuration property, - // otherwise it won't get notified. - var hiddenList = plasmoid.configuration.hiddenList; - if (hiddenList.indexOf(key) === -1) { - hiddenList.push(key); - plasmoid.configuration.hiddenList = hiddenList; - } - timer.restart(); - } - - function showAction(key) { - // We must use assignment to change the configuration property, - // otherwise it won't get notified. - var hiddenList = plasmoid.configuration.hiddenList; - var index = hiddenList.indexOf(key); - if (index !== -1) { - hiddenList.splice(index, 1); - plasmoid.configuration.hiddenList = hiddenList; - } - timer.restart(); + // The expanded input status panel + Plasmoid.fullRepresentation: StatusPanel { + anchors.fill: parent + Layout.minimumWidth: units.gridUnit * 9 + Layout.minimumHeight: units.gridUnit * 9 } - function showMenu(menu, menuData) { - if (!menuData) { - return; - } - - if (menuData["timestamp"] > menu.timestamp) { - menu.timestamp = menuData["timestamp"]; - var actionList = []; - for (var i = 0; i < menuData["props"].length; i++ ) { - actionList.push({"actionId": menuData["props"][i].key, "icon": menuData["props"][i].icon, "text": menuData["props"][i].label, hint: menuData["props"][i].hint}); - } - if (actionList.length > 0) { - menu.actionList = actionList; - menu.open(); - } - } - } + // The floating input candidate list following text cursor position + InputPanel { } - ActionMenu { - property var timestamp: 0; - id: actionMenu - onActionClicked: { - clickHandler(actionId); - } + // Context menu of system tray or panel icon + function action_fcitxkcm() { + KCMShell.open(["kcm_fcitx.desktop"]); } - - ContextMenu { - id: contextMenu + function action_keyboardkcm() { + KCMShell.open(["kcm_keyboard.desktop"]); } - - Timer { - id: timer - interval: 50 - onTriggered: { - var data = dataEngine.data["statusbar"]["Properties"]; - if (!data) { - return; - } - var count = list.count; - var c = 0, i; - var hiddenActions = []; - for (i = 0; i < data.length; i ++) { - if (plasmoid.configuration.hiddenList.indexOf(data[i].key) !== -1) { - hiddenActions.push({'key': data[i].key, - 'icon': data[i].icon, - 'label': data[i].label}); - } else { - c = c + 1; - } - } - if (c < count) { - list.remove(c, count - c); - } - kimpanel.visibleButtons = c; - - c = 0; - for (i = 0; i < data.length; i ++) { - if (plasmoid.configuration.hiddenList.indexOf(data[i].key) !== -1) { - continue; - } - var itemData = {'key': data[i].key, - 'icon': data[i].icon, - 'label': data[i].label, - 'tip': data[i].tip, - 'hint': data[i].hint }; - if (c < count) { - list.set(c, itemData); - } else { - list.append(itemData); - } - c = c + 1; - } - contextMenu.actionList = hiddenActions; - } + Component.onCompleted: { + plasmoid.setAction("keyboardkcm", i18n("Configure &Keyboard"), "input-keyboard"); + plasmoid.setAction("fcitxkcm", i18n("Configure &Fcitx"), "fcitx"); } + // Data engine to get IME status information PlasmaCore.DataSource { id: dataEngine engine: "kimpanel" connectedSources: ["statusbar"] onDataChanged: { - showMenu(actionMenu, dataEngine.data["statusbar"]["Menu"]); - var data = dataEngine.data["statusbar"]["Properties"]; - if (!data) { - kimpanel.visibleButtons = 0; - return; + // Lock input method state when opening kimpanel so we can avoid state jumping + if (!plasmoid.expanded) { + var Properties = dataEngine.data["statusbar"]["Properties"]; + for (var i = 0; i < Properties.length; i++) { + var p = Properties[i]; + // Find data of current input method + if (p.key === "/Fcitx/im" || p.key.indexOf("/IBus/Engine/") === 0 || p.key.indexOf("/Factory/") === 0) { + imIcon = p.icon || "input-keyboard" + imLabel = p.label + imTip = p.tip + imHint = p.hint + } + } } - - timer.restart(); } } } - diff --git a/applets/kimpanel/package/metadata.desktop b/applets/kimpanel/package/metadata.desktop --- a/applets/kimpanel/package/metadata.desktop +++ b/applets/kimpanel/package/metadata.desktop @@ -117,7 +117,7 @@ Keywords[zh_CN]=Input;IM;输入法;输入; Keywords[zh_TW]=Input;IM; Type=Service -Icon=draw-freehand +Icon=input-keyboard X-KDE-ServiceTypes=Plasma/Applet X-Plasma-API=declarativeappletscript @@ -132,3 +132,5 @@ X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPL-2.0+ X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-NotificationArea=true +X-Plasma-NotificationAreaCategory=SystemServices