Compare commits

...

9 Commits

Author SHA1 Message Date
Juan Pablo Ugarte
315ca0cfb0 Merengue: add mrg_webkit module
- Modify WebKit2 (Gtk3) module for Webkit (Gtk4)
2024-02-15 18:12:09 -05:00
Juan Pablo Ugarte
a350cbb143 CmbProject: fix dnd errors 2024-02-15 18:12:09 -05:00
Juan Pablo Ugarte
6adce49744 UI files: open/export all UI files with Cambalache 2024-02-15 18:12:09 -05:00
Juan Pablo Ugarte
706d68b476 CmbFragmentEditor: add support for custom fragments 2024-02-15 18:12:09 -05:00
Juan Pablo Ugarte
9c12a62f36 Data Model: add object custom_child_fragment column
- Add type check to boolean columns
 - Add support for importing/exporting custom_child_fragment
 - Add typing to __node_get("translatable:bool")
   Make sure all boolean nodes have the type anotation
 - Bump project version to 0.17.3
2024-02-15 18:11:52 -05:00
Juan Pablo Ugarte
59ab9fae66 MrgGtkPopover: only create window if popover is not triggered from the UI 2024-02-15 18:00:02 -05:00
Juan Pablo Ugarte
964c788a2a CmbUI: improve get_display_name()
Return template name if it has no file set
2024-02-15 17:59:15 -05:00
Juan Pablo Ugarte
6b716b5dfc CmbTypeChooserWidget: set sw max size on map 2024-02-15 17:58:34 -05:00
Juan Pablo Ugarte
4b4f79ba49 CmbCssEditor: use popover for ui list 2024-02-15 17:56:46 -05:00
24 changed files with 947 additions and 581 deletions

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_shortcuts.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkShortcutsWindow" id="shortcuts">
<property name="section-name">shortcuts</property>
@ -8,67 +10,66 @@
<property name="section-name">shortcuts</property>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="1">Project</property>
<property name="title" translatable="yes">Project</property>
<property name="view">shortcuts</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;n</property>
<property name="title" translatable="1">Create new project</property>
<property name="title" translatable="yes">Create new project</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;o</property>
<property name="title" translatable="1">Open a project</property>
<property name="title" translatable="yes">Open a project</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;w</property>
<property name="title" translatable="1">Close the project</property>
<property name="title" translatable="yes">Close the project</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;s</property>
<property name="title" translatable="1">Save the project</property>
<property name="title" translatable="yes">Save the project</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">0</property>
<property name="accelerator">&lt;Control&gt;e</property>
<property name="title" translatable="1">Save and Export</property>
<property name="title" translatable="yes">Save and Export</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="1">Workspace</property>
<property name="title" translatable="yes">Workspace</property>
<property name="view">shortcuts</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;Insert</property>
<property name="title" translatable="1">Add slot/column</property>
<property name="title" translatable="yes">Add slot/column</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;Delete</property>
<property name="title" translatable="1">Remove slot/column</property>
<property name="title" translatable="yes">Remove slot/column</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;&lt;shift&gt;Insert</property>
<property name="title" translatable="1">Add row</property>
<property name="title" translatable="yes">Add row</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;Control&gt;&lt;shift&gt;Delete</property>
<property name="title" translatable="1">Remove row</property>
<property name="title" translatable="yes">Remove row</property>
</object>
</child>
</object>

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_window.ui -->
<requires lib="gtk" version="4.0"/>
<requires lib="gio" version="2.0"/>
<object class="GtkFileFilter" id="import_filter">
<mime-types>
<mime-type>application/x-glade</mime-type>
@ -15,47 +18,47 @@
<section>
<item>
<attribute name="action">win.import</attribute>
<attribute name="label" translatable="1">Import</attribute>
<attribute name="label" translatable="yes">Import</attribute>
</item>
<item>
<attribute name="action">win.export</attribute>
<attribute name="label" translatable="1">Export all</attribute>
<attribute name="label" translatable="yes">Export all</attribute>
</item>
<item>
<attribute name="action">win.add_css</attribute>
<attribute name="label" translatable="1">Add CSS file</attribute>
<attribute name="label" translatable="yes">Add CSS file</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.close</attribute>
<attribute name="label" translatable="1">Close Project</attribute>
<attribute name="label" translatable="yes">Close Project</attribute>
</item>
<item>
<attribute name="action">win.debug</attribute>
<attribute name="label" translatable="1">Debug Project Data</attribute>
<attribute name="label" translatable="yes">Debug Project Data</attribute>
</item>
<item>
<attribute name="action">win.intro</attribute>
<attribute name="label" translatable="1">Interactive intro</attribute>
<attribute name="label" translatable="yes">Interactive intro</attribute>
</item>
<item>
<attribute name="action">win.contact</attribute>
<attribute name="label" translatable="1">Contact</attribute>
<attribute name="label" translatable="yes">Contact</attribute>
</item>
<item>
<attribute name="action">win.donate</attribute>
<attribute name="label" translatable="1">Donate</attribute>
<attribute name="label" translatable="yes">Donate</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.show-help-overlay</attribute>
<attribute name="label" translatable="1">Keyboard Shortcuts</attribute>
<attribute name="label" translatable="yes">Keyboard Shortcuts</attribute>
</item>
<item>
<attribute name="action">win.about</attribute>
<attribute name="label" translatable="1">About</attribute>
<attribute name="label" translatable="yes">About</attribute>
</item>
</section>
</menu>
@ -66,9 +69,6 @@
</mime-types>
</object>
<template class="CmbWindow" parent="GtkApplicationWindow">
<style>
<class name="cmb-window"/>
</style>
<child>
<object class="GtkOverlay">
<property name="child">
@ -76,20 +76,18 @@
<property name="transition-type">crossfade</property>
<child>
<object class="GtkStackPage">
<property name="name">cambalache</property>
<property name="title" translatable="1">Cambalache</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="version_label">
<property name="vexpand">1</property>
<property name="name">version</property>
<property name="halign">center</property>
<property name="valign">end</property>
<property name="margin-bottom">4</property>
<property name="name">version</property>
<property name="valign">end</property>
<property name="vexpand">1</property>
<attributes>
<attribute name="size" value="9000"></attribute>
<attribute name="size" value="9000"/>
</attributes>
</object>
</child>
@ -98,36 +96,36 @@
</style>
</object>
</property>
<property name="name">cambalache</property>
<property name="title" translatable="yes">Cambalache</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">new_project</property>
<property name="title" translatable="1">New Project</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="1">&lt;b&gt;
<property name="justify">center</property>
<property name="label" translatable="yes">&lt;b&gt;
&lt;span size=&quot;18000&quot;&gt;New project&lt;/span&gt;
&lt;span size="18000"&gt;New project&lt;/span&gt;
&lt;/b&gt;</property>
<property name="use-markup">1</property>
<property name="justify">center</property>
</object>
</child>
<child>
<object class="GtkGrid">
<property name="halign">center</property>
<property name="valign">start</property>
<property name="row-spacing">8</property>
<property name="column-spacing">8</property>
<property name="column-homogeneous">1</property>
<property name="column-spacing">8</property>
<property name="halign">center</property>
<property name="row-spacing">8</property>
<property name="valign">start</property>
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="label" translatable="1">Name</property>
<property name="label" translatable="yes">Name</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
@ -137,7 +135,7 @@
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="label" translatable="1">Toolkit target</property>
<property name="label" translatable="yes">Toolkit target</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
@ -147,7 +145,7 @@
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="label" translatable="1">Location</property>
<property name="label" translatable="yes">Location</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
@ -157,25 +155,25 @@
<child>
<object class="GtkEntry" id="np_name_entry">
<property name="focusable">1</property>
<property name="width-chars">32</property>
<property name="placeholder-text" translatable="1">&lt;project basename&gt;</property>
<property name="input-purpose">alpha</property>
<property name="input-hints">GTK_INPUT_HINT_LOWERCASE | GTK_INPUT_HINT_NONE</property>
<signal name="changed" handler="on_np_name_entry_changed" swapped="no"/>
<property name="input-purpose">alpha</property>
<property name="placeholder-text" translatable="yes">&lt;project basename&gt;</property>
<property name="width-chars">32</property>
<signal name="changed" handler="on_np_name_entry_changed"/>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="column-span">3</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="np_create_button">
<property name="label" translatable="1">Create</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="margin-top">16</property>
<property name="action-name">win.new</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Create</property>
<property name="margin-top">16</property>
<property name="receives-default">1</property>
<style>
<class name="suggested-action"/>
</style>
@ -189,14 +187,11 @@
<object class="GtkBox">
<property name="halign">start</property>
<property name="homogeneous">True</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="np_gtk3_radiobutton">
<property name="tooltip-text" translatable="1">Old stable version</property>
<property name="halign">center</property>
<property name="group">np_gtk4_radiobutton</property>
<property name="halign">center</property>
<property name="tooltip-text" translatable="yes">Old stable version</property>
<child>
<object class="GtkBox">
<property name="spacing">8</property>
@ -210,9 +205,9 @@
</child>
<child>
<object class="GtkLabel">
<property name="justify">center</property>
<property name="label">&lt;b&gt;Gtk 3&lt;/b&gt;</property>
<property name="use-markup">1</property>
<property name="justify">center</property>
</object>
</child>
</object>
@ -221,9 +216,9 @@
</child>
<child>
<object class="GtkToggleButton" id="np_gtk4_radiobutton">
<property name="tooltip-text" translatable="1">Recommended for new projects</property>
<property name="halign">center</property>
<property name="active">1</property>
<property name="halign">center</property>
<property name="tooltip-text" translatable="yes">Recommended for new projects</property>
<child>
<object class="GtkBox">
<property name="spacing">8</property>
@ -237,27 +232,30 @@
</child>
<child>
<object class="GtkLabel">
<property name="justify">center</property>
<property name="label">&lt;b&gt;Gtk 4&lt;/b&gt;</property>
<property name="use-markup">1</property>
<property name="justify">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="linked"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">2</property>
<property name="column-span">3</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="np_location_chooser">
<property name="sensitive">False</property>
<property name="icon-name">folder-symbolic</property>
<property name="action-name">win.select_project_location</property>
<property name="icon-name">folder-symbolic</property>
<property name="sensitive">False</property>
<child>
<object class="GtkBox">
<property name="spacing">4</property>
@ -268,26 +266,26 @@
</child>
<child>
<object class="GtkLabel" id="np_location_chooser_label">
<property name="hexpand">True</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
</child>
</object>
</child>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="column-span">3</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="np_cancel_button">
<property name="label" translatable="1">Cancel</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="margin-top">16</property>
<property name="action-name">win.show_workspace</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Cancel</property>
<property name="margin-top">16</property>
<property name="receives-default">1</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
@ -297,7 +295,7 @@
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="label" translatable="1">UI Filename</property>
<property name="label" translatable="yes">UI Filename</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
@ -306,98 +304,35 @@
</child>
<child>
<object class="GtkEntry" id="np_ui_entry">
<property name="sensitive">0</property>
<property name="focusable">1</property>
<property name="width-chars">32</property>
<property name="input-purpose">alpha</property>
<property name="input-hints">GTK_INPUT_HINT_LOWERCASE | GTK_INPUT_HINT_NONE</property>
<property name="input-purpose">alpha</property>
<property name="sensitive">0</property>
<property name="width-chars">32</property>
<layout>
<property name="column">1</property>
<property name="row">3</property>
<property name="column-span">3</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</property>
<property name="name">new_project</property>
<property name="title" translatable="yes">New Project</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">workspace</property>
<property name="title" translatable="1">Workspace</property>
<property name="child">
<object class="GtkPaned">
<property name="shrink-end-child">0</property>
<property name="resize-end-child">0</property>
<property name="shrink-start-child">0</property>
<property name="height-request">380</property>
<property name="focusable">1</property>
<property name="start-child">
<object class="GtkPaned">
<property name="shrink-end-child">0</property>
<property name="shrink-start-child">0</property>
<property name="resize-start-child">0</property>
<property name="focusable">1</property>
<property name="start-child">
<object class="GtkBox" id="inspector">
<property name="orientation">vertical</property>
<property name="focusable">1</property>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">1</property>
<property name="focusable">1</property>
<property name="min-content-width">256</property>
<property name="propagate-natural-width">1</property>
<property name="propagate-natural-height">1</property>
<child>
<object class="CmbTreeView" id="tree_view">
<property name="focusable">1</property>
<property name="headers-visible">False</property>
<property name="headers-clickable">False</property>
</object>
</child>
</object>
</child>
</object>
</property>
<property name="end-child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="CmbTypeChooser" id="type_chooser">
<property name="spacing">2</property>
<signal name="chooser-popdown" handler="on_type_chooser_chooser_popdown" swapped="no"/>
<signal name="chooser-popup" handler="on_type_chooser_chooser_popup" swapped="no"/>
<signal name="type-selected" handler="on_type_chooser_type_selected" swapped="no"/>
</object>
</child>
<child>
<object class="CmbView" id="view">
<property name="vexpand">1</property>
<signal name="placeholder-activated" handler="on_view_placeholder_activated" swapped="no"/>
<signal name="placeholder-selected" handler="on_view_placeholder_selected" swapped="no"/>
</object>
</child>
</object>
</property>
</object>
</property>
<property name="end-child">
<object class="GtkStack" id="editor_stack">
<property name="transition-type">crossfade</property>
<child>
<object class="GtkStackPage">
<property name="name">object</property>
<property name="title" translatable="1">Object Editor</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
@ -413,12 +348,10 @@
</child>
<child>
<object class="GtkStack" id="object_stack">
<property name="vexpand">1</property>
<property name="transition-type">crossfade</property>
<property name="vexpand">1</property>
<child>
<object class="GtkStackPage">
<property name="name">properties</property>
<property name="title" translatable="1">Properties</property>
<property name="child">
<object class="CmbScrolledWindow">
<property name="child">
@ -428,12 +361,12 @@
</property>
</object>
</property>
<property name="name">properties</property>
<property name="title" translatable="yes">Properties</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">layout</property>
<property name="title" translatable="1">Layout</property>
<property name="child">
<object class="CmbScrolledWindow">
<property name="child">
@ -443,38 +376,38 @@
</property>
</object>
</property>
<property name="name">layout</property>
<property name="title" translatable="yes">Layout</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="child">
<object class="CmbSignalEditor" id="signal_editor"/>
</property>
<property name="name">signals</property>
<property name="title" translatable="1">Signals</property>
<property name="child">
<object class="CmbSignalEditor" id="signal_editor">
</object>
</property>
<property name="title" translatable="yes">Signals</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">fragment</property>
<property name="title" translatable="0">&lt;/&gt;</property>
<property name="child">
<object class="CmbFragmentEditor" id="fragment_editor">
</object>
<object class="CmbFragmentEditor" id="fragment_editor"/>
</property>
<property name="name">fragment</property>
<property name="title">&lt;/&gt;</property>
</object>
</child>
</object>
</child>
</object>
</property>
<property name="name">object</property>
<property name="title" translatable="yes">Object Editor</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">ui</property>
<property name="title" translatable="1">UI Editor</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
@ -494,116 +427,153 @@
<property name="vexpand">1</property>
<child>
<object class="GtkStackPage">
<property name="name">properties</property>
<property name="title" translatable="1">Properties</property>
<property name="child">
<object class="CmbUIEditor" id="ui_editor">
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<signal name="remove-ui" handler="on_ui_editor_remove_ui" swapped="no"/>
<signal name="remove-ui" handler="on_ui_editor_remove_ui"/>
</object>
</property>
<property name="name">properties</property>
<property name="title" translatable="yes">Properties</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">requires</property>
<property name="title" translatable="1">Requires</property>
<property name="child">
<object class="CmbUIRequiresEditor" id="ui_requires_editor">
<property name="orientation">vertical</property>
</object>
</property>
<property name="name">requires</property>
<property name="title" translatable="yes">Requires</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">fragment</property>
<property name="title" translatable="0">&lt;/&gt;</property>
<property name="child">
<object class="CmbFragmentEditor" id="ui_fragment_editor">
<property name="orientation">vertical</property>
</object>
</property>
<property name="name">fragment</property>
<property name="title">&lt;/&gt;</property>
</object>
</child>
</object>
</child>
</object>
</property>
<property name="name">ui</property>
<property name="title" translatable="yes">UI Editor</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">css</property>
<property name="title" translatable="1">CSS Editor</property>
<property name="child">
<object class="CmbCSSEditor" id="css_editor">
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<signal name="remove-css" handler="on_css_editor_remove_ui" swapped="no"/>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<signal name="remove-css" handler="on_css_editor_remove_ui"/>
</object>
</property>
<property name="name">css</property>
<property name="title" translatable="yes">CSS Editor</property>
</object>
</child>
</object>
</property>
<property name="focusable">1</property>
<property name="height-request">380</property>
<property name="resize-end-child">0</property>
<property name="shrink-end-child">0</property>
<property name="shrink-start-child">0</property>
<property name="start-child">
<object class="GtkPaned">
<property name="end-child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="CmbTypeChooser" id="type_chooser">
<property name="spacing">2</property>
<signal name="chooser-popdown" handler="on_type_chooser_chooser_popdown"/>
<signal name="chooser-popup" handler="on_type_chooser_chooser_popup"/>
<signal name="type-selected" handler="on_type_chooser_type_selected"/>
</object>
</child>
<child>
<object class="CmbView" id="view">
<property name="vexpand">1</property>
<signal name="placeholder-activated" handler="on_view_placeholder_activated"/>
<signal name="placeholder-selected" handler="on_view_placeholder_selected"/>
</object>
</child>
</object>
</property>
<property name="focusable">1</property>
<property name="resize-start-child">0</property>
<property name="shrink-end-child">0</property>
<property name="shrink-start-child">0</property>
<property name="start-child">
<object class="GtkBox" id="inspector">
<property name="focusable">1</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="focusable">1</property>
<property name="min-content-width">256</property>
<property name="propagate-natural-height">1</property>
<property name="propagate-natural-width">1</property>
<property name="vexpand">1</property>
<child>
<object class="CmbTreeView" id="tree_view">
<property name="focusable">1</property>
<property name="headers-clickable">False</property>
<property name="headers-visible">False</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
</property>
<property name="name">workspace</property>
<property name="title" translatable="yes">Workspace</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">donate</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<style>
<class name="donate"/>
</style>
<child>
<object class="GtkButton">
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="halign">start</property>
<property name="action-name">win.show_workspace</property>
<style>
<class name="borderless"/>
</style>
<property name="focusable">1</property>
<property name="halign">start</property>
<property name="receives-default">1</property>
<child>
<object class="GtkImage">
<property name="icon-name">go-previous-symbolic</property>
</object>
</child>
<style>
<class name="borderless"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">start</property>
<property name="margin-top">32</property>
<property name="margin-bottom">64</property>
<property name="spacing">196</property>
<property name="homogeneous">1</property>
<property name="margin-bottom">64</property>
<property name="margin-top">32</property>
<property name="spacing">196</property>
<property name="valign">start</property>
<property name="vexpand">1</property>
<child>
<object class="GtkBox">
<property name="halign">center</property>
@ -620,7 +590,7 @@
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="1">• Liberapay is a recurrent donations platform
<property name="label" translatable="yes">• Liberapay is a recurrent donations platform
• Run by a non-profit organization
@ -633,11 +603,11 @@
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="1">Donate</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="halign">center</property>
<property name="action-name">win.liberapay</property>
<property name="focusable">1</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Donate</property>
<property name="receives-default">1</property>
<style>
<class name="suggested-action"/>
</style>
@ -661,7 +631,7 @@
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="1">• Patreon is a membership platform for creators
<property name="label" translatable="yes">• Patreon is a membership platform for creators
• Run by private company
@ -674,28 +644,29 @@
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="1">Donate</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="halign">center</property>
<property name="action-name">win.patreon</property>
<property name="focusable">1</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Donate</property>
<property name="receives-default">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="donate"/>
</style>
</object>
</property>
<property name="name">donate</property>
</object>
</child>
</object>
</property>
<child type="overlay">
<object class="GtkRevealer" id="message_revealer">
<property name="halign">center</property>
<property name="valign">end</property>
<property name="transition-type">slide-up</property>
<property name="child">
<object class="GtkLabel" id="message_label">
<style>
@ -703,6 +674,9 @@
</style>
</object>
</property>
<property name="halign">center</property>
<property name="transition-type">slide-up</property>
<property name="valign">end</property>
<style>
<class name="message"/>
</style>
@ -717,7 +691,7 @@
<property name="orientation">GTK_ORIENTATION_VERTICAL</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="1">Cambalache</property>
<property name="label" translatable="yes">Cambalache</property>
<property name="vexpand">true</property>
<style>
<class name="title"/>
@ -737,8 +711,8 @@
<child type="end">
<object class="GtkMenuButton" id="menu_button">
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="menu-model">main_menu</property>
<property name="receives-default">1</property>
<child>
<object class="GtkImage">
<property name="icon-name">open-menu-symbolic</property>
@ -748,16 +722,13 @@
</child>
<child>
<object class="GtkBox" id="open_button_box">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="open_button">
<property name="label" translatable="1">_Open</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="tooltip-text" translatable="1">Open a project</property>
<property name="action-name">win.open</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">_Open</property>
<property name="receives-default">1</property>
<property name="tooltip-text" translatable="yes">Open a project</property>
<property name="use-underline">1</property>
</object>
</child>
@ -771,15 +742,17 @@
</child>
</object>
</child>
<style>
<class name="linked"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="new_button">
<property name="action-name">win.create_new</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="tooltip-text" translatable="1">Create a new project</property>
<property name="action-name">win.create_new</property>
<property name="tooltip-text" translatable="yes">Create a new project</property>
<child>
<object class="GtkImage">
<property name="icon-name">document-new-symbolic</property>
@ -789,20 +762,17 @@
</child>
<child type="end">
<object class="GtkBox" id="save_button_box">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="cmb_save_button">
<property name="label" translatable="1">Save</property>
<property name="tooltip-text" translatable="1">Save project</property>
<property name="action-name">win.save</property>
<property name="label" translatable="yes">Save</property>
<property name="tooltip-text" translatable="yes">Save project</property>
</object>
</child>
<child>
<object class="GtkButton" id="save_as_button">
<property name="tooltip-text" translatable="1">Save project with a different file name</property>
<property name="action-name">win.save_as</property>
<property name="tooltip-text" translatable="yes">Save project with a different file name</property>
<child>
<object class="GtkImage">
<property name="icon-name">document-save-as-symbolic</property>
@ -810,6 +780,9 @@
</child>
</object>
</child>
<style>
<class name="linked"/>
</style>
</object>
</child>
<child>
@ -817,8 +790,8 @@
</child>
<child type="end">
<object class="GtkButton" id="add_button">
<property name="tooltip-text" translatable="1">Add new UI to project</property>
<property name="action-name">win.add_ui</property>
<property name="tooltip-text" translatable="yes">Add new UI to project</property>
<child>
<object class="GtkImage">
<property name="icon-name">list-add-symbolic</property>
@ -828,8 +801,8 @@
</child>
<child type="end">
<object class="GtkButton" id="intro_button">
<property name="tooltip-text" translatable="1">Start interactive introduction</property>
<property name="action-name">win.intro</property>
<property name="tooltip-text" translatable="yes">Start interactive introduction</property>
<child>
<object class="GtkImage">
<property name="icon-name">start-here-symbolic</property>
@ -839,14 +812,11 @@
</child>
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton" id="undo_button">
<property name="action-name">win.undo</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="action-name">win.undo</property>
<child>
<object class="GtkImage">
<property name="icon-name">edit-undo-symbolic</property>
@ -856,9 +826,9 @@
</child>
<child>
<object class="GtkButton" id="redo_button">
<property name="action-name">win.redo</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="action-name">win.redo</property>
<property name="use-underline">1</property>
<child>
<object class="GtkImage">
@ -867,22 +837,28 @@
</child>
</object>
</child>
<style>
<class name="linked"/>
</style>
</object>
</child>
</object>
</child>
<style>
<class name="cmb-window"/>
</style>
</template>
<object class="GtkAboutDialog" id="about_dialog">
<property name="transient-for">CmbWindow</property>
<property name="program-name">Cambalache</property>
<property name="copyright">© 2020-2024 Juan Pablo Ugarte</property>
<property name="comments" translatable="1">User Interface Maker</property>
<property name="website">https://gitlab.gnome.org/jpu/cambalache</property>
<property name="website-label" translatable="1">Source repository and issue tracker</property>
<property name="authors">Juan Pablo Ugarte</property>
<property name="artists">Franco Dodorico
Juan Pablo Ugarte</property>
<property name="logo-icon-name">ar.xjuan.Cambalache</property>
<property name="authors">Juan Pablo Ugarte</property>
<property name="comments" translatable="yes">User Interface Maker</property>
<property name="copyright">© 2020-2024 Juan Pablo Ugarte</property>
<property name="license-type">lgpl-2-1-only</property>
<property name="logo-icon-name">ar.xjuan.Cambalache</property>
<property name="program-name">Cambalache</property>
<property name="transient-for">CmbWindow</property>
<property name="website">https://gitlab.gnome.org/jpu/cambalache</property>
<property name="website-label" translatable="yes">Source repository and issue tracker</property>
</object>
</interface>

