Skip to content

Commit

Permalink
Fix #168: update language popover UI
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrey Maksimov committed Dec 21, 2023
1 parent a6f2316 commit c1c1b05
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 110 deletions.
1 change: 1 addition & 0 deletions data/com.github.tenderowl.frog.gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<file preprocess="xml-stripblanks">ui/welcome_page.ui</file>
<file preprocess="xml-stripblanks">ui/extracted_page.ui</file>
<file preprocess="xml-stripblanks">ui/language_popover.ui</file>
<file preprocess="xml-stripblanks">ui/language_popover_row.ui</file>
<file preprocess="xml-stripblanks">ui/language_dialog.ui</file>
<file preprocess="xml-stripblanks">ui/language_row.ui</file>
<file preprocess="xml-stripblanks">ui/shortcuts.ui</file>
Expand Down
1 change: 1 addition & 0 deletions data/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ blueprints = custom_target('blueprints',
'ui/shortcuts.blp',
'ui/window.blp',
'ui/language_popover.blp',
'ui/language_popover_row.blp',
'ui/language_row.blp',
'ui/welcome_page.blp',
'ui/extracted_page.blp',
Expand Down
40 changes: 30 additions & 10 deletions data/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,38 @@
color: #3584e4;
}

#lang_list row {
padding: 0;
/* #lang_list row { */
/* padding: 0; */
/* } */

/* #lang_list row:first-child { */
/* border-top-left-radius: 12px; */
/* border-top-right-radius: 12px; */
/* border-top-width: 0; */
/* } */

/* #lang_list row:last-child { */
/* border-bottom-left-radius: 12px; */
/* border-bottom-right-radius: 12px; */
/* border-bottom-width: 0; */
/* } */

/* Lang Selector */
.search_box {
background: @popover_bg_color;
border-bottom: 1px solid @borders;
padding: 6px;
}

.lang-selector list {
padding: 6px;
padding-top: 4px;
}

#lang_list row:first-child {
border-top-left-radius: 12px;
border-top-right-radius: 12px;
border-top-width: 0;
.lang-selector row {
margin-top: 2px;
}

