import { Button, VerticalBox , HorizontalBox, TabWidget, ListView, StandardListView, StandardTableView, CheckBox} from "std-widgets.slint"; import {CurrentTab, BottomPanelVisibility} from "common.slint"; import {ColorPalette} from "color_palette.slint"; import {GuiState} from "gui_state.slint"; import {Callabler} from "callabler.slint"; component TabItem { in property scanning; in property text; in property curr_tab; callback changed_current_tab(); Rectangle { width: parent.width; horizontal-stretch: 1.0; background: touch-area.has-hover ? ColorPalette.tab_hovered_color : transparent; touch_area := TouchArea { clicked => { if (GuiState.active_tab == root.curr_tab) { return; } GuiState.active_tab = root.curr_tab; Callabler.tab_changed(); changed_current_tab(); } } } HorizontalLayout { width: parent.width; alignment: LayoutAlignment.start; layout_rectangle := VerticalLayout { empty_rectangle := Rectangle { } current_rectangle := Rectangle { visible: (GuiState.active_tab == root.curr_tab); border-radius: 2px; width: 5px; height: 0px; background: ColorPalette.tab_selected_color; animate height{ duration: 150ms; easing: ease; } } empty_rectangle2 := Rectangle { } } } Text { text: root.text; width: parent.width; horizontal-alignment: center; } states [ is-selected when GuiState.active_tab == root.curr_tab: { current_rectangle.height: layout_rectangle.height; } is-not-selected when GuiState.active_tab != root.curr_tab: { current_rectangle.height: 0px; } ] } export component LeftSidePanel { in-out property scanning; callback changed_current_tab(); width: 120px; VerticalLayout { spacing: 2px; Rectangle { visible: GuiState.active_tab != CurrentTab.About; height: 80px; Image { width: parent.height; source: @image-url("../icons/logo_small.png"); image-fit: ImageFit.contain; } touch_area := TouchArea { clicked => { GuiState.active_tab = CurrentTab.About; Callabler.tab_changed(); root.changed_current_tab(); GuiState.bottom_panel_visibility = BottomPanelVisibility.NotVisible; } } } ListView { out property element_size: 25px; out property <[{name: string, tab: CurrentTab}]> speed_model: [ {name: "Duplicate Files", tab: CurrentTab.DuplicateFiles}, {name: "Empty Folders", tab: CurrentTab.EmptyFolders}, {name: "Big Files", tab: CurrentTab.BigFiles}, {name: "Empty Files", tab: CurrentTab.EmptyFiles}, {name: "Temporary Files", tab: CurrentTab.TemporaryFiles}, {name: "Similar Images", tab: CurrentTab.SimilarImages}, {name: "Similar Videos", tab: CurrentTab.SimilarVideos}, {name: "Music Duplicates", tab: CurrentTab.SimilarMusic}, {name: "Invalid Symlinks", tab: CurrentTab.InvalidSymlinks}, {name: "Broken Files", tab: CurrentTab.BrokenFiles}, {name: "Bad Extensions", tab: CurrentTab.BadExtensions} ]; for r[idx] in speed_model: TabItem { height: parent.element_size; scanning: scanning; text: r.name; curr_tab: r.tab; changed_current_tab() => {root.changed_current_tab();} } } Rectangle { HorizontalLayout { alignment: start; Button { visible: GuiState.active_tab != CurrentTab.Settings; min-width: 20px; min-height: 20px; max-height: self.width; preferred-height: self.width; icon: @image-url("../icons/settings.svg"); clicked => { GuiState.active_tab = CurrentTab.Settings; Callabler.tab_changed(); root.changed_current_tab(); } } } HorizontalLayout { alignment: end; Button { checkable: true; checked: GuiState.visible_tool_settings; visible: GuiState.available_subsettings; min-width: 20px; min-height: 20px; max-height: self.width; preferred-height: self.width; icon: @image-url("../icons/subsettings.svg"); clicked => { GuiState.visible_tool_settings = !GuiState.visible_tool_settings; } } } } } }