View File

@ -1,41 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_context_menu.ui -->
<requires lib="gtk" version="4.0"/>
<requires lib="gio" version="2.0"/>
<menu id="menu_model">
<section>
<item>
<attribute name="action">win.cut</attribute>
<attribute name="label" translatable="1">Cut</attribute>
<attribute name="label" translatable="yes">Cut</attribute>
</item>
<item>
<attribute name="action">win.copy</attribute>
<attribute name="label" translatable="1">Copy</attribute>
<attribute name="label" translatable="yes">Copy</attribute>
</item>
<item>
<attribute name="action">win.paste</attribute>
<attribute name="label" translatable="1">Paste</attribute>
<attribute name="label" translatable="yes">Paste</attribute>
</item>
<item>
<attribute name="action">win.delete</attribute>
<attribute name="label" translatable="1">Delete</attribute>
<attribute name="label" translatable="yes">Delete</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.add_object</attribute>
<attribute name="label" translatable="1">Add object here</attribute>
<attribute name="label" translatable="yes">Add object here</attribute>
</item>
<item>
<attribute name="action">win.add_object_toplevel</attribute>
<attribute name="label" translatable="1">Add object as toplevel</attribute>
<attribute name="label" translatable="yes">Add object as toplevel</attribute>
</item>
<item>
<attribute name="action">win.clear</attribute>
<attribute name="label" translatable="1">Clear Properties</attribute>
<attribute name="label" translatable="yes">Clear Properties</attribute>
</item>
<item>
<attribute name="action">win.documentation</attribute>
<attribute name="label" translatable="1">Read Documentation</attribute>
<attribute name="label" translatable="yes">Read Documentation</attribute>
</item>
</section>
<section id="main_section"/>

