├── README.md ├── SideBar.pro ├── SideBar.qml ├── fonts └── SourceSansPro-Regular.ttf ├── icons ├── Bookmarks.svg ├── Explore.svg ├── Home.svg ├── Menu.svg ├── Messages.svg ├── Notifications.svg ├── Profile.svg ├── Search.svg └── Setting.svg ├── main.cpp ├── main.qml └── qml.qrc /README.md: -------------------------------------------------------------------------------- 1 | # SideBar 2 | simple side bar created with Qml
3 | icons used in the program: https://www.figma.com/community/file/944228750903853832 4 | # Demo 5 | https://user-images.githubusercontent.com/81587689/128551462-4a84c207-5807-4da0-b654-2373e95f7c38.mp4 6 | -------------------------------------------------------------------------------- /SideBar.pro: -------------------------------------------------------------------------------- 1 | QT += quick svg 2 | 3 | CONFIG += c++17 4 | 5 | # You can make your code fail to compile if it uses deprecated APIs. 6 | # In order to do so, uncomment the following line. 7 | # DEFINES += QT_DISABLE_DEPRECATED_BEFORE = 0x060000 # disables all the APIs deprecated before Qt 6.0.0 8 | 9 | SOURCES += \ 10 | main.cpp 11 | 12 | RESOURCES += qml.qrc 13 | 14 | # Additional import path used to resolve QML modules in Qt Creator's code model 15 | QML_IMPORT_PATH = 16 | 17 | # Additional import path used to resolve QML modules just for Qt Quick Designer 18 | QML_DESIGNER_IMPORT_PATH = 19 | 20 | # Default rules for deployment. 21 | qnx: target.path = /tmp/$${TARGET}/bin 22 | else: unix:!android: target.path = /opt/$${TARGET}/bin 23 | !isEmpty(target.path): INSTALLS += target 24 | -------------------------------------------------------------------------------- /SideBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Controls 2.15 3 | import QtQuick.Layouts 1.15 4 | import QtGraphicalEffects 1.15 5 | 6 | Item { 7 | id: sideBar 8 | 9 | width: 105 10 | height: 700 11 | state: 'close' 12 | anchors.centerIn: parent 13 | 14 | states: [ 15 | State { 16 | name: 'open' 17 | 18 | PropertyChanges { 19 | target: sideBar 20 | width: 270 21 | } 22 | 23 | PropertyChanges { 24 | target: timer 25 | index: 0 26 | } 27 | }, 28 | State { 29 | name: 'close' 30 | 31 | PropertyChanges { 32 | target: sideBar 33 | width: 105 34 | } 35 | 36 | PropertyChanges { 37 | target: timer 38 | index: 0 39 | } 40 | } 41 | ] 42 | 43 | transitions: [ 44 | Transition { 45 | from: 'close' 46 | to: 'open' 47 | 48 | NumberAnimation { 49 | properties: 'width' 50 | duration: 300 51 | easing.type: Easing.OutCubic 52 | } 53 | 54 | ScriptAction { 55 | script: { 56 | timer.start(); 57 | } 58 | } 59 | }, 60 | Transition { 61 | from: 'open' 62 | to: 'close' 63 | 64 | SequentialAnimation { 65 | 66 | ScriptAction { 67 | script: { 68 | timer.start(); 69 | } 70 | } 71 | 72 | PauseAnimation { 73 | duration: 600 74 | } 75 | 76 | NumberAnimation { 77 | properties: 'width' 78 | duration: 300 79 | easing.type: Easing.OutCubic 80 | } 81 | } 82 | } 83 | ] 84 | 85 | Timer { 86 | id: timer 87 | 88 | property int index: 0 89 | 90 | interval: 10 91 | 92 | onTriggered: { 93 | if (sideBar.state == 'open') 94 | columnItems.itemAt(index).state = 'left'; 95 | else 96 | columnItems.itemAt(index).state = 'middle'; 97 | 98 | if (++index != 9) 99 | timer.start(); 100 | } 101 | } 102 | 103 | Rectangle { 104 | id: body 105 | 106 | radius: 10 107 | color: '#FFFFFF' 108 | anchors.fill: parent 109 | 110 | ColumnLayout { 111 | id: buttonColumn 112 | 113 | width: parent.width 114 | spacing: 20 115 | anchors { top: parent.top; topMargin: 30 } 116 | 117 | Repeater { 118 | id: columnItems 119 | 120 | model: ['Menu', 'Search', 'Home', 'Explore', 'Notifications', 'Bookmarks', 'Messages', 'Profile', 'Setting'] 121 | delegate: Rectangle { 122 | id: button 123 | 124 | Layout.preferredWidth: 50 125 | Layout.preferredHeight: 50 126 | radius: 10 127 | color: buttonMouseArea.containsMouse ? '#f0f0f0' : '#ffffff' 128 | Layout.alignment: Qt.AlignLeft 129 | Layout.topMargin: model.index === 1 ? 20 : 0 130 | state: 'middle' 131 | 132 | Behavior on color { 133 | ColorAnimation { 134 | duration: 200 135 | } 136 | } 137 | 138 | states: [ 139 | State { 140 | name: 'left' 141 | 142 | PropertyChanges { 143 | target: button 144 | Layout.leftMargin: 10 145 | Layout.preferredWidth: model.index !== 0 ? 240 : 50 146 | } 147 | 148 | PropertyChanges { 149 | target: title 150 | opacity: 1 151 | } 152 | }, 153 | State { 154 | name: 'middle' 155 | 156 | PropertyChanges { 157 | target: button 158 | Layout.leftMargin: Math.ceil((sideBar.width - 50) / 2) 159 | Layout.preferredWidth: 50 160 | } 161 | 162 | PropertyChanges { 163 | target: title 164 | opacity: 0 165 | } 166 | } 167 | ] 168 | 169 | transitions: [ 170 | Transition { 171 | from: 'middle' 172 | to: 'left' 173 | 174 | NumberAnimation { 175 | properties: 'Layout.leftMargin, Layout.preferredWidth, opacity' 176 | duration: 300 177 | easing.type: Easing.InOutSine 178 | } 179 | }, 180 | Transition { 181 | from: 'left' 182 | to: 'middle' 183 | 184 | NumberAnimation { 185 | properties: 'Layout.leftMargin, Layout.preferredWidth, opacity' 186 | duration: 300 187 | easing.type: Easing.InOutSine 188 | } 189 | } 190 | ] 191 | 192 | MouseArea { 193 | id: buttonMouseArea 194 | 195 | hoverEnabled: true 196 | anchors.fill: parent 197 | 198 | onClicked: { 199 | if (model.index === 0) { 200 | if (sideBar.state == 'close') 201 | sideBar.state = 'open'; 202 | else 203 | sideBar.state = 'close'; 204 | } 205 | } 206 | } 207 | 208 | Image { 209 | id: icon 210 | 211 | source: 'icons/' + modelData + '.svg' 212 | sourceSize: Qt.size(30, 30) 213 | anchors { verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: 10 } 214 | } 215 | 216 | Text { 217 | id: title 218 | 219 | text: model.index === 0 ? '' : modelData 220 | font.family: sourceSansProFont.name 221 | anchors { verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: 55 } 222 | 223 | } 224 | } 225 | } 226 | } 227 | } 228 | 229 | DropShadow { 230 | id: shadow 231 | 232 | anchors.fill: body 233 | source: body 234 | radius: 20 235 | samples: radius * 2 + 1 236 | color: Qt.rgba(0, 0, 0, 0.05) 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /fonts/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmirHosseinCH/SideBar/78f61bf7326997325dcad4b7cbdecceb5643cb11/fonts/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /icons/Bookmarks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /icons/Explore.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /icons/Home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /icons/Menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /icons/Messages.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /icons/Notifications.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /icons/Profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /icons/Search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /icons/Setting.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) { 6 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 7 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 8 | #endif 9 | 10 | QGuiApplication app(argc, argv); 11 | 12 | QSurfaceFormat format; 13 | format.setSamples(8); 14 | QSurfaceFormat::setDefaultFormat(format); 15 | 16 | QQmlApplicationEngine engine; 17 | const QUrl url(QStringLiteral("qrc:/main.qml")); 18 | QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, 19 | &app, [url](QObject *obj, const QUrl &objUrl) { 20 | if (!obj && url == objUrl) 21 | QCoreApplication::exit(-1); 22 | }, Qt::QueuedConnection); 23 | engine.load(url); 24 | 25 | return app.exec(); 26 | } 27 | -------------------------------------------------------------------------------- /main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Controls 2.15 3 | 4 | ApplicationWindow { 5 | id: window 6 | 7 | width: 750 8 | height: 850 9 | visible: true 10 | title: 'SideBar' 11 | color: '#E0E2ED' 12 | 13 | FontLoader { 14 | id: sourceSansProFont 15 | 16 | source: 'fonts/SourceSansPro-Regular.ttf' 17 | name: 'SourceSansPro' 18 | } 19 | 20 | SideBar {} 21 | } 22 | -------------------------------------------------------------------------------- /qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.qml 4 | fonts/SourceSansPro-Regular.ttf 5 | SideBar.qml 6 | icons/Bookmarks.svg 7 | icons/Explore.svg 8 | icons/Home.svg 9 | icons/Menu.svg 10 | icons/Messages.svg 11 | icons/Notifications.svg 12 | icons/Profile.svg 13 | icons/Search.svg 14 | icons/Setting.svg 15 | 16 | 17 | --------------------------------------------------------------------------------