diff --git a/qml/AppControls2/CollectionItem.qml b/qml/AppControls2/CollectionItem.qml
new file mode 100644
index 0000000..a193c43
--- /dev/null
+++ b/qml/AppControls2/CollectionItem.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.12
+import org.ukui.menu.core 1.0
+
+RoundButton {
+ id: control
+ property string appName: ""
+ property string appIcon: ""
+
+ height: 104
+ width: height
+ radius: 10
+ scale: control.pressed ? 1.1 : 1.0
+ hoverEnabled: true
+
+ contentItem: IconLabel {
+ anchors.fill: parent
+ appName: control.appName
+ appIcon: control.appIcon
+ display: Display.TextUnderIcon
+ }
+
+ background: StyleBackground {
+ radius: control.radius
+ useStyleTransparent: false
+ alpha: control.pressed ? 0.75 : control.hovered ? 0.6 : 0.40
+ }
+}
+
diff --git a/qml/AppControls2/IconLabel.qml b/qml/AppControls2/IconLabel.qml
new file mode 100644
index 0000000..3de9772
--- /dev/null
+++ b/qml/AppControls2/IconLabel.qml
@@ -0,0 +1,70 @@
+import QtQuick 2.0
+import org.ukui.menu.core 1.0
+
+Item {
+ id: root
+
+ property int display: Display.TextUnderIcon
+ // 上下布局icon大小为48*48 左右布局icon大小为32*32
+ property int iconHeight: 48
+ property int iconWidth: 48
+ property string appName: ""
+ property string appIcon: ""
+ // 上下布局spacing:0 左右布局spacing:12
+ property int spacing: 2
+ state: root.display
+
+ states: [
+ State {
+ name: Display.TextBesideIcon
+ AnchorChanges {
+ target: iconImage
+ anchors.verticalCenter: root.verticalCenter
+ }
+ PropertyChanges {
+ target: iconText
+ textMaxWidth: root.width - iconImage.width - root.spacing
+
+ anchors.left: iconImage.right
+ anchors.leftMargin: root.spacing
+ anchors.verticalCenter: root.verticalCenter
+ }
+ },
+ State {
+ name: Display.TextUnderIcon
+ PropertyChanges {
+ target: iconImage
+ anchors.top: root.top
+ anchors.topMargin: (root.height - root.spacing -iconImage.height -iconText.height) / 2
+ anchors.horizontalCenter: root.horizontalCenter
+ }
+ PropertyChanges {
+ target: iconText
+ textMaxWidth: root.width
+
+ anchors.top: iconImage.bottom
+ anchors.topMargin: root.spacing
+ anchors.horizontalCenter: root.horizontalCenter
+ }
+ }
+ ]
+
+ Image {
+ id: iconImage
+ height: root.iconHeight
+ width: root.iconWidth
+ source: root.appIcon
+ }
+
+ StyleText {
+ id: iconText
+ property int textMaxWidth: root.width
+ text: root.appName
+ font.pixelSize: 14
+ elide: Text.ElideRight
+ Component.onCompleted: {
+ var textWidth = contentWidth > textMaxWidth ? textMaxWidth : contentWidth
+ width = textWidth
+ }
+ }
+}
diff --git a/qml/AppControls2/StyleBackground.qml b/qml/AppControls2/StyleBackground.qml
new file mode 100644
index 0000000..57562a7
--- /dev/null
+++ b/qml/AppControls2/StyleBackground.qml
@@ -0,0 +1,42 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.5
+import org.ukui.menu.core 1.0
+
+Rectangle {
+ property bool useStyleTransparent: true
+ property int paletteRole: Palette.Base
+ property int paletteGroup: Palette.Active
+ property real alpha: 1.0
+
+ clip: true
+
+ function updateColor() {
+ if (useStyleTransparent) {
+ color = themePalette.paletteColorWithTransparency(paletteRole,paletteGroup)
+ } else {
+ color = themePalette.paletteColorWithCustomTransparency(paletteRole,paletteGroup,alpha)
+ }
+ }
+
+ Component.onCompleted: {
+ updateColor()
+ themePalette.styleColorChanged.connect(updateColor)
+ }
+ Component.onDestruction: {
+ themePalette.styleColorChanged.disconnect(updateColor)
+ }
+
+ onUseStyleTransparentChanged: {
+ updateColor()
+ }
+ onPaletteRoleChanged: {
+ updateColor()
+ }
+ onPaletteGroupChanged: {
+ updateColor()
+ }
+ onAlphaChanged: {
+ updateColor()
+ }
+}
+
diff --git a/qml/AppControls2/StyleText.qml b/qml/AppControls2/StyleText.qml
new file mode 100644
index 0000000..89422c2
--- /dev/null
+++ b/qml/AppControls2/StyleText.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+import org.ukui.menu.core 1.0
+
+Text {
+ property int paletteRole: Palette.Text
+
+ function updateColor() {
+ color = themePalette.paletteColor(paletteRole)
+ }
+
+ Component.onCompleted: {
+ updateColor()
+ themePalette.styleColorChanged.connect(updateColor)
+ }
+ Component.onDestruction: {
+ themePalette.styleColorChanged.disconnect(updateColor)
+ }
+
+ onPaletteRoleChanged: {
+ updateColor()
+ }
+}
diff --git a/qml/qml.qrc b/qml/qml.qrc
index 374d78e..efc3fb5 100644
--- a/qml/qml.qrc
+++ b/qml/qml.qrc
@@ -10,5 +10,9 @@
AppUI/Sidebar.qml
AppControls2/qmldir
AppControls2/App.qml
+ AppControls2/CollectionItem.qml
+ AppControls2/StyleBackground.qml
+ AppControls2/StyleText.qml
+ AppControls2/IconLabel.qml
diff --git a/src/commons.h b/src/commons.h
index 79a5803..2811782 100644
--- a/src/commons.h
+++ b/src/commons.h
@@ -24,6 +24,19 @@
namespace UkuiMenu {
+class Display {
+ Q_GADGET
+public:
+ enum Type {
+ IconOnly,
+ TextOnly,
+ TextBesideIcon,
+ TextUnderIcon
+ };
+
+ Q_ENUM(Type)
+};
+
class SortType
{
Q_GADGET
@@ -94,6 +107,7 @@ public:
qRegisterMetaType("DataType::Type");
qRegisterMetaType("DataEntity");
+ qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "Display", "Use enums only.");
qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "SortType", "Use enums only");
qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataType", "Use enums only");
// qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataEntity", "unknown");