View File

@ -22,8 +22,8 @@
#
from gi.repository import GObject, Gtk
from cambalache import utils, _
from .cmb_css import CmbCSS
from . import utils
@Gtk.Template(resource_path="/ar/xjuan/Cambalache/cmb_css_editor.ui")
@ -34,6 +34,7 @@ class CmbCSSEditor(Gtk.Grid):
priority = Gtk.Template.Child()
is_global = Gtk.Template.Child()
ui_menu_button = Gtk.Template.Child()
ui_box = Gtk.Template.Child()
infobar = Gtk.Template.Child()
save_button = Gtk.Template.Child()
@ -102,6 +103,7 @@ class CmbCSSEditor(Gtk.Grid):
obj.connect("file-changed", self.__on_file_changed)
self.__update_provider_for()
self.__update_ui_button_label()
@Gtk.Template.Callback("on_remove_button_clicked")
def __on_remove_button_clicked(self, button):
@ -153,6 +155,27 @@ class CmbCSSEditor(Gtk.Grid):
else:
self.object.remove_ui(ui)
self.__update_ui_button_label()
def __update_ui_button_label(self):
n = 0
first_one = None
child = self.ui_box.get_first_child()
while child is not None:
if child.props.active:
n += 1
if first_one is None:
first_one = child
child = child.get_next_sibling()
if first_one is None:
self.ui_menu_button.props.label = _("None")
else:
self.ui_menu_button.props.label = f"{first_one.props.label} + {n - 1}" if n > 1 else first_one.props.label
def __on_ui_added_removed(self, project, ui):
self.__update_provider_for()

View File

