Compare commits

..

No commits in common. "60c0d0ac113fc25e1b6623c578c0db97951ef1aa" and "bc0ee493e7caeb720ea9c942f1fb29f20529a413" have entirely different histories.

3 changed files with 150 additions and 160 deletions

View File

@ -3,13 +3,7 @@
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="Adw" version="1.0"/> <requires lib="Adw" version="1.0"/>
<menu id="sidebar_menu"> <menu id="import_menu">
<section>
<item>
<attribute name="label">Add Project</attribute>
<attribute name="action">win.add-project</attribute>
</item>
</section>
<section> <section>
<item> <item>
<attribute name="label">Import from OpenAPI / Swagger</attribute> <attribute name="label">Import from OpenAPI / Swagger</attribute>
@ -24,148 +18,133 @@
<attribute name="action">win.import-http-file</attribute> <attribute name="action">win.import-http-file</attribute>
</item> </item>
</section> </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> </menu>
<template class="RosterWindow" parent="AdwApplicationWindow"> <template class="RosterWindow" parent="AdwApplicationWindow">
<property name="default-width">1200</property> <property name="default-width">1200</property>
<property name="default-height">800</property> <property name="default-height">800</property>
<property name="width-request">470</property>
<property name="content"> <property name="content">
<object class="AdwToastOverlay" id="toast_overlay"> <object class="AdwToastOverlay" id="toast_overlay">
<property name="child"> <property name="child">
<object class="AdwOverlaySplitView" id="split_view"> <object class="GtkPaned" id="main_pane">
<property name="min-sidebar-width">200</property> <property name="orientation">horizontal</property>
<property name="max-sidebar-width">320</property> <property name="position">180</property>
<property name="shrink-start-child">False</property>
<property name="resize-start-child">True</property>
<property name="shrink-end-child">False</property>
<property name="resize-end-child">True</property>
<property name="wide-handle">False</property>
<!-- LEFT: Sidebar Panel with AdwToolbarView --> <!-- LEFT: Sidebar Panel with AdwToolbarView -->
<property name="sidebar"> <property name="start-child">
<object class="AdwToolbarView"> <object class="AdwToolbarView">
<property name="width-request">200</property>
<!-- Sidebar Header Bar --> <!-- Sidebar Header Bar -->
<child type="top"> <child type="top">
<object class="AdwHeaderBar"> <object class="AdwHeaderBar">
<property name="show-end-title-buttons">False</property> <property name="show-end-title-buttons">False</property>
<property name="show-start-title-buttons">False</property> <property name="show-start-title-buttons">False</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label">Projects</property> <property name="label">Projects</property>
<style>
<class name="title"/>
</style>
</object>
</property>
<child type="start">
<object class="GtkWindowControls">
<property name="side">start</property>
</object>
</child>
<child type="end">
<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 type="end">
<object class="GtkMenuButton" id="import_menu_button">
<property name="icon-name">papyrus-vertical-symbolic</property>
<property name="tooltip-text">Import</property>
<property name="menu-model">import_menu</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
</child>
<!-- Sidebar Content -->
<property name="content">
<object class="GtkBox">
<property name="orientation">vertical</property>
<!-- Projects List -->
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<child>
<object class="GtkListBox" id="projects_listbox">
<style> <style>
<class name="title"/> <class name="navigation-sidebar"/>
</style>
</object>
</property>
<child type="start">
<object class="GtkWindowControls">
<property name="side">start</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="sidebar_hamburger_button">
<property name="primary">True</property>
<property name="icon-name">open-menu-symbolic</property>
<property name="tooltip-text">Menu</property>
<property name="menu-model">sidebar_menu</property>
<style>
<class name="flat"/>
</style> </style>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
<!-- Sidebar Content -->
<property name="content">
<object class="GtkBox">
<property name="orientation">vertical</property>
<!-- 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>
</object>
</property>
</object> </object>
</property> </property>
</object>
</property>
<!-- RIGHT: Main Content Panel with AdwToolbarView --> <!-- RIGHT: Main Content Panel with AdwToolbarView -->
<property name="content"> <property name="end-child">
<object class="AdwToolbarView"> <object class="AdwToolbarView">
<!-- Main Header Bar --> <!-- Main Header Bar -->
<child type="top"> <child type="top">
<object class="AdwHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title">False</property> <property name="show-title">False</property>
<property name="show-start-title-buttons">False</property> <property name="show-start-title-buttons">False</property>
<property name="show-end-title-buttons">False</property> <property name="show-end-title-buttons">False</property>
<!-- Sidebar toggle (only visible when collapsed) --> <!-- Left side buttons -->
<child type="start"> <child type="start">
<object class="GtkToggleButton" id="sidebar_toggle_button"> <object class="GtkButton" id="save_request_button">
<property name="icon-name">sidebar-show-symbolic</property> <property name="icon-name">document-save-symbolic</property>
<property name="tooltip-text">Show Sidebar</property> <property name="tooltip-text">Save Current Request (Ctrl+S)</property>
<style> <signal name="clicked" handler="on_save_request_clicked"/>
<class name="flat"/> <style>
</style> <class name="flat"/>
<binding name="visible"> </style>
<lookup name="collapsed">split_view</lookup> </object>
</binding> </child>
</object>
</child>
<!-- Left side buttons --> <child type="start">
<child type="start"> <object class="GtkButton" id="export_request_button">
<object class="GtkButton" id="save_request_button"> <property name="icon-name">export-symbolic</property>
<property name="icon-name">document-save-symbolic</property> <property name="tooltip-text">Export as cURL</property>
<property name="tooltip-text">Save Current Request (Ctrl+S)</property> <signal name="clicked" handler="on_export_request_clicked"/>
<signal name="clicked" handler="on_save_request_clicked"/> <style>
<style> <class name="flat"/>
<class name="flat"/> </style>
</style> </object>
</object> </child>
</child>
<child type="start">
<object class="GtkButton" id="export_request_button">
<property name="icon-name">export-symbolic</property>
<property name="tooltip-text">Export as cURL</property>
<signal name="clicked" handler="on_export_request_clicked"/>
<style>
<class name="flat"/>
</style>
</object>
</child>
<!-- Window controls: separate end child so it's always rightmost --> <!-- Right side buttons -->
<child type="end"> <child type="end">
<object class="GtkWindowControls"> <object class="GtkBox">
<property name="side">end</property> <property name="spacing">6</property>
</object>
</child>
<!-- Right side buttons --> <!-- New Request Button -->
<child type="end"> <child>
<object class="GtkButton" id="new_request_button"> <object class="GtkButton" id="new_request_button">
<property name="icon-name">list-add-symbolic</property> <property name="icon-name">list-add-symbolic</property>
<property name="tooltip-text">New Request (Ctrl+T)</property> <property name="tooltip-text">New Request (Ctrl+T)</property>
@ -174,8 +153,27 @@
</style> </style>
</object> </object>
</child> </child>
<!-- Main Menu -->
<child>
<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>
<!-- Window Controls -->
<child>
<object class="GtkWindowControls">
<property name="side">end</property>
</object>
</child>
</object> </object>
</child> </child>
</object>
</child>
<!-- Tab Bar as separate top bar --> <!-- Tab Bar as separate top bar -->
<child type="top"> <child type="top">
@ -258,14 +256,22 @@
</property> </property>
</object> </object>
</property> </property>
<!-- Collapse sidebar when window is narrow -->
<child>
<object class="AdwBreakpoint">
<condition>max-width: 700sp</condition>
<setter object="split_view" property="collapsed">True</setter>
</object>
</child>
</template> </template>
<menu id="primary_menu">
<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> </interface>