#lang_list row:last-child {
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
border-bottom-width: 0;
.lang-selector separator {
margin: 0 6px;
}
12 changes: 6 additions & 6 deletions data/ui/extracted_page.blp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ template $ExtractedPage : Adw.NavigationPage {
[title]
Label {}

[start]
MenuButton lang_combo {
label: _("Language");
tooltip-text: _("Select language to extract");
popover: $LanguagePopover language_popover {};
}
// [start]
// MenuButton lang_combo {
// label: _("Language");
// tooltip-text: _("Select language to extract");
// popover: $LanguagePopover language_popover {};
// }

[start]
Adw.SplitButton grab_btn {
Expand Down
57 changes: 20 additions & 37 deletions data/ui/language_popover.blp
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,33 @@ using Gio 2.0;

template $LanguagePopover : Popover {

show => $_on_popover_show();
closed => $_on_popover_closed();
styles ["lang-selector","menu"]

Box {
orientation: vertical;
spacing: 10;
margin-start: 2;
margin-end: 2;
margin-top: 2;
margin-bottom: 2;

SearchEntry entry {
placeholder-text: _("Search language");
activate => $_on_search_activate();
search-changed => $_on_search_changed();
stop-search => $_on_stop_search();
height-request: 256;


Box search_box {
orientation: vertical;
styles ["search_box"]

SearchEntry entry {
placeholder-text: _("Search Languages…");
activate => $_on_search_activate();
search-changed => $_on_search_changed();
stop-search => $_on_stop_search();
}
}

ScrolledWindow {
min-content-height: 256;

ListView list_view {
single-click-activate: true;
show-separators: true;
enable-rubberband: false;

model: SingleSelection selection {
model: SortListModel sort_list {
model: FilterListModel filter_list {
model: Gio.ListStore list_store {
item-type: typeof<$LanguageItem>;
};

filter: CustomFilter filter {};
};
sorter: CustomSorter sorter {};
};
};
factory: SignalListItemFactory factory {
bind => $_on_factory_bind();
setup => $_on_factory_setup();
};
activate => $_on_language_activate();

styles ["card"]
vexpand: true;

ListBox list_view {
selection-mode: single;
row-activated => $_on_language_activate();
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions data/ui/language_popover_row.blp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Gtk 4.0;

template $LanguagePopoverRow : Gtk.ListBoxRow {
child: Box {
spacing: 6;

Label title {
xalign: 0;
}

Image selection {
icon-name: "object-select-symbolic";
visible: false;
}
};
}
14 changes: 7 additions & 7 deletions data/ui/welcome_page.blp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ template $WelcomePage : Adw.NavigationPage {
popover: $LanguagePopover language_popover {};
}

[start]
Adw.SplitButton grab_btn {
action-name: "app.get_screenshot";
tooltip-text: _("Take a screenshot");
icon-name: "camera-photo-symbolic";
menu-model: grab_menu;
}
// [start]
// Adw.SplitButton grab_btn {
// action-name: "app.get_screenshot";
// tooltip-text: _("Take a screenshot");
// icon-name: "camera-photo-symbolic";
// menu-model: grab_menu;
// }

[start]
Spinner spinner {
Expand Down
4 changes: 3 additions & 1 deletion frog/types/language_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ class LanguageItem(GObject.GObject):

title: str = GObject.Property(type=str)
code: str = GObject.Property(type=str)
selected: bool = GObject.Property(type=bool, default=False)

def __init__(self, code: str, title: str):
def __init__(self, code: str, title: str, selected: bool = False):
super().__init__()
self.title = title
self.code = code
self.selected = selected

def __repr__(self):
return f'<LanguageItem: {self.title}, {self.code}>'
29 changes: 17 additions & 12 deletions frog/widgets/extracted_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@

from frog.config import RESOURCE_PREFIX
from frog.gobject_worker import GObjectWorker
from frog.language_manager import language_manager
# from frog.language_manager import language_manager
from frog.services.share_service import ShareService
from frog.services.tts import ttsservice, TTSService
from frog.settings import Settings
from frog.types.language_item import LanguageItem
from frog.widgets.language_popover import LanguagePopover
# from frog.types.language_item import LanguageItem
# from frog.widgets.language_popover import LanguagePopover
from frog.widgets.share_row import ShareRow


Expand All @@ -49,8 +49,8 @@ class ExtractedPage(Adw.NavigationPage):
"on-listen-stop": (GObject.SIGNAL_RUN_LAST, None, ()),
}

lang_combo: Gtk.MenuButton = Gtk.Template.Child()
language_popover: LanguagePopover = Gtk.Template.Child()
# lang_combo: Gtk.MenuButton = Gtk.Template.Child()
# language_popover: LanguagePopover = Gtk.Template.Child()
listen_btn: Gtk.Button = Gtk.Template.Child()
listen_cancel_btn: Gtk.Button = Gtk.Template.Child()
listen_spinner: Gtk.Spinner = Gtk.Template.Child()
Expand All @@ -70,22 +70,27 @@ def __init__(self):

ttsservice.connect("stop", self._on_listen_end)

self.language_popover.connect('language-changed', self._on_language_changed)
# self.language_popover.connect('language-changed', self._on_language_changed)

self.settings = Gtk.Application.get_default().props.settings

self.lang_combo.set_label(
language_manager.get_language(self.settings.get_string("active-language"))
)
# self.lang_combo.set_label(
# language_manager.get_language(self.settings.get_string("active-language"))
# )

def _on_language_changed(self, _: LanguagePopover, language: LanguageItem):
self.lang_combo.set_label(language.title)
self.settings.set_string("active-language", language.code)
# def _on_language_changed(self, _: LanguagePopover, language: LanguageItem):
# self.lang_combo.set_label(language.title)
# self.settings.set_string("active-language", language.code)

def do_hiding(self) -> None:
self.buffer.set_text("")
self.emit("go-back", 1)

# def do_showing(self) -> None:
# self.lang_combo.set_label(
# language_manager.get_language(self.settings.get_string("active-language"))
# )

@GObject.Property(type=str)
def extracted_text(self) -> str:
return self.buffer.get_text(
Expand Down
66 changes: 29 additions & 37 deletions frog/widgets/language_popover.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
# use or other dealings in this Software without prior written
# authorization.

from gi.repository import Gtk, Gio, GObject, GLib
from gi.repository import Gtk, Gio, GObject

from frog.config import RESOURCE_PREFIX
from frog.language_manager import language_manager
from frog.types.language_item import LanguageItem
from frog.settings import Settings
from frog.types.language_item import LanguageItem
from frog.widgets.language_popover_row import LanguagePopoverRow


@Gtk.Template(resource_path=f"{RESOURCE_PREFIX}/ui/language_popover.ui")
Expand All @@ -43,10 +44,10 @@ class LanguagePopover(Gtk.Popover):
}

entry: Gtk.SearchEntry = Gtk.Template.Child()
list_view: Gtk.ListView = Gtk.Template.Child()
list_store: Gio.ListStore = Gtk.Template.Child()
filter_list: Gtk.FilterListModel = Gtk.Template.Child()
filter: Gtk.CustomFilter = Gtk.Template.Child()
list_view: Gtk.ListBox = Gtk.Template.Child()
lang_list: Gio.ListStore = Gio.ListStore(item_type=LanguageItem)
filter_list: Gtk.FilterListModel # = Gtk.Template.Child()
filter: Gtk.CustomFilter # = Gtk.Template.Child()

settings: Settings
_active_language: str | None = None
Expand All @@ -63,9 +64,14 @@ def __init__(self):
self.active_language = self.settings.get_string('active-language')
print("active-language", self.settings.get_string('active-language'))

self.fill_lang_combo()
if not language_manager.get_downloaded_codes():
self.text_shot_btn.set_sensitive(False)
# self.populate_model()
self.bind_model()

def bind_model(self):
self.filter = Gtk.CustomFilter()
self.filter.set_filter_func(self.on_language_filter)
self.filter_list = Gtk.FilterListModel.new(self.lang_list, self.filter)
self.list_view.bind_model(self.filter_list, LanguagePopoverRow)

@GObject.Property(type=str)
def active_lang(self):
Expand All @@ -75,35 +81,22 @@ def active_lang(self):
def active_lang(self, lang_code: str):
self._active_language = lang_code

def on_language_filter(self, proposal: LanguageItem, text: str) -> bool:
return text.lower() in proposal.title.lower()
def on_language_filter(self, proposal: LanguageItem, text: str = None) -> bool:
return not text or text.lower() in proposal.title.lower()

def _on_language_downloaded(self, _sender, _lang_code: str):
self.fill_lang_combo()
self.populate_model()

def _on_language_removed(self, _sender, _lang_code: str):
self.fill_lang_combo()
self.populate_model()

@Gtk.Template.Callback()
def _on_search_activate(self, entry: Gtk.SearchEntry):
self._on_language_activate(self.list_view, 0)

@Gtk.Template.Callback()
def _on_factory_setup(self, _: Gtk.ListItemFactory, list_item: Gtk.ListItem):
label = Gtk.Label(margin_top=8, margin_end=8,
margin_start=8, margin_bottom=8,
xalign=0)
list_item.set_child(label)

@Gtk.Template.Callback()
def _on_factory_bind(self, _: Gtk.ListItemFactory, list_item: Gtk.ListItem):
row: Gtk.Label = list_item.get_child() # type: ignore
item: LanguageItem = list_item.get_item() # type: ignore
row.set_label(item.title)

@Gtk.Template.Callback()
def _on_language_activate(self, _: Gtk.ListView, position: int):
item: LanguageItem = self.filter_list.get_item(position)
def _on_language_activate(self, _: Gtk.ListBox, row: LanguagePopoverRow):
item: LanguageItem = row.lang
self.emit('language-changed', item)
self.active_language = item.code
language_manager.active_language = item
Expand All @@ -119,22 +112,21 @@ def _on_search_changed(self, entry: Gtk.SearchEntry):
def _on_stop_search(self, _entry: Gtk.SearchEntry):
self.popdown()

@Gtk.Template.Callback()
def _on_popover_show(self, _):
self.populate_model()

@Gtk.Template.Callback()
def _on_popover_closed(self, *_):
self.entry.set_text('')

def fill_lang_combo(self):
self.list_store.remove_all()
def populate_model(self):
self.lang_list.remove_all()

downloaded_languages = language_manager.get_downloaded_languages(force=True)
for lang in downloaded_languages:
GLib.idle_add(
self.list_store.append,
LanguageItem(code=language_manager.get_language_code(lang), title=lang),
priority=GLib.PRIORITY_LOW
)

print(f'Fill combo with {self.active_language}')
code = language_manager.get_language_code(lang)
self.lang_list.append(LanguageItem(code=code, title=lang, selected=self.active_language == code))

if self.active_language in language_manager.get_downloaded_codes():
self.emit('language-changed', language_manager.get_language_item(self.active_language))
Expand Down
Loading

0 comments on commit c1c1b05

Please sign in to comment.