@ -1,13 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_css_editor.ui -->
<requires lib="gtk" version="4.0"/>
<template class="CmbCSSEditor" parent="GtkGrid">
<property name="row-spacing">4</property>
<property name="column-spacing">3</property>
<property name="row-spacing">4</property>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Filename:</property>
<property name="label" translatable="yes">Filename:</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
@ -17,7 +19,7 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Priority:</property>
<property name="label" translatable="yes">Priority:</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
@ -26,9 +28,9 @@
</child>
<child>
<object class="GtkLabel">
<property name="tooltip-text" translatable="1">This provider will be used in all UI.</property>
<property name="halign">start</property>
<property name="label" translatable="1">Global:</property>
<property name="label" translatable="yes">Global:</property>
<property name="tooltip-text" translatable="yes">This provider will be used in all UI.</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
@ -37,16 +39,43 @@
</child>
<child>
<object class="CmbEntry" id="filename">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="placeholder-text" translatable="1">&lt;file name relative to project&gt;</property>
<property name="placeholder-text" translatable="yes">&lt;file name relative to project&gt;</property>
<property name="visible">True</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkMenuButton" id="ui_menu_button">
<property name="halign">start</property>
<property name="popover">
<object class="GtkPopover">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="propagate-natural-height">True</property>
<property name="propagate-natural-width">True</property>
<child>
<object class="GtkBox" id="ui_box">
<property name="orientation">vertical</property>
</object>
</child>
</object>
</child>
</object>
</property>
<layout>
<property name="column">1</property>
<property name="column-span">1</property>
<property name="row">3</property>
<property name="row-span">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="priority">
<property name="focusable">1</property>
@ -67,30 +96,11 @@
</layout>
</object>
</child>
<child>
<object class="GtkBox" id="ui_box">
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="tooltip-text" translatable="1">List of UI where this provider will be used</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="label" translatable="1">Provider for:</property>
<property name="label" translatable="yes">Provider for:</property>
<property name="tooltip-text" translatable="yes">List of UI where this provider will be used</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
@ -103,11 +113,10 @@
<child>
<object class="GtkButton" id="remove_button">
<property name="focusable">1</property>
<!-- <property name="receives-default">1</property> -->
<!-- <property name="tooltip-text" translatable="1">Remove CSS file from project</property> -->
<property name="halign">start</property>
<property name="valign">end</property>
<signal name="clicked" handler="on_remove_button_clicked" swapped="no"/>
<signal name="clicked" handler="on_remove_button_clicked"/>
<child>
<object class="GtkImage">
<property name="icon-name">app-remove-symbolic</property>
@ -118,21 +127,21 @@
<child>
<object class="GtkLabel">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="label" translatable="1">&lt;small&gt;Note: CSS files need to be loaded at runtime&lt;/small&gt;</property>
<property name="label" translatable="yes">&lt;small&gt;Note: CSS files need to be loaded at runtime&lt;/small&gt;</property>
<property name="use-markup">1</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkButton" id="save_button">
<property name="sensitive">0</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="tooltip-text" translatable="1">Save CSS file</property>
<property name="hexpand">True</property>
<property name="halign">end</property>
<property name="hexpand">True</property>
<property name="receives-default">1</property>
<property name="sensitive">0</property>
<property name="tooltip-text" translatable="yes">Save CSS file</property>
<property name="valign">end</property>
<signal name="clicked" handler="on_save_button_clicked" swapped="no"/>
<signal name="clicked" handler="on_save_button_clicked"/>
<child>
<object class="GtkImage">
<property name="icon-name">document-save-symbolic</property>
@ -142,8 +151,8 @@
</child>
<layout>
<property name="column">0</property>
<property name="row">5</property>
<property name="column-span">2</property>
<property name="row">5</property>
</layout>
</object>
</child>
@ -155,17 +164,17 @@
<child>
<object class="GtkInfoBar" id="infobar">
<property name="message-type">warning</property>
<property name="show-close-button">1</property>
<property name="revealed">0</property>
<signal name="response" handler="on_infobar_response" swapped="no"/>
<property name="show-close-button">1</property>
<signal name="response" handler="on_infobar_response"/>
<child type="action">
<object class="GtkButton" id="reload_button">
<property name="label" translatable="1">Reload</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="halign">start</property>
<property name="valign">end</property>
</object>
<object class="GtkButton" id="reload_button">
<property name="focusable">1</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Reload</property>
<property name="receives-default">1</property>
<property name="valign">end</property>
</object>
</child>
<child>
<object class="GtkBox">
@ -175,14 +184,12 @@
<object class="GtkLabel">
<property name="halign">start</property>
<property name="hexpand">1</property>
<property name="label" translatable="1">The file changed on disk.</property>
<property name="label" translatable="yes">The file changed on disk.</property>
</object>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">reload_button</action-widget>
</action-widgets>
<!-- Custom object fragments -->
</object>
</child>
<child>
@ -191,22 +198,21 @@
<property name="vexpand">1</property>
<child>
<object class="CmbSourceView" id="view">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="lang">css</property>
<property name="visible">True</property>
</object>
</child>
</object>
</child>
</object>
</property>
<child type="label_item">
<placeholder/>
</child>
<property name="vexpand">True</property>
<property name="vexpand-set">True</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
<property name="column-span">2</property>
<property name="row">4</property>
</layout>
</object>
</child>

View File

@ -473,6 +473,9 @@ class CmbDB(GObject.GObject):
if version < (0, 13, 1):
data = cmb_db_migration.ensure_columns_for_0_13_1(table, data)
if version < (0, 17, 3):
data = cmb_db_migration.ensure_columns_for_0_17_3(table, data)
return data
def __migrate_table_data(self, c, version, table, data):
@ -844,14 +847,30 @@ class CmbDB(GObject.GObject):
knowns = []
retval = []
def get_key_val(node, attr):
tokens = attr.split(":")
key = tokens[0]
val = node.get(key, None)
if len(tokens) > 1:
t = tokens[1]
if t == "bool":
return (key, val.lower() in {"1", "t", "y", "true", "yes"} if val else False)
elif t == "int":
return (key, int(val))
return (key, val)
for attr in args:
if isinstance(attr, list):
for opt in attr:
retval.append(node.get(opt, None))
knowns.append(opt)
key, val = get_key_val(node, opt)
retval.append(val)
knowns.append(key)
elif attr in keys:
retval.append(node.get(attr))
knowns.append(attr)
key, val = get_key_val(node, attr)
retval.append(val)
knowns.append(key)
else:
self.__collect_error("missing-attr", node, attr)
@ -865,21 +884,46 @@ class CmbDB(GObject.GObject):
def __get_property_info(self, info, property_id):
pinfo = None
debug = info.type_id == "CmbFragmentEditor"
if debug:
print(info.properties, info.interfaces, property_id)
# Find owner type for property
if property_id in info.properties:
pinfo = info.properties[property_id]
else:
# Search in interfaces properties
for iface in info.interfaces:
iface_info = self.type_info[iface]
if property_id in iface_info.properties:
pinfo = iface_info.properties[property_id]
break
for parent in info.hierarchy:
type_info = self.type_info[parent]
# Search in parent properties
if property_id in type_info.properties:
pinfo = type_info.properties[property_id]
# Search in parent interfaces properties
for iface in type_info.interfaces:
iface_info = self.type_info[iface]
if property_id in iface_info.properties:
pinfo = iface_info.properties[property_id]
break
if pinfo is not None:
break
return pinfo
def __import_property(self, c, info, ui_id, object_id, prop, object_id_map=None):
name, translatable, context, comments, bind_source_id, bind_property_id, bind_flags = self.__node_get(
prop, "name", ["translatable", "context", "comments", "bind-source", "bind-property", "bind-flags"]
prop, "name", ["translatable:bool", "context", "comments", "bind-source", "bind-property", "bind-flags"]
)
property_id = name.replace("_", "-")
@ -899,15 +943,14 @@ class CmbDB(GObject.GObject):
inline_object_id = None
# GtkBuilder in Gtk4 supports defining an object in a property
if self.target_tk == "gtk-4.0" and pinfo.is_object:
obj_node = prop.find("object")
if self.target_tk == "gtk-4.0" and pinfo.is_object and obj_node is not None:
if pinfo.disable_inline_object:
self.__collect_error("not-inline-object", prop, f"{info.type_id}:{property_id}")
return
obj_node = prop.find("object")
if obj_node is not None:
inline_object_id = self.__import_object(ui_id, obj_node, object_id)
value = None
inline_object_id = self.__import_object(ui_id, obj_node, object_id)
value = None
# Need to remap object ids on paste
if object_id_map and pinfo.is_object:
@ -949,7 +992,7 @@ class CmbDB(GObject.GObject):
user_data,
swap,
after,
) = self.__node_get(signal, "name", ["handler", "object", "swapped", "after"])
) = self.__node_get(signal, "name", ["handler", "object", "swapped:bool", "after:bool"])
tokens = name.split("::")
@ -1000,6 +1043,8 @@ class CmbDB(GObject.GObject):
object_id = None
packing = None
custom_fragments = []
for node in child.iterchildren():
if node.tag == "object":
object_id = self.__import_object(ui_id, node, parent_id, internal, ctype, object_id_map=object_id_map)
@ -1009,12 +1054,18 @@ class CmbDB(GObject.GObject):
elif node.tag == "placeholder":
# Ignore placeholder tags
pass
elif node.tag is etree.Comment:
pass
else:
self.__unknown_tag(node, ctype, node.tag)
custom_fragments.append(node)
if packing is not None and object_id:
self.__import_layout_properties(c, info, ui_id, parent_id, object_id, packing)
fragment = self.__custom_fragments_tostring(custom_fragments)
if fragment and object_id is not None:
c.execute("UPDATE object SET custom_child_fragment=? WHERE ui_id=? AND object_id=?", (fragment, ui_id, object_id))
def __get_layout_property_owner(self, type_id, property_id):
info = self.type_info.get(type_id, None)
@ -1044,7 +1095,7 @@ class CmbDB(GObject.GObject):
self.__unknown_tag(prop, parent_id, prop.tag)
continue
name, translatable, context, comments = self.__node_get(prop, "name", ["translatable", "context", "comments"])
name, translatable, context, comments = self.__node_get(prop, "name", ["translatable:bool", "context", "comments"])
property_id = name.replace("_", "-")
comment = self.__node_get_comment(prop)
owner_id = self.__get_layout_property_owner(parent_type[0], property_id)
@ -1139,7 +1190,7 @@ class CmbDB(GObject.GObject):
comment = self.__node_get_comment(ntag)
if taginfo.translatable:
translatable, context, comments = self.__node_get(ntag, ["translatable", "context", "comments"])
translatable, context, comments = self.__node_get(ntag, ["translatable:bool", "context", "comments"])
else:
translatable, context, comments = (None, None, None)
@ -1303,7 +1354,6 @@ class CmbDB(GObject.GObject):
self.__import_object_data(ui_id, object_id, taginfo.owner_id, taginfo, child, None)
else:
custom_fragments.append(child)
# self.__unknown_tag(child, klass, child.tag)
fragment = self.__custom_fragments_tostring(custom_fragments)
if fragment:
@ -1573,12 +1623,13 @@ class CmbDB(GObject.GObject):
if type_id == GMENU_TYPE:
obj = E.menu()
# Only menu has id
self.__node_set(obj, "id", f"__cmb__{ui_id}.{object_id}" if merengue else name)
elif type_id == GMENU_SECTION_TYPE:
obj = E.section()
self.__node_set(obj, "id", f"__cmb__{ui_id}.{object_id}" if merengue else name)
elif type_id == GMENU_SUBMENU_TYPE:
obj = E.submenu()
self.__node_set(obj, "id", f"__cmb__{ui_id}.{object_id}" if merengue else name)
elif type_id == GMENU_ITEM_TYPE:
obj = E.item()
else:
@ -1764,7 +1815,6 @@ class CmbDB(GObject.GObject):
# From now own all output should be without an ID
# because we do not want so select internal widget from the template
ignore_id = True
self.__node_set(obj, "id", name)
elif not ignore_id:
self.__node_set(obj, "id", f"__cmb__{ui_id}.{object_id}")
else:
@ -1918,7 +1968,7 @@ class CmbDB(GObject.GObject):
# Children
for row in c.execute(
"""
SELECT object_id, internal, type, comment, position
SELECT object_id, internal, type, comment, position, custom_child_fragment
FROM object
WHERE ui_id=? AND parent_id=? AND
object_id NOT IN (SELECT inline_object_id FROM object_property
@ -1927,7 +1977,7 @@ class CmbDB(GObject.GObject):
""",
(ui_id, object_id, ui_id, object_id),
):
child_id, internal, ctype, comment, position = row
child_id, internal, ctype, comment, position, custom_child_fragment = row
if merengue:
position = position if position is not None else 0
@ -1948,35 +1998,37 @@ class CmbDB(GObject.GObject):
obj.append(child)
if linfo is None:
continue
if linfo is not None:
# Packing / Layout
layout = E("packing" if self.target_tk == "gtk+-3.0" else "layout")
for prop in cc.execute(
f"""
SELECT value, property_id, comment
FROM object_layout_property
WHERE ui_id=? AND object_id=? AND child_id=?
UNION
SELECT default_value AS value, property_id, null
FROM property
WHERE save_always=1 AND owner_id IN ({placeholders}) AND property_id NOT IN
(SELECT property_id FROM object_layout_property WHERE ui_id=? AND object_id=? AND child_id=?)
ORDER BY property_id
""",
(ui_id, object_id, child_id) + tuple(hierarchy) + (ui_id, object_id, child_id),
):
value, property_id, comment = prop
node = E.property(value, name=property_id)
layout.append(node)
self.__node_add_comment(node, comment)
# Packing / Layout
layout = E("packing" if self.target_tk == "gtk+-3.0" else "layout")
for prop in cc.execute(
f"""
SELECT value, property_id, comment
FROM object_layout_property
WHERE ui_id=? AND object_id=? AND child_id=?
UNION
SELECT default_value AS value, property_id, null
FROM property
WHERE save_always=1 AND owner_id IN ({placeholders}) AND property_id NOT IN
(SELECT property_id FROM object_layout_property WHERE ui_id=? AND object_id=? AND child_id=?)
ORDER BY property_id
""",
(ui_id, object_id, child_id) + tuple(hierarchy) + (ui_id, object_id, child_id),
):
value, property_id, comment = prop
node = E.property(value, name=property_id)
layout.append(node)
self.__node_add_comment(node, comment)
if len(layout) > 0:
if self.target_tk == "gtk+-3.0":
child.append(layout)
else:
child_obj.append(layout)
if len(layout) > 0:
if self.target_tk == "gtk+-3.0":
child.append(layout)
else:
child_obj.append(layout)
if custom_child_fragment is not None:
# Dump custom child fragments
self.__export_custom_fragment(child, custom_child_fragment)
# Custom buildable tags
# Iterate over all hierarchy extra data
@ -2002,7 +2054,7 @@ class CmbDB(GObject.GObject):
except Exception:
pass
else:
node.append(etree.Comment(" Custom fragments "))
node.append(etree.Comment(f" Custom {node.tag} fragments "))
for child in root:
node.append(child)

