roster/src/main-window.ui
Pavel Baksy 3cc96a82d6 Add foldable sidebar with custom project icons
Implement a collapsible sidebar that can be folded to show just project
icons in a slim strip, or expanded to show full project details. Projects
can now have custom icons selected from a 6x6 grid of 36 symbolic icons.

Features:
- Foldable sidebar with toggle button (fold/unfold)
- Slim sidebar view showing only project icons when folded
- Custom project icons with 36 symbolic icon choices
- Icon picker dialog with 6x6 grid layout
- Edit Project dialog (renamed from Rename) with name and icon selection
- Project icons displayed in both full and slim sidebar views
- Smooth transitions between folded/unfolded states
- Click on slim project icon to unfold sidebar

Technical changes:
- Add icon field to Project model with default "folder-symbolic"
- Create constants.py with PROJECT_ICONS list (36 symbolic icons)
- Implement IconPickerDialog with grid layout and selection
- Create SlimProjectItem widget for folded sidebar view
- Update ProjectManager.update_project() to handle icon changes
- Restructure sidebar using GtkStack for full/slim view switching
- Update project-item.ui to display project icon
- Change "Rename" menu to "Edit Project" with icon picker
- Add fold/unfold buttons with sidebar-show icons
- Update build system with new files and resources
2025-12-18 15:37:29 +01:00

396 lines
18 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<requires lib="Adw" version="1.0"/>
<template class="RosterWindow" parent="AdwApplicationWindow">
<property name="title">Roster</property>
<property name="default-width">1200</property>
<property name="default-height">800</property>
<property name="content">
<object class="AdwToolbarView">
<!-- Header Bar -->
<child type="top">
<object class="AdwHeaderBar">
<child type="end">
<object class="GtkMenuButton">
<property name="primary">True</property>
<property name="icon-name">open-menu-symbolic</property>
<property name="tooltip-text" translatable="yes">Main Menu</property>
<property name="menu-model">primary_menu</property>
</object>
</child>
</object>
</child>
<!-- Main Content -->
<property name="content">
<object class="GtkBox">
<property name="orientation">vertical</property>
<!-- URL Input Section -->
<child>
<object class="AdwClamp">
<property name="maximum-size">1000</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<!-- Method Dropdown -->
<child>
<object class="GtkDropDown" id="method_dropdown">
<property name="enable-search">False</property>
</object>
</child>
<!-- URL Entry -->
<child>
<object class="GtkEntry" id="url_entry">
<property name="placeholder-text">Enter URL...</property>
<property name="hexpand">True</property>
</object>
</child>
<!-- Send Button -->
<child>
<object class="GtkButton" id="send_button">
<property name="label">Send</property>
<signal name="clicked" handler="on_send_clicked"/>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- 3-Column Layout: Sidebar | Request | Response -->
<child>
<object class="GtkPaned" id="main_pane">
<property name="vexpand">True</property>
<property name="orientation">horizontal</property>
<property name="position">250</property>
<property name="shrink-start-child">False</property>
<property name="resize-start-child">True</property>
<!-- START: Sidebar for Projects -->
<property name="start-child">
<object class="GtkStack" id="sidebar_stack">
<property name="transition-type">slide-left-right</property>
<!-- Full Sidebar -->
<child>
<object class="GtkStackPage">
<property name="name">full</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="width-request">200</property>
<!-- Sidebar Header -->
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<child>
<object class="GtkLabel">
<property name="label">Projects</property>
<property name="xalign">0</property>
<property name="hexpand">True</property>
<style>
<class name="heading"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="add_project_button">
<property name="icon-name">list-add-symbolic</property>
<property name="tooltip-text">Add Project</property>
<signal name="clicked" handler="on_add_project_clicked"/>
<style>
<class name="flat"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="fold_sidebar_button">
<property name="icon-name">sidebar-show-right-symbolic</property>
<property name="tooltip-text">Fold Sidebar</property>
<signal name="clicked" handler="on_fold_sidebar_clicked"/>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
</child>
<!-- Projects List -->
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<child>
<object class="GtkListBox" id="projects_listbox">
<style>
<class name="navigation-sidebar"/>
</style>
</object>
</child>
</object>
</child>
<!-- Save Current Request Button -->
<child>
<object class="GtkButton" id="save_request_button">
<property name="label">Save Current Request</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-bottom">12</property>
<signal name="clicked" handler="on_save_request_clicked"/>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
<!-- Slim Sidebar -->
<child>
<object class="GtkStackPage">
<property name="name">slim</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="width-request">60</property>
<!-- Unfold Button -->
<child>
<object class="GtkButton" id="unfold_sidebar_button">
<property name="icon-name">sidebar-show-left-symbolic</property>
<property name="tooltip-text">Unfold Sidebar</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<signal name="clicked" handler="on_unfold_sidebar_clicked"/>
<style>
<class name="flat"/>
</style>
</object>
</child>
<!-- Slim Projects List -->
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<child>
<object class="GtkBox" id="slim_projects_box">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</property>
<!-- END: Request/Response Split -->
<property name="end-child">
<object class="GtkPaned" id="split_pane">
<property name="orientation">horizontal</property>
<property name="position">600</property>
<property name="shrink-start-child">False</property>
<property name="shrink-end-child">False</property>
<property name="resize-start-child">True</property>
<property name="resize-end-child">True</property>
<!-- LEFT: Request Configuration -->
<property name="start-child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<!-- Request Tabs Placeholder -->
<child>
<object class="GtkBox" id="request_tabs_container">
<property name="orientation">vertical</property>
<property name="vexpand">True</property>
</object>
</child>
</object>
</property>
<!-- RIGHT: Response Display -->
<property name="end-child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<!-- Response Tabs Placeholder -->
<child>
<object class="GtkBox" id="response_tabs_container">
<property name="orientation">vertical</property>
<property name="vexpand">True</property>
</object>
</child>
<!-- Status Bar -->
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<child>
<object class="GtkLabel" id="status_label">
<property name="label">Ready</property>
<style>
<class name="heading"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="time_label">
<property name="label"></property>
</object>
</child>
<!-- Spacer -->
<child>
<object class="GtkBox">
<property name="hexpand">True</property>
</object>
</child>
<!-- History Toggle Button -->
<child>
<object class="GtkToggleButton" id="history_toggle_button">
<property name="icon-name">view-list-symbolic</property>
<property name="tooltip-text">Toggle History Panel</property>
<signal name="toggled" handler="on_history_toggle_button_toggled"/>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
</child>
<!-- History Panel (Collapsible) -->
<child>
<object class="GtkRevealer" id="history_revealer">
<property name="reveal-child">False</property>
<property name="transition-type">slide-up</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="height-request">200</property>
<!-- History Header -->
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">6</property>
<child>
<object class="GtkLabel">
<property name="label">Request History</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<style>
<class name="heading"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="hide_history_button">
<property name="icon-name">go-down-symbolic</property>
<property name="tooltip-text">Hide history</property>
<signal name="clicked" handler="on_toggle_history"/>
</object>
</child>
</object>
</child>
<!-- History List -->
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<child>
<object class="GtkListBox" id="history_listbox">
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</property>
</template>
<menu id="primary_menu">
<section>
<item>
<attribute name="label" translatable="yes">Toggle History</attribute>
<attribute name="action">win.toggle-history</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
<attribute name="action">app.shortcuts</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About Roster</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
</interface>