Compare commits

..

11 Commits

3 changed files with 160 additions and 150 deletions

View File

@ -3,7 +3,13 @@
<requires lib="gtk" version="4.0"/>
<requires lib="Adw" version="1.0"/>
<menu id="import_menu">
<menu id="sidebar_menu">
<section>
<item>
<attribute name="label">Add Project</attribute>
<attribute name="action">win.add-project</attribute>
</item>
</section>
<section>
<item>
<attribute name="label">Import from OpenAPI / Swagger</attribute>
@ -18,27 +24,36 @@
<attribute name="action">win.import-http-file</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>
<template class="RosterWindow" parent="AdwApplicationWindow">
<property name="default-width">1200</property>
<property name="default-height">800</property>
<property name="width-request">470</property>
<property name="content">
<object class="AdwToastOverlay" id="toast_overlay">
<property name="child">
<object class="GtkPaned" id="main_pane">
<property name="orientation">horizontal</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>
<object class="AdwOverlaySplitView" id="split_view">
<property name="min-sidebar-width">200</property>
<property name="max-sidebar-width">320</property>
<!-- LEFT: Sidebar Panel with AdwToolbarView -->
<property name="start-child">
<property name="sidebar">
<object class="AdwToolbarView">
<property name="width-request">200</property>
<!-- Sidebar Header Bar -->
<child type="top">
@ -59,20 +74,11 @@
</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>
<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>
@ -105,7 +111,7 @@
</property>
<!-- RIGHT: Main Content Panel with AdwToolbarView -->
<property name="end-child">
<property name="content">
<object class="AdwToolbarView">
<!-- Main Header Bar -->
@ -115,6 +121,20 @@
<property name="show-start-title-buttons">False</property>
<property name="show-end-title-buttons">False</property>
<!-- Sidebar toggle (only visible when collapsed) -->
<child type="start">
<object class="GtkToggleButton" id="sidebar_toggle_button">
<property name="icon-name">sidebar-show-symbolic</property>
<property name="tooltip-text">Show Sidebar</property>
<style>
<class name="flat"/>
</style>
<binding name="visible">
<lookup name="collapsed">split_view</lookup>
</binding>
</object>
</child>
<!-- Left side buttons -->
<child type="start">
<object class="GtkButton" id="save_request_button">
@ -126,7 +146,6 @@
</style>
</object>
</child>
<child type="start">
<object class="GtkButton" id="export_request_button">
<property name="icon-name">export-symbolic</property>
@ -138,13 +157,15 @@
</object>
</child>
<!-- Window controls: separate end child so it's always rightmost -->
<child type="end">
<object class="GtkWindowControls">
<property name="side">end</property>
</object>
</child>
<!-- Right side buttons -->
<child type="end">
<object class="GtkBox">
<property name="spacing">6</property>
<!-- New Request Button -->
<child>
<object class="GtkButton" id="new_request_button">
<property name="icon-name">list-add-symbolic</property>
<property name="tooltip-text">New Request (Ctrl+T)</property>
@ -153,25 +174,6 @@
</style>
</object>
</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>
</child>
</object>
</child>
@ -256,22 +258,14 @@
</property>
</object>
</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>
<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>

View File

@ -115,6 +115,7 @@ class RequestTabWidget(Gtk.Box):
self.url_entry = Gtk.Entry()
self.url_entry.set_placeholder_text("Enter URL...")
self.url_entry.set_hexpand(True)
self.url_entry.add_css_class("url-entry")
self.url_box.append(self.url_entry)
# Send Button
@ -131,10 +132,10 @@ class RequestTabWidget(Gtk.Box):
split_pane = Gtk.Paned(orientation=Gtk.Orientation.HORIZONTAL)
split_pane.set_vexpand(True)
split_pane.set_position(UI_PANE_REQUEST_RESPONSE_POSITION)
split_pane.set_shrink_start_child(False)
split_pane.set_shrink_end_child(False)
split_pane.set_resize_start_child(True)
split_pane.set_resize_end_child(True)
split_pane.set_shrink_start_child(True) # request can collapse to 0
split_pane.set_shrink_end_child(False) # response stays
split_pane.set_resize_start_child(True) # request gives up space first
split_pane.set_resize_end_child(False) # response keeps its size
# Request Panel
request_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
@ -165,6 +166,7 @@ class RequestTabWidget(Gtk.Box):
# Response Panel
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)
response_switcher = Gtk.StackSwitcher()

View File

@ -19,7 +19,7 @@
import gi
gi.require_version('GtkSource', '5')
from gi.repository import Adw, Gtk, GLib, Gio, GtkSource
from gi.repository import Adw, Gtk, GLib, Gio, GtkSource, GObject
from typing import Dict, Optional
import logging
from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab
@ -63,14 +63,12 @@ class RosterWindow(Adw.ApplicationWindow):
tab_view = Gtk.Template.Child()
tab_bar = Gtk.Template.Child()
# Panes
main_pane = Gtk.Template.Child()
# Split view
split_view = Gtk.Template.Child()
sidebar_toggle_button = Gtk.Template.Child()
# Sidebar widgets
projects_listbox = Gtk.Template.Child()
add_project_button = Gtk.Template.Child()
import_menu_button = Gtk.Template.Child()
# History (hidden but kept for compatibility)
history_listbox = Gtk.Template.Child()
@ -102,6 +100,14 @@ class RosterWindow(Adw.ApplicationWindow):
# 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
self._setup_tab_system()
self._load_projects()
@ -204,6 +210,11 @@ class RosterWindow(Adw.ApplicationWindow):
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-chip {
border-radius: 4px;
@ -508,6 +519,10 @@ class RosterWindow(Adw.ApplicationWindow):
self.add_action(action)
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.connect("activate", lambda a, p: self.on_import_openapi_clicked(None))
self.add_action(action)
@ -949,7 +964,6 @@ class RosterWindow(Adw.ApplicationWindow):
item.connect('manage-environments-requested', self._on_manage_environments, project)
self.projects_listbox.append(item)
@Gtk.Template.Callback()
def on_add_project_clicked(self, button):
"""Show dialog to create project."""
dialog = Adw.AlertDialog()