View File

@ -102,3 +102,11 @@ def ensure_columns_for_0_13_1(table, data):
return [row + (None, None, None) for row in data]
return data
def ensure_columns_for_0_17_3(table, data):
if table == "object":
# Append custom_child_fragment column
return [row + (None,) for row in data]
return data

View File

@ -22,6 +22,7 @@
#
from gi.repository import GObject, Gtk
from .cmb_object import CmbObject
@Gtk.Template(resource_path="/ar/xjuan/Cambalache/cmb_fragment_editor.ui")
@ -29,10 +30,12 @@ class CmbFragmentEditor(Gtk.Box):
__gtype_name__ = "CmbFragmentEditor"
view = Gtk.Template.Child()
child_view = Gtk.Template.Child()
switcher = Gtk.Template.Child()
def __init__(self, **kwargs):
self._object = None
self.__binding = None
self.__bindings = []
super().__init__(**kwargs)
@ -45,9 +48,10 @@ class CmbFragmentEditor(Gtk.Box):
if obj == self._object:
return
if self.__binding:
self.__binding.unbind()
self.__binding = None
for binding in self.__bindings:
binding.unbind()
self.__bindings = []
self._object = obj
@ -61,7 +65,20 @@ class CmbFragmentEditor(Gtk.Box):
"text",
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
)
self.__binding = binding
self.__bindings.append(binding)
# Only objects have child fragments
if type(obj) == CmbObject and obj.parent is not None:
binding = GObject.Object.bind_property(
obj,
"custom-child-fragment",
self.child_view,
"text",
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
)
self.__bindings.append(binding)
self.switcher.set_visible(True)
Gtk.WidgetClass.set_css_name(CmbFragmentEditor, "CmbFragmentEditor")

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_fragment_editor.ui -->
<requires lib="gtk" version="4.0"/>
<template class="CmbFragmentEditor" parent="GtkBox">
<property name="orientation">vertical</property>
@ -7,21 +9,52 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Extra fragments:</property>
<property name="label" translatable="yes">Extra fragments:</property>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">1</property>
<property name="focusable">1</property>
<object class="GtkStack" id="fragment_stack">
<property name="vexpand">True</property>
<child>
<object class="CmbSourceView" id="view">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="lang">xml</property>
<object class="GtkStackPage">
<property name="child">
<object class="GtkScrolledWindow">
<child>
<object class="CmbSourceView" id="view">
<property name="can-focus">True</property>
<property name="lang">xml</property>
</object>
</child>
</object>
</property>
<property name="name">fragment</property>
<property name="title" translatable="yes">Fragment</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="child">
<object class="GtkScrolledWindow">
<child>
<object class="CmbSourceView" id="child_view">
<property name="can-focus">True</property>
<property name="lang">xml</property>
</object>
</child>
</object>
</property>
<property name="name">child_fragment</property>
<property name="title" translatable="yes">Child Fragment</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStackSwitcher" id="switcher">
<property name="halign">center</property>
<property name="stack">fragment_stack</property>
<property name="visible">False</property>
</object>
</child>
</template>
</interface>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_object_data_editor.ui -->
<requires lib="gtk" version="4.0"/>
<template class="CmbObjectDataEditor" parent="GtkBox">
<property name="orientation">vertical</property>
@ -8,28 +10,27 @@
<object class="GtkBox">
<property name="spacing">4</property>
<child>
<object class="GtkLabel" id="label">
</object>
<object class="GtkLabel" id="label"/>
</child>
<child>
<object class="GtkBox" id="top_box">
<property name="hexpand">True</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="remove_button">
<property name="focusable">1</property>
<property name="halign">end</property>
<style>
<class name="borderless"/>
</style>
<signal name="clicked" handler="on_remove_clicked" swapped="no"/>
<signal name="clicked" handler="on_remove_clicked"/>
<child>
<object class="GtkImage">
<property name="icon-name">user-trash-symbolic</property>
</object>
</child>
<style>
<class name="borderless"/>
</style>
<style>
<class name="hidden"/>
</style>
@ -37,8 +38,8 @@
</child>
<child>
<object class="GtkMenuButton" id="add_child">
<property name="visible">0</property>
<property name="halign">end</property>
<property name="visible">0</property>
<child>
<object class="GtkImage">
<property name="icon-name">list-add-symbolic</property>
@ -48,33 +49,27 @@
</child>
<child>
<object class="GtkButton" id="add_only_child">
<property name="visible">0</property>
<property name="focusable">1</property>
<property name="halign">end</property>
<signal name="clicked" handler="on_add_only_child_clicked" swapped="no"/>
<style>
<class name="borderless"/>
</style>
<property name="visible">0</property>
<signal name="clicked" handler="on_add_only_child_clicked"/>
<child>
<object class="GtkImage">
<property name="icon-name">list-add-symbolic</property>
</object>
</child>
<style>
<class name="borderless"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkGrid" id="grid">
<property name="vexpand">1</property>
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<property name="row-spacing">4</property>
<property name="vexpand">1</property>
</object>
</child>
</template>

View File

@ -976,7 +976,21 @@ class CmbBaseObject(CmbBase):
super().__init__(**kwargs)
@classmethod
def from_row(cls, project, ui_id, object_id, type_id, name, parent_id, internal, type, comment, position, custom_fragment):
def from_row(
cls,
project,
ui_id,
object_id,
type_id,
name,
parent_id,
internal,
type,
comment,
position,
custom_fragment,
custom_child_fragment,
):
return cls(project=project, ui_id=ui_id, object_id=object_id)
@GObject.Property(type=str)
@ -1147,6 +1161,27 @@ class CmbBaseObject(CmbBase):
value,
)
@GObject.Property(type=str)
def custom_child_fragment(self):
return self.db_get(
"SELECT custom_child_fragment FROM object WHERE (ui_id, object_id) IS (?, ?);",
(
self.ui_id,
self.object_id,
),
)
@custom_child_fragment.setter
def _set_custom_child_fragment(self, value):
self.db_set(
"UPDATE object SET custom_child_fragment=? WHERE (ui_id, object_id) IS (?, ?);",
(
self.ui_id,
self.object_id,
),
value,
)
class CmbBaseObjectData(CmbBase):
__gtype_name__ = "CmbBaseObjectData"