View File

@ -115,7 +115,6 @@ class RequestTabWidget(Gtk.Box):
self.url_entry = Gtk.Entry() self.url_entry = Gtk.Entry()
self.url_entry.set_placeholder_text("Enter URL...") self.url_entry.set_placeholder_text("Enter URL...")
self.url_entry.set_hexpand(True) self.url_entry.set_hexpand(True)
self.url_entry.add_css_class("url-entry")
self.url_box.append(self.url_entry) self.url_box.append(self.url_entry)
# Send Button # Send Button
@ -132,10 +131,10 @@ class RequestTabWidget(Gtk.Box):
split_pane = Gtk.Paned(orientation=Gtk.Orientation.HORIZONTAL) split_pane = Gtk.Paned(orientation=Gtk.Orientation.HORIZONTAL)
split_pane.set_vexpand(True) split_pane.set_vexpand(True)
split_pane.set_position(UI_PANE_REQUEST_RESPONSE_POSITION) split_pane.set_position(UI_PANE_REQUEST_RESPONSE_POSITION)
split_pane.set_shrink_start_child(True) # request can collapse to 0 split_pane.set_shrink_start_child(False)
split_pane.set_shrink_end_child(False) # response stays split_pane.set_shrink_end_child(False)
split_pane.set_resize_start_child(True) # request gives up space first split_pane.set_resize_start_child(True)
split_pane.set_resize_end_child(False) # response keeps its size split_pane.set_resize_end_child(True)
# Request Panel # Request Panel
request_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) request_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
@ -166,7 +165,6 @@ class RequestTabWidget(Gtk.Box):
# Response Panel # Response Panel
response_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) response_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
response_box.set_size_request(250, -1)
# Stack switcher (placed in bottom bar together with status info) # Stack switcher (placed in bottom bar together with status info)
response_switcher = Gtk.StackSwitcher() response_switcher = Gtk.StackSwitcher()

