mirror of
https://gitlab.gnome.org/jpu/cambalache.git
synced 2025-08-10 00:03:17 -04:00
Compare commits
2 Commits
19851963fb
...
fa89006ff2
Author | SHA1 | Date | |
---|---|---|---|
|
fa89006ff2 | ||
|
15b8ecf3d8 |
@ -52,6 +52,11 @@ popover.cmb-tutor label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
popover.cmb-tutor image {
|
||||
padding-right: 1em;
|
||||
-gtk-icon-size: 48px;
|
||||
}
|
||||
|
||||
button.cmb-tutor-highlight,
|
||||
modelbutton.cmb-tutor-highlight,
|
||||
buttonbox.cmb-tutor-highlight > button,
|
||||
|
@ -141,10 +141,16 @@ class CmbTutor(GObject.GObject):
|
||||
def __popover_new(self, text):
|
||||
popover = Gtk.Popover(autohide=False)
|
||||
popover.add_css_class("cmb-tutor")
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, hexpand=True)
|
||||
|
||||
box.append(Gtk.Image(icon_name="dialog-information-symbolic", icon_size=Gtk.IconSize.LARGE))
|
||||
box.append(Gtk.Label(label=text, wrap=True, max_width_chars=28))
|
||||
box.append(Gtk.Image(icon_name="dialog-information-symbolic"))
|
||||
box.append(Gtk.Label(
|
||||
label=text,
|
||||
vexpand=False,
|
||||
hexpand=True,
|
||||
wrap=True,
|
||||
max_width_chars=24
|
||||
))
|
||||
popover.set_child(box)
|
||||
|
||||
return popover
|
||||
|
@ -25,44 +25,44 @@ from .cmb_tutor import CmbTutorPosition
|
||||
from cambalache import _
|
||||
|
||||
intro = [
|
||||
# (_("Hi, I will show you around Cambalache"), "intro_button", 5),
|
||||
# (_("You can open a project"), "open_button", 3),
|
||||
# (
|
||||
# _("find recently used"),
|
||||
# "recent_button",
|
||||
# 2,
|
||||
# ),
|
||||
# (_("or create a new one"), "new_button", 4),
|
||||
# (_("Common actions like Undo"), "undo_button", 4),
|
||||
# (_("Redo"), "redo_button", 2),
|
||||
# (_("Add new UI file"), "add_button", 3),
|
||||
# (_("and Save are directly accessible in the headerbar"), "cmb_save_button", 6),
|
||||
# (_("just like Save As"), "save_as_button", 2),
|
||||
# (_("and the main menu"), "menu_button", 3, "main-menu"),
|
||||
# (_("Create a project to continue"), "intro_button", 2, "add-project"),
|
||||
# (_("Great!"), "intro_button", 2),
|
||||
# (
|
||||
# _("This is the project workspace, where you can see and select the widgets to edit"),
|
||||
# "view",
|
||||
# 6,
|
||||
# None,
|
||||
# CmbTutorPosition.CENTER,
|
||||
# ),
|
||||
# (_("Project tree, with multiple UI support"), "tree_view", 4, None, CmbTutorPosition.CENTER),
|
||||
# (
|
||||
# _("Class selector bar"),
|
||||
# "type_chooser_box",
|
||||
# 3,
|
||||
# ),
|
||||
# (_("And the object editor"), "editor_stack", 3, None, CmbTutorPosition.CENTER),
|
||||
# (_("You can search all supported classes here"), "type_chooser_all", 4, "show-type-popover", CmbTutorPosition.LEFT),
|
||||
# (_("or investigate what is in each group"), "type_chooser_gtk", 4, "show-type-popover-gtk", CmbTutorPosition.LEFT),
|
||||
# (_("Now let's add a new UI file"), "add_button", 5, "add-ui"),
|
||||
# (_("Good, now try to create a window"), "intro_button", 4, "add-window"),
|
||||
# (_("Excellent!"), "intro_button", 2),
|
||||
# (_("BTW, did you know you can double click on any placeholder to create widgets?"), "intro_button", 5),
|
||||
# (_("Try adding a grid"), "intro_button", 3, "add-grid"),
|
||||
# (_("and a button"), "intro_button", 3, "add-button"),
|
||||
(_("Hi, I will show you around Cambalache"), "intro_button", 5),
|
||||
(_("You can open a project"), "open_button", 3),
|
||||
(
|
||||
_("find recently used"),
|
||||
"recent_button",
|
||||
2,
|
||||
),
|
||||
(_("or create a new one"), "new_button", 4),
|
||||
(_("Common actions like Undo"), "undo_button", 4),
|
||||
(_("Redo"), "redo_button", 2),
|
||||
(_("Add new UI file"), "add_button", 3),
|
||||
(_("and Save are directly accessible in the headerbar"), "cmb_save_button", 6),
|
||||
(_("just like Save As"), "save_as_button", 2),
|
||||
(_("and the main menu"), "menu_button", 3, "menu_button"),
|
||||
(_("Create a project to continue"), "intro_button", 2, "add-project"),
|
||||
(_("Great!"), "intro_button", 2),
|
||||
(
|
||||
_("This is the project workspace, where you can see and select the widgets to edit"),
|
||||
"view",
|
||||
6,
|
||||
None,
|
||||
CmbTutorPosition.CENTER,
|
||||
),
|
||||
(_("Project tree, with multiple UI support"), "tree_view", 4, None, CmbTutorPosition.CENTER),
|
||||
(
|
||||
_("Class selector bar"),
|
||||
"type_chooser_box",
|
||||
3,
|
||||
),
|
||||
(_("And the object editor"), "editor_stack", 3, None, CmbTutorPosition.CENTER),
|
||||
(_("You can search all supported classes here"), "type_chooser_all", 4, "show-type-popover", CmbTutorPosition.LEFT),
|
||||
(_("or investigate what is in each group"), "type_chooser_gtk", 4, "show-type-popover-gtk", CmbTutorPosition.LEFT),
|
||||
(_("Now let's add a new UI file"), "add_button", 5, "add-ui"),
|
||||
(_("Good, now try to create a window"), "intro_button", 4, "add-window"),
|
||||
(_("Excellent!"), "intro_button", 2),
|
||||
(_("BTW, did you know you can double click on any placeholder to create widgets?"), "intro_button", 5),
|
||||
(_("Try adding a grid"), "intro_button", 3, "add-grid"),
|
||||
(_("and a button"), "intro_button", 3, "add-button"),
|
||||
(_("Quite easy! Isn't it?"), "intro_button", 3),
|
||||
(
|
||||
_("Once you finish, you can export all UI files to xml here"),
|
||||
|
@ -49,6 +49,7 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
|
||||
headerbar = Gtk.Template.Child()
|
||||
subtitle = Gtk.Template.Child()
|
||||
recent_menu = Gtk.Template.Child()
|
||||
undo_button = Gtk.Template.Child()
|
||||
redo_button = Gtk.Template.Child()
|
||||
stack = Gtk.Template.Child()
|
||||
@ -148,13 +149,17 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
|
||||
# Stateful actions
|
||||
for action, parameter_type, state in [
|
||||
("open_recent", "s", None),
|
||||
("workspace_theme", "s", "")
|
||||
]:
|
||||
gaction = Gio.SimpleAction.new_stateful(
|
||||
action,
|
||||
GLib.VariantType.new(parameter_type),
|
||||
GLib.Variant(parameter_type, state)
|
||||
)
|
||||
if state is None:
|
||||
gaction = Gio.SimpleAction.new(action, GLib.VariantType.new(parameter_type))
|
||||
else:
|
||||
gaction = Gio.SimpleAction.new_stateful(
|
||||
action,
|
||||
GLib.VariantType.new(parameter_type),
|
||||
GLib.Variant(parameter_type, state)
|
||||
)
|
||||
gaction.connect("activate", getattr(self, f"_on_{action}_activate"))
|
||||
self.actions[action] = gaction
|
||||
self.add_action(gaction)
|
||||
@ -256,6 +261,8 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
)
|
||||
|
||||
self.view.connect("notify::gtk-theme", self.__on_view_gtk_theme_notify)
|
||||
self.connect("notify::focus-widget", self.__on_focus_widget_notify)
|
||||
self.__update_recent_menu()
|
||||
|
||||
def __on_view_gtk_theme_notify(self, obj, pspec):
|
||||
print("__on_view_gtk_theme_notify", obj.props.gtk_theme)
|
||||
@ -362,14 +369,6 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
)
|
||||
popover.popup()
|
||||
|
||||
# FIXME: GTK4
|
||||
#@Gtk.Template.Callback("on_open_recent_action_item_activated")
|
||||
def __on_open_recent_action_item_activated(self, recent):
|
||||
uri = recent.get_current_uri()
|
||||
if uri is not None:
|
||||
filename, host = GLib.filename_from_uri(uri)
|
||||
self.emit("open-project", filename, None, None)
|
||||
|
||||
@Gtk.Template.Callback("on_ui_editor_remove_ui")
|
||||
def __on_ui_editor_remove_ui(self, editor):
|
||||
self.__remove_object_with_confirmation(editor.object)
|
||||
@ -380,10 +379,10 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
self.__remove_object_with_confirmation(editor.object)
|
||||
return True
|
||||
|
||||
# FIXME: GTK4
|
||||
#@Gtk.Template.Callback("on_window_set_focus")
|
||||
def __on_window_set_focus(self, window, widget):
|
||||
types = [Gtk.Entry, Gtk.TextView, Gtk.SpinButton]
|
||||
def __on_focus_widget_notify(self, obj, pspec):
|
||||
widget = self.props.focus_widget
|
||||
|
||||
types = [Gtk.Text, Gtk.TextView]
|
||||
focused_widget_needs = True
|
||||
|
||||
for type in types:
|
||||
@ -434,8 +433,10 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
# If foreground luminance is closer to 1 then the background must be dark
|
||||
if luminance(fg) > 0.5:
|
||||
self.add_css_class("dark")
|
||||
self.view._set_dark_mode(True)
|
||||
else:
|
||||
self.remove_css_class("dark")
|
||||
self.view._set_dark_mode(False)
|
||||
|
||||
def __np_name_to_ui(self, binding, value):
|
||||
if len(value):
|
||||
@ -1037,7 +1038,7 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
self.project.connect("object-added", self.__on_object_added, "GtkGrid")
|
||||
elif node == "add-button":
|
||||
self.project.connect("object-added", self.__on_object_added, "GtkButton")
|
||||
elif node == "main-menu":
|
||||
elif node in ["menu_button", "main-menu"]:
|
||||
self.menu_button.popup()
|
||||
elif node == "show-type-popover":
|
||||
widget.props.popover.popup()
|
||||
@ -1056,7 +1057,7 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
elif node in ["add-ui", "add-window", "add-grid", "add-button"]:
|
||||
self.tutor_waiting_for_user_action = True
|
||||
self.tutor.pause()
|
||||
elif node == "donate":
|
||||
elif node in ["menu_button", "donate"]:
|
||||
self.menu_button.popdown()
|
||||
elif node == "show-type-popover":
|
||||
widget.props.popover.popdown()
|
||||
@ -1097,6 +1098,29 @@ class CmbWindow(Gtk.ApplicationWindow):
|
||||
def _on_inspect_activate(self, action, data):
|
||||
self.view.inspect()
|
||||
|
||||
def _on_open_recent_activate(self, action, data):
|
||||
self.emit("open-project", data.get_string(), None, None)
|
||||
|
||||
def __update_recent_menu(self):
|
||||
manager = Gtk.RecentManager.get_default()
|
||||
|
||||
mime_types = [
|
||||
"application/x-cambalache-project"
|
||||
]
|
||||
|
||||
for recent in manager.get_items():
|
||||
if recent.get_mime_type() not in mime_types:
|
||||
continue
|
||||
|
||||
filename, host = GLib.filename_from_uri(recent.get_uri())
|
||||
if not os.path.exists(filename):
|
||||
continue
|
||||
|
||||
item = Gio.MenuItem()
|
||||
item.set_label(recent.get_display_name())
|
||||
item.set_action_and_target_value("win.open_recent", GLib.Variant("s", filename))
|
||||
self.recent_menu.append_item(item)
|
||||
|
||||
def __load_window_state(self):
|
||||
state = self.window_settings.get_uint("state")
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id="recent_menu"/>
|
||||
<object class="GtkFileFilter" id="open_filter">
|
||||
<mime-types>
|
||||
<mime-type>application/x-cambalache-project</mime-type>
|
||||
@ -321,6 +322,7 @@
|
||||
<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>
|
||||
@ -330,11 +332,9 @@
|
||||
<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>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -434,11 +434,6 @@
|
||||
<property name="title" translatable="1">Signals</property>
|
||||
<property name="child">
|
||||
<object class="CmbSignalEditor" id="signal_editor">
|
||||
<property name="margin-start">4</property>
|
||||
<property name="margin-end">4</property>
|
||||
<property name="margin-bottom">4</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">4</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@ -449,10 +444,6 @@
|
||||
<property name="title" translatable="0"></></property>
|
||||
<property name="child">
|
||||
<object class="CmbFragmentEditor" id="fragment_editor">
|
||||
<property name="margin-start">4</property>
|
||||
<property name="margin-end">4</property>
|
||||
<property name="margin-bottom">4</property>
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@ -742,8 +733,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="recent_button">
|
||||
<property name="focusable">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="menu-model">recent_menu</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">pan-down-symbolic</property>
|
||||
@ -752,6 +742,7 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="new_button">
|
||||
|
@ -34,9 +34,10 @@ class CmbContextMenu(Gtk.PopoverMenu):
|
||||
target_tk = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
||||
|
||||
main_section = Gtk.Template.Child()
|
||||
theme_submenu = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.theme_submenu = None
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.connect("notify::target-tk", lambda o, p: self.__populate_css_theme_box())
|
||||
@ -54,6 +55,9 @@ class CmbContextMenu(Gtk.PopoverMenu):
|
||||
else:
|
||||
themes = ["Adwaita", "HighContrast", "HighContrastInverse"]
|
||||
|
||||
if self.theme_submenu is None:
|
||||
self.theme_submenu = Gio.Menu()
|
||||
self.main_section.prepend_submenu(_("CSS theme"), self.theme_submenu)
|
||||
|
||||
# Remove all items from theme submenu
|
||||
self.theme_submenu.remove_all()
|
||||
@ -88,3 +92,9 @@ class CmbContextMenu(Gtk.PopoverMenu):
|
||||
item.set_action_and_target_value("win.workspace_theme", GLib.Variant("s", theme))
|
||||
self.theme_submenu.append_item(item)
|
||||
|
||||
def popup_at(self, x, y):
|
||||
r = Gdk.Rectangle()
|
||||
r.x, r.y = (x, y)
|
||||
r.width = r.height = 0
|
||||
self.set_pointing_to(r)
|
||||
self.popup()
|
||||
|
@ -38,11 +38,7 @@
|
||||
<attribute name="label" translatable="1">Read Documentation</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section id="main_section">
|
||||
<submenu id="theme_submenu">
|
||||
<attribute name="label" translatable="1">CSS theme</attribute>
|
||||
</submenu>
|
||||
</section>
|
||||
<section id="main_section"/>
|
||||
</menu>
|
||||
<template class="CmbContextMenu" parent="GtkPopoverMenu">
|
||||
<property name="menu-model">menu_model</property>
|
||||
|
@ -618,8 +618,8 @@ class CmbDB(GObject.GObject):
|
||||
|
||||
return f"\t({r})"
|
||||
|
||||
def _dump_table(c, table):
|
||||
c.execute(f"SELECT * FROM {table};")
|
||||
def _dump_query(c, query):
|
||||
c.execute(query)
|
||||
row = c.fetchone()
|
||||
|
||||
if row is None:
|
||||
@ -635,20 +635,27 @@ class CmbDB(GObject.GObject):
|
||||
|
||||
return f"\n{retval}\n "
|
||||
|
||||
def append_data(project, name, data):
|
||||
if data is None:
|
||||
return
|
||||
|
||||
element = etree.Element(name)
|
||||
element.text = data
|
||||
project.append(element)
|
||||
|
||||
self.conn.commit()
|
||||
c = self.conn.cursor()
|
||||
|
||||
project = E("cambalache-project", version=config.FILE_FORMAT_VERSION, target_tk=self.target_tk)
|
||||
|
||||
for table in self.__tables:
|
||||
data = _dump_table(c, table)
|
||||
data = _dump_query(c, f"SELECT * FROM {table};")
|
||||
append_data(project, table, data)
|
||||
|
||||
if data is None:
|
||||
continue
|
||||
|
||||
element = etree.Element(table)
|
||||
element.text = data
|
||||
project.append(element)
|
||||
# DUMP custom properties and signals
|
||||
for table in ["property", "signal"]:
|
||||
data = _dump_query(c, f"SELECT {table}.* FROM {table},type WHERE {table}.owner_id == type.type_id AND type.library_id IS NULL;")
|
||||
append_data(project, table, data)
|
||||
|
||||
# Dump xml to file
|
||||
with open(filename, "wb") as fd:
|
||||
|
@ -40,7 +40,6 @@ class CmbTreeView(Gtk.TreeView):
|
||||
self.__in_selection_change = False
|
||||
self._selection.connect("changed", self.__on_selection_changed)
|
||||
self.set_headers_visible(False)
|
||||
self.__right_click = False
|
||||
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn("Object(Type)", renderer)
|
||||
@ -50,31 +49,14 @@ class CmbTreeView(Gtk.TreeView):
|
||||
self.connect("notify::model", self.__on_model_notify)
|
||||
self.connect("row-activated", self.__on_row_activated)
|
||||
|
||||
self.menu = CmbContextMenu()
|
||||
|
||||
# FIXME: GTK4
|
||||
#self.connect("button-press-event", self.__on_button_press_event)
|
||||
#self.connect("button-release-event", self.__on_button_release_event)
|
||||
gesture = Gtk.GestureClick(button=3)
|
||||
gesture.connect("pressed", self.__on_button_press)
|
||||
self.add_controller(gesture)
|
||||
|
||||
self.set_reorderable(True)
|
||||
|
||||
def __on_button_press_event(self, widget, event):
|
||||
if event.window != self.get_bin_window() or event.button != 3:
|
||||
return False
|
||||
|
||||
self.__right_click = True
|
||||
return True
|
||||
|
||||
def __on_button_release_event(self, widget, event):
|
||||
if event.window != self.get_bin_window() or event.button != 3:
|
||||
return False
|
||||
|
||||
if not self.__right_click:
|
||||
return False
|
||||
|
||||
self.__right_click = False
|
||||
|
||||
retval = self.get_path_at_pos(event.x, event.y)
|
||||
def __on_button_press(self, widget, npress, x, y):
|
||||
retval = self.get_path_at_pos(x, y)
|
||||
|
||||
if retval is None:
|
||||
return False
|
||||
@ -82,7 +64,12 @@ class CmbTreeView(Gtk.TreeView):
|
||||
path, col, xx, yy = retval
|
||||
self.get_selection().select_path(path)
|
||||
|
||||
self.menu.popup_at(event.x, event.y)
|
||||
menu = CmbContextMenu()
|
||||
|
||||
# Use parent instead of self to avoid warning and focus not working properly
|
||||
# (run-dev.py:188589): Gtk-CRITICAL **: 16:45:12.790: gtk_css_node_insert_after: assertion 'previous_sibling == NULL || previous_sibling->parent == parent' failed
|
||||
menu.set_parent(self.props.parent)
|
||||
menu.popup_at(x, y)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -75,7 +75,6 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="width-chars">16</property>
|
||||
<property name="placeholder-text" translatable="1"><translation domain></property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
|
@ -131,6 +131,7 @@ class CmbView(Gtk.Box):
|
||||
self.__restart_project = None
|
||||
self.__ui_id = 0
|
||||
self.__theme = None
|
||||
self.__dark = False
|
||||
|
||||
self.menu = self.__create_context_menu()
|
||||
|
||||
@ -147,10 +148,6 @@ class CmbView(Gtk.Box):
|
||||
self.__port = None
|
||||
self.__merengue_last_exit = None
|
||||
|
||||
# FIXME: GTK4
|
||||
#context = self.get_style_context()
|
||||
#context.connect("changed", lambda ctx: self.__update_webview_bg())
|
||||
|
||||
if self.__broadwayd_bin is None:
|
||||
logger.warning("broadwayd not found, Gtk 3 workspace wont work.")
|
||||
|
||||
@ -169,24 +166,18 @@ class CmbView(Gtk.Box):
|
||||
def __evaluate_js(self, script):
|
||||
self.webview.evaluate_javascript(script, -1, None, None, None, None, None, None)
|
||||
|
||||
def __update_webview_bg(self):
|
||||
context = self.get_style_context()
|
||||
|
||||
# FIXME: GTK4
|
||||
# with warnings.catch_warnings():
|
||||
# warnings.filterwarnings("ignore", category=DeprecationWarning)
|
||||
# bg = context.get_background_color(Gtk.StateFlags.NORMAL)
|
||||
|
||||
# self.__evaluate_js(f"document.body.style.background = '{bg.to_string()}';")
|
||||
def _set_dark_mode(self, dark):
|
||||
self.__dark = dark
|
||||
self.__evaluate_js(f"document.body.style.background = '{'#222' if dark else 'inherit'}';")
|
||||
|
||||
def __on_load_changed(self, webview, event):
|
||||
if event != WebKit.LoadEvent.FINISHED:
|
||||
return
|
||||
|
||||
self.__update_webview_bg()
|
||||
self._set_dark_mode(self.__dark)
|
||||
|
||||
# Disable alert() function used when broadwayd get disconnected
|
||||
# Monkey patch setupDocument() to avoid disabling document.oncontextmenu
|
||||
# Monkey pat ch setupDocument() to avoid disabling document.oncontextmenu
|
||||
self.__evaluate_js(
|
||||
"""
|
||||
window.alert = function (message) {
|
||||
@ -463,11 +454,9 @@ window.setupDocument = function (document) {
|
||||
self.__theme = theme
|
||||
self.__merengue_command("gtk_settings_set", args={"property": "gtk-theme-name", "value": theme})
|
||||
|
||||
# FIXME: GTK4
|
||||
@Gtk.Template.Callback("on_context_menu")
|
||||
def __on_context_menu(self, webview, menu, hit_test_result):
|
||||
self.menu.set_pointing_to(utils.get_pointing_to(self))
|
||||
self.menu.popup()
|
||||
self.menu.popup_at(*utils.get_pointer(self))
|
||||
return True
|
||||
|
||||
def __webview_set_msg(self, msg):
|
||||
|
@ -24,7 +24,7 @@
|
||||
import os
|
||||
|
||||
from cambalache import _
|
||||
from gi.repository import GdkPixbuf, GObject, Gdk, Gtk, Pango
|
||||
from gi.repository import GLib, Gio, GdkPixbuf, GObject, Gdk, Gtk, Pango
|
||||
from .cmb_entry import CmbEntry
|
||||
from .icon_naming_spec import standard_icon_context, standard_icon_names
|
||||
|
||||
@ -48,6 +48,8 @@ class CmbIconNameEntry(CmbEntry):
|
||||
# Model, store it in a Python class variable to share between all instances
|
||||
icon_model = None
|
||||
|
||||
iconlist = []
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._filters = {}
|
||||
|
||||
@ -92,33 +94,55 @@ class CmbIconNameEntry(CmbEntry):
|
||||
iconlist = []
|
||||
|
||||
theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
|
||||
# FIXME: GTK4
|
||||
# print(theme.get_icon_names())
|
||||
|
||||
# for context in theme.list_contexts():
|
||||
# for icon in theme.list_icons(context):
|
||||
# iconlist.append((icon, context, icon in standard_icon_names))
|
||||
# FIXME: get the context/category of each icon
|
||||
for icon in theme.get_icon_names():
|
||||
iconlist.append((icon, "cmb_all", icon in standard_icon_names))
|
||||
|
||||
# for icon, context, standard in sorted(iconlist, key=lambda i: i[0].lower()):
|
||||
# if icon.endswith(".symbolic"):
|
||||
# continue
|
||||
for icon, context, standard in sorted(iconlist, key=lambda i: i[0].lower()):
|
||||
if icon.endswith(".symbolic"):
|
||||
continue
|
||||
|
||||
# info = theme.lookup_icon(icon, 32, Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
# symbolic = info.is_symbolic()
|
||||
icon_paintable = theme.lookup_icon(icon, None, 32, 1, Gtk.TextDirection.NONE, Gtk.IconLookupFlags.PRELOAD)
|
||||
symbolic = icon_paintable.is_symbolic()
|
||||
|
||||
# if not os.path.exists(info.get_filename()):
|
||||
# continue
|
||||
icon_file = icon_paintable.get_file()
|
||||
if icon_file is None:
|
||||
continue
|
||||
|
||||
# standard_symbolic = symbolic and icon.removesuffix("-symbolic") in standard_icon_names
|
||||
icon_path = icon_file.get_path()
|
||||
if icon_path is None or not os.path.exists(icon_path):
|
||||
continue
|
||||
|
||||
# iter = cls.icon_model.append(
|
||||
# [icon, icon if standard else f"<i>{icon}</i>", context, standard, symbolic, standard_symbolic, None]
|
||||
# )
|
||||
# info.load_icon_async(None, cls.__load_icon_finish, iter)
|
||||
standard_symbolic = symbolic and icon.removesuffix("-symbolic") in standard_icon_names
|
||||
|
||||
try:
|
||||
iter = cls.icon_model.append(
|
||||
[icon, icon if standard else f"<i>{icon}</i>", context, standard, symbolic, standard_symbolic, None]
|
||||
)
|
||||
cls.iconlist.append((icon_file, iter))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# Kickoff async loading
|
||||
file, iter = cls.iconlist.pop()
|
||||
file.read_async(GLib.PRIORITY_DEFAULT, None, cls.__load_file_finish, iter)
|
||||
|
||||
@classmethod
|
||||
def __load_icon_finish(cls, info, res, data):
|
||||
cls.icon_model[data][6] = info.load_icon_finish(res)
|
||||
def __load_file_finish(cls, obj, res, iter):
|
||||
stream = obj.read_finish(res)
|
||||
GdkPixbuf.Pixbuf.new_from_stream_at_scale_async(stream, 32, 32, True, None, cls.__load_icon_finish, iter)
|
||||
|
||||
@classmethod
|
||||
def __load_icon_finish(cls, obj, res, iter):
|
||||
try:
|
||||
cls.icon_model[iter][cls.COL_PIXBUF] = GdkPixbuf.Pixbuf.new_from_stream_finish(res)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
if len(cls.iconlist):
|
||||
file, iter = cls.iconlist.pop()
|
||||
file.read_async(GLib.PRIORITY_DEFAULT, None, cls.__load_file_finish, iter)
|
||||
|
||||
def __model_filter_func(self, model, iter, data):
|
||||
if self.standard_only and self.symbolic_only:
|
||||
@ -151,6 +175,8 @@ class CmbIconNameEntry(CmbEntry):
|
||||
def __on_icon_pressed(self, widget, icon_pos):
|
||||
# Create popover with icon chooser
|
||||
popover = Gtk.Popover()
|
||||
popover.set_parent(self)
|
||||
|
||||
hbox = Gtk.Box(visible=True)
|
||||
vbox = Gtk.Box(visible=True, orientation=Gtk.Orientation.VERTICAL, vexpand=True)
|
||||
stack = Gtk.Stack(visible=True, transition_type=Gtk.StackTransitionType.CROSSFADE)
|
||||
@ -159,9 +185,10 @@ class CmbIconNameEntry(CmbEntry):
|
||||
hbox.append(vbox)
|
||||
hbox.append(stack)
|
||||
|
||||
theme = Gtk.IconTheme.get_default()
|
||||
theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
|
||||
|
||||
sorted_contexts = sorted(theme.list_contexts())
|
||||
# sorted_contexts = sorted(theme.list_contexts())
|
||||
sorted_contexts = []
|
||||
sorted_contexts.insert(0, "cmb_all")
|
||||
|
||||
# Add one icon view per context
|
||||
|
@ -39,9 +39,8 @@ class CmbToplevelChooser(Gtk.ComboBox):
|
||||
self.connect("changed", self.__on_changed)
|
||||
|
||||
renderer = Gtk.CellRendererText()
|
||||
# FIXME: GTK4
|
||||
#self.pack_start(renderer, True)
|
||||
#self.set_cell_data_func(renderer, self.__name_cell_data_func, None)
|
||||
self.pack_start(renderer, True)
|
||||
self.set_cell_data_func(renderer, self.__name_cell_data_func, None)
|
||||
|
||||
def __name_cell_data_func(self, column, cell, model, iter_, data):
|
||||
obj = model.get_value(iter_, 0)
|
||||
|
@ -1,13 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<object class="GtkTextBuffer" id="buffer_comments"/>
|
||||
<object class="GtkTextBuffer" id="buffer_context"/>
|
||||
<object class="GtkTextBuffer" id="buffer_text"/>
|
||||
<template class="CmbTranslatableWidget" parent="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">4</property>
|
||||
<property name="margin-end">4</property>
|
||||
<property name="margin-top">4</property>
|
||||
@ -16,126 +13,70 @@
|
||||
<property name="spacing">4</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Text:</property>
|
||||
<property name="label" translatable="1">Text:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="width-request">300</property>
|
||||
<property name="height-request">60</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<property name="focusable">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkTextView" id="text_view_value">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="border-width">2</property>
|
||||
<property name="focusable">1</property>
|
||||
<property name="buffer">buffer_text</property>
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accepts-tab">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="check_button_translatable">
|
||||
<property name="label" translatable="yes">translatable</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="label" translatable="1">translatable</property>
|
||||
<property name="focusable">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-top">8</property>
|
||||
<property name="label" translatable="yes">Translation context:</property>
|
||||
<property name="label" translatable="1">Translation context:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="height-request">60</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<property name="focusable">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkTextView" id="text_view_context">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="border-width">2</property>
|
||||
<property name="focusable">1</property>
|
||||
<property name="buffer">buffer_context</property>
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accepts-tab">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-top">8</property>
|
||||
<property name="label" translatable="yes">Comments for translators:</property>
|
||||
<property name="label" translatable="1">Comments for translators:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="height-request">60</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<property name="focusable">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkTextView" id="text_view_comments">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="border-width">2</property>
|
||||
<property name="focusable">1</property>
|
||||
<property name="buffer">buffer_comments</property>
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accepts-tab">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
|
@ -6,7 +6,7 @@ project(
|
||||
|
||||
# File format version follows app version and only changes when there is a
|
||||
# change that prevents older versions to load it.
|
||||
fileformatversion = '0.13.1'
|
||||
fileformatversion = '0.17.0'
|
||||
|
||||
python = import('python')
|
||||
python_bin = python.find_installation('python3')
|
||||
|
Loading…
x
Reference in New Issue
Block a user