View File

@ -31,6 +31,7 @@ from lxml import etree
from .cmb_db import CmbDB
from .cmb_ui import CmbUI
from .cmb_css import CmbCSS
from .cmb_base import CmbBase
from .cmb_object import CmbObject
from .cmb_object_data import CmbObjectData
from .cmb_property import CmbProperty
@ -119,7 +120,7 @@ class CmbProject(Gtk.TreeStore):
raise Exception("Either target_tk or filename are required")
# Use a TreeStore to hold object tree instead of using SQL for every TreeStore call
self.set_column_types([GObject.GObject])
self.set_column_types([CmbBase])
# DataModel is only used internally
self.db = CmbDB(target_tk=self.target_tk)
@ -586,6 +587,7 @@ class CmbProject(Gtk.TreeStore):
comment=None,
position=0,
custom_fragment=None,
custom_child_fragment=None,
):
obj = CmbObject(project=self, ui_id=ui_id, object_id=object_id, info=self.type_info[obj_type])
@ -1452,8 +1454,9 @@ class CmbProject(Gtk.TreeStore):
iter = self.iter_next(iter)
# GtkTreeDragDest Iface
def do_drag_data_received(self, path, selection_data):
valid, _model, drag_path = Gtk.tree_get_row_drag_data(selection_data)
def do_drag_data_received(self, dest, value):
value = GObject.Value(Gtk.TreeRowData, value)
valid, _model, drag_path = Gtk.tree_get_row_drag_data(value)
if not valid:
return False
@ -1463,12 +1466,12 @@ class CmbProject(Gtk.TreeStore):
# Move to new place
try:
iter = self.get_iter(path)
self.move_before(drag_iter, iter)
iter = self.get_iter(dest)
drag_iter = self.insert_before(None, iter, [self[drag_iter][0]])
except ValueError:
path.prev()
iter = self.get_iter(path)
self.move_after(drag_iter, iter)
dest.prev()
iter = self.get_iter(dest)
drag_iter = self.insert_before(None, iter, [self[drag_iter][0]])
position_path = self.get_path(drag_iter)
@ -1482,15 +1485,17 @@ class CmbProject(Gtk.TreeStore):
drag_obj.parent.reorder_child(drag_obj, indices[-1])
self.__reordering_children = False
# Manually emmit signal since we disable it by setting __reordering_children flag
# Manually emit signal since we disable it by setting __reordering_children flag
self.emit("object-changed", drag_obj, "position")
self.set_selection([])
self.set_selection([drag_obj])
return False
return True
def do_row_drop_possible(self, path, selection_data):
valid, _model, drag_path = Gtk.tree_get_row_drag_data(selection_data)
def do_row_drop_possible(self, path, value):
value = GObject.Value(Gtk.TreeRowData, value)
valid, _model, drag_path = Gtk.tree_get_row_drag_data(value)
if not valid:
return False

View File

@ -1,9 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_signal_editor.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkEntryCompletion" id="handler_entrycompletion">
<child>
<object class="GtkCellRendererText"/>
<!-- Custom child fragments -->
<attributes>
<attribute name="text">0</attribute>
</attributes>
@ -28,8 +31,6 @@
<property name="spacing">4</property>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">1</property>
<property name="focusable">1</property>
<property name="child">
<object class="GtkTreeView" id="treeview">
<property name="focusable">1</property>
@ -40,13 +41,14 @@
</child>
<child>
<object class="GtkTreeViewColumn" id="signal_id_column">
<property name="resizable">1</property>
<property name="min-width">64</property>
<property name="title" translatable="1">Signal</property>
<property name="resizable">1</property>
<property name="title" translatable="yes">Signal</property>
<child>
<object class="GtkCellRendererText" id="signal_id">
<signal name="edited" handler="on_detail_edited" swapped="no"/>
<signal name="edited" handler="on_detail_edited"/>
</object>
<!-- Custom child fragments -->
<attributes>
<attribute name="text">2</attribute>
</attributes>
@ -55,16 +57,17 @@
</child>
<child>
<object class="GtkTreeViewColumn" id="handler_column">
<property name="resizable">1</property>
<property name="min-width">64</property>
<property name="title" translatable="1">Handler</property>
<property name="expand">1</property>
<property name="min-width">64</property>
<property name="resizable">1</property>
<property name="title" translatable="yes">Handler</property>
<child>
<object class="GtkCellRendererText" id="handler">
<property name="editable">1</property>
<property name="placeholder-text">&lt;Enter callback&gt;</property>
<signal name="edited" handler="on_handler_edited" swapped="no"/>
<signal name="edited" handler="on_handler_edited"/>
</object>
<!-- Custom child fragments -->
<attributes>
<attribute name="text">4</attribute>
</attributes>
@ -73,13 +76,14 @@
</child>
<child>
<object class="GtkTreeViewColumn" id="user_data_column">
<property name="title" translatable="1">Data</property>
<property name="title" translatable="yes">Data</property>
<child>
<object class="GtkCellRendererText" id="user_data">
<property name="editable">1</property>
<property name="placeholder-text">&lt;object&gt;</property>
<signal name="edited" handler="on_user_data_edited" swapped="no"/>
<signal name="edited" handler="on_user_data_edited"/>
</object>
<!-- Custom child fragments -->
<attributes>
<attribute name="text">5</attribute>
</attributes>
@ -88,11 +92,12 @@
</child>
<child>
<object class="GtkTreeViewColumn" id="swap_column">
<property name="title" translatable="1">Swap</property>
<property name="title" translatable="yes">Swap</property>
<child>
<object class="GtkCellRendererToggle" id="swap">
<signal name="toggled" handler="on_swap_toggled" swapped="no"/>
<signal name="toggled" handler="on_swap_toggled"/>
</object>
<!-- Custom child fragments -->
<attributes>
<attribute name="active">6</attribute>
</attributes>
@ -101,11 +106,12 @@
</child>
<child>
<object class="GtkTreeViewColumn" id="after_column">
<property name="title" translatable="1">After</property>
<property name="title" translatable="yes">After</property>
<child>
<object class="GtkCellRendererToggle" id="after">
<signal name="toggled" handler="on_after_toggled" swapped="no"/>
<signal name="toggled" handler="on_after_toggled"/>
</object>
<!-- Custom child fragments -->
<attributes>
<attribute name="active">7</attribute>
</attributes>
@ -114,6 +120,8 @@
</child>
</object>
</property>
<property name="focusable">1</property>
<property name="vexpand">1</property>
</object>
</child>
</template>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_type_chooser.ui -->
<requires lib="gtk" version="4.0"/>
<object class="CmbTypeChooserPopover" id="all">
<property name="show-categories">True</property>
@ -28,14 +30,14 @@
<object class="GtkBox" id="content">
<child>
<object class="GtkMenuButton" id="type_chooser_all">
<property name="focusable">1</property>
<property name="focus-on-click">0</property>
<property name="receives-default">1</property>
<property name="focusable">1</property>
<property name="popover">all</property>
<property name="receives-default">1</property>
<child>
<object class="GtkImage">
<object class="GtkImage">
<property name="icon-name">edit-find-symbolic</property>
</object>
</object>
</child>
</object>
</child>
@ -46,82 +48,79 @@
</child>
<child>
<object class="GtkLabel" id="type_label">
<property name="sensitive">0</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
<property name="hexpand">1</property>
<property name="sensitive">0</property>
<attributes>
<attribute name="style" value="italic"></attribute>
<attribute name="style" value="italic"/>
</attributes>
</object>
</child>
<child>
<object class="GtkBox" id="type_chooser_gtk">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<style>
<class name="linked"/>
</style>
<property name="visible">True</property>
<child>
<object class="GtkMenuButton">
<property name="focusable">1</property>
<property name="focus-on-click">0</property>
<property name="receives-default">1</property>
<property name="focusable">1</property>
<property name="popover">toplevel</property>
<property name="receives-default">1</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="1" comments="Widget group for toplevels/windows">Toplevel</property>
<property name="label" translatable="yes" comments="Widget group for toplevels/windows">Toplevel</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="focusable">1</property>
<property name="focus-on-click">0</property>
<property name="receives-default">1</property>
<property name="focusable">1</property>
<property name="popover">layout</property>
<property name="receives-default">1</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="1" comments="Widget group for container widgets like GtkBox grid">Layout</property>
<property name="label" translatable="yes" comments="Widget group for container widgets like GtkBox grid">Layout</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="focusable">1</property>
<property name="focus-on-click">0</property>
<property name="receives-default">1</property>
<property name="focusable">1</property>
<property name="popover">control</property>
<property name="receives-default">1</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="1" comments="Widget group for control widget like buttons, entries">Control</property>
<property name="label" translatable="yes" comments="Widget group for control widget like buttons, entries">Control</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="focusable">1</property>
<property name="focus-on-click">0</property>
<property name="receives-default">1</property>
<property name="focusable">1</property>
<property name="popover">display</property>
<property name="receives-default">1</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="1" comments="Widget group for display widgets (label, image)">Display</property>
<property name="label" translatable="yes" comments="Widget group for display widgets (label, image)">Display</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton">
<property name="focusable">1</property>
<property name="focus-on-click">0</property>
<property name="receives-default">1</property>
<property name="focusable">1</property>
<property name="popover">model</property>
<property name="receives-default">1</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="1" comments="Widget group for model objects (ListStore, TextBuffer)">Model</property>
<property name="label" translatable="yes" comments="Widget group for model objects (ListStore, TextBuffer)">Model</property>
</object>
</child>
</object>
@ -129,8 +128,8 @@
<child>
<object class="GtkMenuButton">
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="popover">extra</property>
<property name="receives-default">1</property>
<child>
<object class="GtkImage">
<property name="icon-name">pan-down-symbolic</property>
@ -138,6 +137,9 @@
</child>
</object>
</child>
<style>
<class name="linked"/>
</style>
</object>
</child>
</template>