View File

@ -19,7 +19,7 @@
import gi import gi
gi.require_version('GtkSource', '5') gi.require_version('GtkSource', '5')
from gi.repository import Adw, Gtk, GLib, Gio, GtkSource, GObject from gi.repository import Adw, Gtk, GLib, Gio, GtkSource
from typing import Dict, Optional from typing import Dict, Optional
import logging import logging
from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab
@ -63,12 +63,14 @@ class RosterWindow(Adw.ApplicationWindow):
tab_view = Gtk.Template.Child() tab_view = Gtk.Template.Child()
tab_bar = Gtk.Template.Child() tab_bar = Gtk.Template.Child()
# Split view # Panes
split_view = Gtk.Template.Child() main_pane = Gtk.Template.Child()
sidebar_toggle_button = Gtk.Template.Child()
# Sidebar widgets # Sidebar widgets
projects_listbox = Gtk.Template.Child() projects_listbox = Gtk.Template.Child()
add_project_button = Gtk.Template.Child()
import_menu_button = Gtk.Template.Child()
# History (hidden but kept for compatibility) # History (hidden but kept for compatibility)
history_listbox = Gtk.Template.Child() history_listbox = Gtk.Template.Child()
@ -100,14 +102,6 @@ class RosterWindow(Adw.ApplicationWindow):
# Setup custom CSS # Setup custom CSS
self._setup_custom_css() self._setup_custom_css()
# Bind sidebar toggle button to split view (bidirectional)
self.split_view.bind_property(
'show-sidebar',
self.sidebar_toggle_button,
'active',
GObject.BindingFlags.BIDIRECTIONAL | GObject.BindingFlags.SYNC_CREATE
)
# Setup UI # Setup UI
self._setup_tab_system() self._setup_tab_system()
self._load_projects() self._load_projects()
@ -210,11 +204,6 @@ class RosterWindow(Adw.ApplicationWindow):
font-weight: 600; font-weight: 600;
} }
/* URL entry can shrink to near-zero so the Send button stays visible */
entry.url-entry {
min-width: 0;
}
/* Method chips in sidebar request list */ /* Method chips in sidebar request list */
.method-chip { .method-chip {
border-radius: 4px; border-radius: 4px;
@ -519,10 +508,6 @@ class RosterWindow(Adw.ApplicationWindow):
self.add_action(action) self.add_action(action)
self.get_application().set_accels_for_action("win.send-request", ["<Control>Return"]) self.get_application().set_accels_for_action("win.send-request", ["<Control>Return"])
action = Gio.SimpleAction.new("add-project", None)
action.connect("activate", lambda a, p: self.on_add_project_clicked(None))
self.add_action(action)
action = Gio.SimpleAction.new("import-openapi", None) action = Gio.SimpleAction.new("import-openapi", None)
action.connect("activate", lambda a, p: self.on_import_openapi_clicked(None)) action.connect("activate", lambda a, p: self.on_import_openapi_clicked(None))
self.add_action(action) self.add_action(action)
@ -964,6 +949,7 @@ class RosterWindow(Adw.ApplicationWindow):
item.connect('manage-environments-requested', self._on_manage_environments, project) item.connect('manage-environments-requested', self._on_manage_environments, project)
self.projects_listbox.append(item) self.projects_listbox.append(item)
@Gtk.Template.Callback()
def on_add_project_clicked(self, button): def on_add_project_clicked(self, button):
"""Show dialog to create project.""" """Show dialog to create project."""
dialog = Adw.AlertDialog() dialog = Adw.AlertDialog()