View File

@ -57,6 +57,19 @@ class CmbTypeChooserWidget(Gtk.Box):
super().__init__(**kwargs)
self.connect("map", self.__on_map)
def __on_map(self, widget):
root = widget.get_root()
if root is not None:
height = root.get_allocated_height() - 100
if height > 460:
height = height * 0.7
self.scrolledwindow.set_max_content_height(height)
return False
def __type_info_should_append(self, info):
retval = False

View File

@ -1,28 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_type_chooser_widget.ui -->
<requires lib="gtk" version="4.0"/>
<template class="CmbTypeChooserWidget" parent="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkSearchEntry" id="searchentry">
<signal name="activate" handler="on_searchentry_activate" swapped="no"/>
<signal name="search-changed" handler="on_searchentry_search_changed" swapped="no"/>
<signal name="activate" handler="on_searchentry_activate"/>
<signal name="search-changed" handler="on_searchentry_search_changed"/>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="hscrollbar-policy">never</property>
<property name="window-placement">bottom-left</property>
<property name="min-content-height">256</property>
<property name="propagate-natural-width">1</property>
<property name="propagate-natural-height">1</property>
<property name="child">
<object class="GtkTreeView" id="treeview">
<property name="headers-visible">0</property>
<property name="enable-search">0</property>
<property name="activate-on-single-click">1</property>
<signal name="row-activated" handler="on_treeview_row_activated" swapped="no"/>
<property name="enable-search">0</property>
<property name="headers-visible">0</property>
<signal name="row-activated" handler="on_treeview_row_activated"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection"/>
</child>
@ -30,6 +27,7 @@
<object class="GtkTreeViewColumn" id="column_adaptor">
<child>
<object class="GtkCellRendererText" id="adaptor_cell"/>
<!-- Custom child fragments -->
<attributes>
<attribute name="markup">0</attribute>
<attribute name="sensitive">3</attribute>
@ -39,6 +37,11 @@
</child>
</object>
</property>
<property name="hscrollbar-policy">never</property>
<property name="min-content-height">256</property>
<property name="propagate-natural-height">1</property>
<property name="propagate-natural-width">1</property>
<property name="window-placement">bottom-left</property>
</object>
</child>
</template>

View File

@ -115,7 +115,17 @@ class CmbUI(CmbBaseUI):
c.close()
def get_display_name(self):
return self.filename if self.filename else _("Unnamed {ui_id}").format(ui_id=self.ui_id)
if self.filename:
return self.filename
template_id = self.template_id
if template_id:
template = self.project.get_object_by_id(self.ui_id, template_id)
if template is not None:
return template.name
return _("Unnamed {ui_id}").format(ui_id=self.ui_id)
def __get_infered_target(self, library_id):
ui_id = self.ui_id

View File

@ -1,17 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_ui_editor.ui -->
<requires lib="gtk" version="4.0"/>
<object class="CmbTextBuffer" id="authors"/>
<object class="CmbTextBuffer" id="comment"/>
<object class="CmbTextBuffer" id="copyright"/>
<object class="CmbTextBuffer" id="description"/>
<template class="CmbUIEditor" parent="GtkGrid">
<property name="row-spacing">4</property>
<property name="column-spacing">3</property>
<property name="row-spacing">4</property>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Filename:</property>
<property name="label" translatable="yes">Filename:</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
@ -21,7 +23,7 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Description:</property>
<property name="label" translatable="yes">Description:</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
@ -31,7 +33,7 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Copyright:</property>
<property name="label" translatable="yes">Copyright:</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
@ -41,7 +43,7 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Authors:</property>
<property name="label" translatable="yes">Authors:</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
@ -51,7 +53,7 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Domain:</property>
<property name="label" translatable="yes">Domain:</property>
<layout>
<property name="column">0</property>
<property name="row">5</property>
@ -60,10 +62,10 @@
</child>
<child>
<object class="CmbEntry" id="filename">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="placeholder-text" translatable="1">&lt;file name relative to project&gt;</property>
<property name="placeholder-text" translatable="yes">&lt;file name relative to project&gt;</property>
<property name="visible">True</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
@ -72,10 +74,10 @@
</child>
<child>
<object class="CmbEntry" id="translation_domain">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="halign">start</property>
<property name="placeholder-text" translatable="1">&lt;translation domain&gt;</property>
<property name="placeholder-text" translatable="yes">&lt;translation domain&gt;</property>
<property name="visible">True</property>
<layout>
<property name="column">1</property>
<property name="row">5</property>
@ -84,15 +86,15 @@
</child>
<child>
<object class="GtkScrolledWindow">
<property name="focusable">1</property>
<property name="min-content-height">96</property>
<property name="max-content-height">256</property>
<property name="child">
<object class="GtkTextView">
<property name="focusable">1</property>
<property name="buffer">description</property>
<property name="focusable">1</property>
</object>
</property>
<property name="focusable">1</property>
<property name="max-content-height">256</property>
<property name="min-content-height">96</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
@ -101,15 +103,15 @@
</child>
<child>
<object class="GtkScrolledWindow">
<property name="focusable">1</property>
<property name="min-content-height">96</property>
<property name="max-content-height">256</property>
<property name="child">
<object class="GtkTextView">
<property name="focusable">1</property>
<property name="buffer">authors</property>
<property name="focusable">1</property>
</object>
</property>
<property name="focusable">1</property>
<property name="max-content-height">256</property>
<property name="min-content-height">96</property>
<layout>
<property name="column">1</property>
<property name="row">4</property>
@ -118,10 +120,10 @@
</child>
<child>
<object class="CmbToplevelChooser" id="template_id">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="derivable-only">True</property>
<property name="halign">start</property>
<property name="visible">True</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
@ -131,7 +133,7 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Template:</property>
<property name="label" translatable="yes">Template:</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
@ -140,14 +142,14 @@
</child>
<child>
<object class="GtkBox">
<property name="spacing">4</property>
<property name="valign">end</property>
<property name="vexpand">1</property>
<property name="spacing">4</property>
<child>
<object class="GtkButton" id="remove_button">
<property name="focusable">1</property>
<property name="receives-default">1</property>
<signal name="clicked" handler="on_remove_button_clicked" swapped="no"/>
<signal name="clicked" handler="on_remove_button_clicked"/>
<child>
<object class="GtkImage">
<property name="icon-name">app-remove-symbolic</property>
@ -157,13 +159,13 @@
</child>
<child>
<object class="GtkButton" id="export_button">
<property name="label" translatable="1">Export</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<property name="tooltip-text" translatable="1">Export</property>
<property name="halign">end</property>
<property name="hexpand">True</property>
<signal name="clicked" handler="on_export_button_clicked" swapped="no"/>
<property name="label" translatable="yes">Export</property>
<property name="receives-default">1</property>
<property name="tooltip-text" translatable="yes">Export</property>
<signal name="clicked" handler="on_export_button_clicked"/>
<style>
<class name="suggested-action"/>
</style>
@ -171,22 +173,22 @@
</child>
<layout>
<property name="column">0</property>
<property name="row">7</property>
<property name="column-span">2</property>
<property name="row">7</property>
</layout>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="focusable">1</property>
<property name="min-content-height">96</property>
<property name="max-content-height">256</property>
<property name="child">
<object class="GtkTextView">
<property name="focusable">1</property>
<property name="buffer">copyright</property>
<property name="focusable">1</property>
</object>
</property>
<property name="focusable">1</property>
<property name="max-content-height">256</property>
<property name="min-content-height">96</property>
<layout>
<property name="column">1</property>
<property name="row">3</property>
@ -196,7 +198,7 @@
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="label" translatable="1">Comment:</property>
<property name="label" translatable="yes">Comment:</property>
<layout>
<property name="column">0</property>
<property name="row">6</property>
@ -205,15 +207,15 @@
</child>
<child>
<object class="GtkScrolledWindow">
<property name="focusable">1</property>
<property name="min-content-height">96</property>
<property name="max-content-height">256</property>
<property name="child">
<object class="GtkTextView">
<property name="focusable">1</property>
<property name="buffer">comment</property>
<property name="focusable">1</property>
</object>
</property>
<property name="focusable">1</property>
<property name="max-content-height">256</property>
<property name="min-content-height">96</property>
<layout>
<property name="column">1</property>
<property name="row">6</property>

View File

@ -1,73 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.3 -->
<interface>
<!-- interface-name cmb_view.ui -->
<requires lib="gtk" version="4.0"/>
<requires lib="webkitgtk" version="6.0"/>
<object class="WebKitSettings" id="settings">
<property name="enable-html5-local-storage">False</property>
<property name="enable-html5-database">False</property>
<property name="enable-fullscreen">False</property>
<property name="enable-html5-database">False</property>
<property name="enable-html5-local-storage">False</property>
<property name="enable-media">False</property>
<property name="enable-webaudio">False</property>
<property name="media-playback-allows-inline">False</property>
<property name="user-agent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15</property>
<property name="enable-media">False</property>
</object>
<template class="CmbView" parent="GtkBox">
<child>
<object class="GtkStack" id="stack">
<property name="hexpand">true</property>
<property name="transition-duration">300</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkStackPage">
<property name="name">ui_view</property>
<property name="title" translatable="1">Project View</property>
<property name="child">
<object class="WebKitWebView" id="webview">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="settings">settings</property>
<signal name="context-menu" handler="on_context_menu" swapped="no"/>
<child>
<placeholder/>
</child>
<object class="GtkStack" id="stack">
<property name="hexpand">true</property>
<property name="transition-duration">300</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkStackPage">
<property name="child">
<object class="WebKitWebView" id="webview">
<property name="can-focus">True</property>
<property name="settings">settings</property>
<property name="visible">True</property>
<signal name="context-menu" handler="on_context_menu"/>
</object>
</property>
<property name="name">ui_view</property>
<property name="title" translatable="yes">Project View</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">ui_xml</property>
<property name="title" translatable="1">UI Definition</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">1</property>
<property name="focusable">1</property>
</child>
<child>
<object class="GtkStackPage">
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="CmbSourceView" id="text_view">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="editable">False</property>
<property name="cursor-visible">False</property>
<property name="lang">xml</property>
<object class="GtkScrolledWindow">
<property name="focusable">1</property>
<property name="vexpand">1</property>
<child>
<object class="CmbSourceView" id="text_view">
<property name="can-focus">True</property>
<property name="cursor-visible">False</property>
<property name="editable">False</property>
<property name="lang">xml</property>
<property name="visible">True</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStackSwitcher">
<property name="halign">center</property>
<property name="margin-bottom">4</property>
<property name="margin-top">4</property>
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStackSwitcher">
<property name="halign">center</property>
<property name="margin-top">4</property>
<property name="margin-bottom">4</property>
<property name="stack">stack</property>
</object>
</child>
</property>
<property name="name">ui_xml</property>
<property name="title" translatable="yes">UI Definition</property>
</object>
</property>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@ -122,6 +122,7 @@ CREATE TABLE object (
comment TEXT,
position INTEGER NOT NULL ON CONFLICT REPLACE DEFAULT 0,
custom_fragment TEXT,
custom_child_fragment TEXT,
PRIMARY KEY(ui_id, object_id),
FOREIGN KEY(ui_id, parent_id) REFERENCES object(ui_id, object_id) ON DELETE CASCADE
) WITHOUT ROWID;
@ -205,7 +206,7 @@ CREATE TABLE object_property (
property_id TEXT,
value TEXT,
translatable BOOLEAN,
translatable BOOLEAN CHECK (translatable IS NULL OR (translatable IN (1, 0))),
comment TEXT,
translation_context TEXT,
translation_comments TEXT,
@ -238,7 +239,7 @@ CREATE TABLE object_layout_property (
property_id TEXT,
value TEXT,
translatable BOOLEAN,
translatable BOOLEAN CHECK (translatable IS NULL OR (translatable IN (1, 0))),
comment TEXT,
translation_context TEXT,
translation_comments TEXT,
@ -265,8 +266,8 @@ CREATE TABLE object_signal (
handler TEXT NOT NULL,
detail TEXT,
user_data INTEGER,
swap BOOLEAN,
after BOOLEAN,
swap BOOLEAN CHECK (swap IS NULL OR (swap IN (1, 0))),
after BOOLEAN CHECK (after IS NULL OR (after IN (1, 0))),
comment TEXT,
FOREIGN KEY(ui_id, object_id) REFERENCES object ON DELETE CASCADE,
FOREIGN KEY(owner_id, signal_id) REFERENCES signal
@ -290,7 +291,7 @@ CREATE TABLE object_data (
value TEXT,
parent_id INTEGER,
comment TEXT,
translatable BOOLEAN,
translatable BOOLEAN CHECK (translatable IS NULL OR (translatable IN (1, 0))),
translation_context TEXT,
translation_comments TEXT,
PRIMARY KEY(ui_id, object_id, owner_id, data_id, id),

View File

@ -39,31 +39,23 @@ class MrgGtkPopover(MrgGtkWidget):
self.property_ignore_list.add("autohide")
else:
self.property_ignore_list.add("modal")
self.property_ignore_list.add("relative_to")
#self.property_ignore_list.add("relative_to")
def __ensure_popup(self):
if self.object is None:
return
self.__button.set_popover(self.object)
if self.__button:
self.__button.set_popover(self.object)
if Gtk.MAJOR_VERSION == 3:
self.object.set_modal(False)
else:
self.object.set_autohide(False)
def popup(self):
if self.__button is None:
return
if Gtk.MAJOR_VERSION == 3:
self.__button.set_active(True)
else:
self.__button.popup()
def object_changed(self, old, new):
# Clear old popover
if old:
if old and self.__button:
self.__button.set_popover(None)
self.selection = None
@ -74,14 +66,20 @@ class MrgGtkPopover(MrgGtkWidget):
self.window = None
return
if self.window is None:
# TODO: keep track when these prop changes and update window
if Gtk.MAJOR_VERSION == 4:
canot_be_activated = self.object.props.parent is None
else:
canot_be_activated = self.object.props.relative_to is None
if self.window is None and canot_be_activated:
self.__button = Gtk.MenuButton(
visible=True, halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER, receives_default=False
)
self.window = Gtk.Window(title="Popover Preview Window", deletable=False, width_request=320, height_request=240)
self.window = Gtk.Window(title="Popover Preview Window", deletable=False)
self.window.set_default_size(640, 480)
self.window.set_default_size(320, 240)
if Gtk.MAJOR_VERSION == 4:
self.__button.set_icon_name("open-menu-symbolic")
@ -98,10 +96,12 @@ class MrgGtkPopover(MrgGtkWidget):
if Gtk.MAJOR_VERSION == 4:
self.object.show()
self.window.show()
if self.window:
self.window.show()
else:
self.object.show_all()
self.window.show_all()
if self.window:
self.window.show_all()
def on_selected_changed(self):
super().on_selected_changed()

View File

@ -0,0 +1,29 @@
# Merengue WebKit plugin
#
# Copyright (C) 2022 Juan Pablo Ugarte
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation;
# version 2.1 of the License.
#
# library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Authors:
# Juan Pablo Ugarte <juanpablougarte@gmail.com>
#
from gi.repository import GObject
from .mrg_webkit_web_view import MrgWebKitWebView
from .mrg_webkit_web_view import MrgDummyWebView
from .mrg_webkit_web_view import MrgDummyWebViewProxy
GObject.type_ensure(MrgDummyWebViewProxy.__gtype__)

View File

@ -0,0 +1,144 @@
# MrgWebKitWebView Controller
#
# Copyright (C) 2022 Juan Pablo Ugarte
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation;
# version 2.1 of the License.
#
# library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Authors:
# Juan Pablo Ugarte <juanpablougarte@gmail.com>
#
from gi.repository import GObject, Gtk, WebKit
from merengue.mrg_gtk import MrgGtkWidget
from merengue import getLogger
logger = getLogger(__name__)
class MrgWebKitWebView(MrgGtkWidget):
object = GObject.Property(type=WebKit.WebView, flags=GObject.ParamFlags.READWRITE)
def __init__(self, **kwargs):
super().__init__(**kwargs)
logger.warning("MrgWebKitWebView __init__")
def object_changed(self, old, new):
super().object_changed(old, new)
if self.object:
self.object.load_html(
"""
<!DOCTYPE html>
<html>
<head>
<title>Cambalache WebKit</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: table;
}
div.content {
display: table-cell;
text-align: center;
vertical-align: middle;
border: 3px groove lightgray;
border-radius: 1em;
}
</style>
</head>
<script>
function open_url() {
const url = document.querySelector('#url_entry').value;
window.location.href = (url.startsWith('http')) ? url : 'http://' + url;
}
</script>
<body>
<div class="content">
<h3>WebKit Test Page</h3>
<span>URL:</span>
<input type="text" id="url_entry" />
<input type="button" value="Open" onclick="open_url()" />
<br/>
<br/>
<a href="https://gitlab.gnome.org/jpu/cambalache">Cambalache</a>
<a href="https://webkitgtk.org/">WebKitGtk</a>
</div>
</body>
</html>
""",
".",
)
class MrgDummyWebViewProxy(Gtk.Label):
__gtype_name__ = "MrgDummyWebViewProxy"
automation_presentation_type = GObject.Property(
type=WebKit.AutomationBrowsingContextPresentation,
default=WebKit.AutomationBrowsingContextPresentation.WINDOW,
flags=GObject.ParamFlags.READWRITE,
)
camera_capture_state = GObject.Property(
type=WebKit.MediaCaptureState, default=WebKit.MediaCaptureState.NONE, flags=GObject.ParamFlags.READWRITE
)
default_content_security_policy = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
display_capture_state = GObject.Property(
type=WebKit.MediaCaptureState, default=WebKit.MediaCaptureState.NONE, flags=GObject.ParamFlags.READWRITE
)
editable = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
is_controlled_by_automation = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
is_ephemeral = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
is_muted = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
microphone_capture_state = GObject.Property(
type=WebKit.MediaCaptureState, default=WebKit.MediaCaptureState.NONE, flags=GObject.ParamFlags.READWRITE
)
related_view = GObject.Property(type=WebKit.WebView, flags=GObject.ParamFlags.READWRITE)
settings = GObject.Property(type=WebKit.Settings, flags=GObject.ParamFlags.READWRITE)
user_content_manager = GObject.Property(type=WebKit.UserContentManager, flags=GObject.ParamFlags.READWRITE)
web_context = GObject.Property(type=WebKit.WebContext, flags=GObject.ParamFlags.READWRITE)
web_extension_mode = GObject.Property(
type=WebKit.WebExtensionMode, default=WebKit.WebExtensionMode.NONE, flags=GObject.ParamFlags.READWRITE
)
website_policies = GObject.Property(type=WebKit.WebsitePolicies, flags=GObject.ParamFlags.READWRITE)
zoom_level = GObject.Property(type=float, flags=GObject.ParamFlags.READWRITE)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.props.label = "WebKit.WebView\nplaceholder"
self.props.justify = Gtk.Justification.CENTER
class MrgDummyWebView(MrgGtkWidget):
object = GObject.Property(type=MrgDummyWebViewProxy, flags=GObject.ParamFlags.READWRITE)
def __init__(self, **kwargs):
super().__init__(**kwargs)

View File

@ -1,12 +1,12 @@
project(
'cambalache', 'c',
version: '0.17.2',
version: '0.17.3',
meson_version: '>= 0.50.0'
)
# File format version follows app version and only changes when there is a
# change that prevents older versions to load it.
fileformatversion = '0.17.1'
fileformatversion = '0.17.3'
python = import('python')
python_bin = python.find_installation('python3')