Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
tuneit
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ximper Linux
tuneit
Commits
3da4c51e
Commit
3da4c51e
authored
Jan 08, 2025
by
Roman Alifanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
big refactoring
parent
d1dc212d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
298 additions
and
4 deletions
+298
-4
meson.build
src/meson.build
+4
-0
__init__.py
src/settings/__init__.py
+141
-0
backends.py
src/settings/backends.py
+45
-0
__init__.py
src/settings/tools/__init__.py
+0
-0
yml_tools.py
src/settings/tools/yml_tools.py
+31
-0
BaseWidget.py
src/settings/widgets/BaseWidget.py
+6
-0
BooleanWidget.py
src/settings/widgets/BooleanWidget.py
+14
-0
ChoiceWidget.py
src/settings/widgets/ChoiceWidget.py
+14
-0
EntryWidget.py
src/settings/widgets/EntryWidget.py
+13
-0
__init__.py
src/settings/widgets/__init__.py
+19
-0
window.blp
src/window.blp
+11
-4
window.py
src/window.py
+0
-0
No files found.
src/meson.build
View file @
3da4c51e
...
...
@@ -42,3 +42,6 @@ tuneit_sources = [
]
install_data(tuneit_sources, install_dir: moduledir)
install_subdir('settings', install_dir: moduledir, strip_directory : false)
install_subdir('shop', install_dir: moduledir, strip_directory : false)
\ No newline at end of file
src/settings/__init__.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
,
Gtk
from
.backends
import
backend_factory
from
.tools.yml_tools
import
load_yaml_files_from_directory
,
merge_categories_by_name
from
.widgets
import
WidgetFactory
class
Setting
:
def
__init__
(
self
,
setting_data
):
self
.
name
=
setting_data
[
'name'
]
self
.
type
=
setting_data
[
'type'
]
self
.
help
=
setting_data
.
get
(
'help'
,
""
)
self
.
backend
=
setting_data
.
get
(
'backend'
)
self
.
key
=
setting_data
.
get
(
'key'
)
self
.
default
=
setting_data
.
get
(
'default'
)
self
.
map
=
setting_data
.
get
(
'map'
,
self
.
_default_map
())
if
setting_data
.
get
(
'gtype'
):
self
.
gtype
=
setting_data
.
get
(
'gtype'
)[
0
]
self
.
data
=
setting_data
.
get
(
'data'
,
{})
def
_default_map
(
self
):
if
self
.
type
==
'boolean'
:
# Дефолтная карта для булевых настроек
return
{
True
:
True
,
False
:
False
}
return
{}
def
create_row
(
self
):
widget
=
WidgetFactory
.
create_widget
(
self
)
return
widget
.
create_row
()
if
widget
else
None
def
_get_selected_row_index
(
self
):
current_value
=
self
.
_get_backend_value
()
return
list
(
self
.
map
.
values
())
.
index
(
current_value
)
if
current_value
in
self
.
map
.
values
()
else
0
def
_get_backend_value
(
self
):
backend
=
self
.
_get_backend
()
if
backend
:
return
backend
.
get_value
(
self
.
key
,
self
.
gtype
)
return
self
.
default
def
_set_backend_value
(
self
,
value
):
backend
=
self
.
_get_backend
()
if
backend
:
backend
.
set_value
(
self
.
key
,
value
,
self
.
gtype
)
def
_get_backend
(
self
):
backend
=
backend_factory
.
get_backend
(
self
.
backend
)
if
not
backend
:
print
(
f
"Бекенд {self.backend} не зарегистрирован."
)
return
backend
class
Section
:
def
__init__
(
self
,
section_data
,
strategy
):
self
.
name
=
section_data
[
'name'
]
self
.
weight
=
section_data
.
get
(
'weight'
,
0
)
self
.
settings
=
[
Setting
(
s
)
for
s
in
section_data
.
get
(
'settings'
,
[])]
self
.
strategy
=
strategy
def
create_preferences_group
(
self
):
return
self
.
strategy
.
create_preferences_group
(
self
)
class
SectionStrategy
:
def
create_preferences_group
(
self
,
section
):
raise
NotImplementedError
(
"Метод create_preferences_group должен быть реализован"
)
class
ClassicSectionStrategy
(
SectionStrategy
):
def
create_preferences_group
(
self
,
section
):
group
=
Adw
.
PreferencesGroup
(
title
=
section
.
name
)
for
setting
in
section
.
settings
:
row
=
setting
.
create_row
()
if
row
:
print
(
f
"Добавление строки для настройки: {setting.name}"
)
group
.
add
(
row
)
else
:
print
(
f
"Не удалось создать строку для настройки: {setting.name}"
)
return
group
class
NewSectionStrategy
(
SectionStrategy
):
def
create_preferences_group
(
self
,
section
):
group
=
Adw
.
PreferencesGroup
(
title
=
section
.
name
)
print
(
f
"Создание секции нового типа: {section.name}"
)
for
setting
in
section
.
settings
:
row
=
setting
.
create_row
()
group
.
add
(
row
)
return
group
class
SectionFactory
:
def
__init__
(
self
):
self
.
strategies
=
{
'classic'
:
ClassicSectionStrategy
(),
}
def
create_section
(
self
,
section_data
):
section_type
=
section_data
.
get
(
'type'
,
'classic'
)
strategy
=
self
.
strategies
.
get
(
section_type
)
if
not
strategy
:
raise
ValueError
(
f
"Неизвестный тип секции: {section_type}"
)
return
Section
(
section_data
,
strategy
)
class
Category
:
def
__init__
(
self
,
category_data
,
section_factory
:
SectionFactory
):
self
.
name
=
category_data
[
'name'
]
self
.
weight
=
category_data
.
get
(
'weight'
,
0
)
self
.
sections
=
[
section_factory
.
create_section
(
s
)
for
s
in
category_data
.
get
(
'sections'
,
[])]
def
create_stack_page
(
self
,
stack
):
box
=
Gtk
.
ScrolledWindow
()
pref_page
=
Adw
.
PreferencesPage
()
clamp
=
Adw
.
Clamp
()
clamp
.
set_child
(
pref_page
)
box
.
set_child
(
clamp
)
for
section
in
self
.
sections
:
preferences_group
=
section
.
create_preferences_group
()
if
preferences_group
:
pref_page
.
add
(
preferences_group
)
else
:
print
(
f
"Секция {section.name} не создала виджетов."
)
stack
.
add_child
(
box
)
.
set_title
(
self
.
name
)
def
init_settings_stack
(
stack
):
yaml_files_directory
=
"/usr/share/ximper-tuneit/modules"
# Укажите путь к папке с YAML файлами
yaml_data
=
load_yaml_files_from_directory
(
yaml_files_directory
)
merged_data
=
merge_categories_by_name
(
yaml_data
)
section_factory
=
SectionFactory
()
categories
=
[
Category
(
c
,
section_factory
)
for
c
in
merged_data
]
for
category
in
categories
:
category
.
create_stack_page
(
stack
)
if
not
stack
:
print
(
"Ошибка: settings_pagestack не найден."
)
src/settings/backends.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Gio
,
GLib
class
Backend
:
def
get_value
(
self
,
key
,
gtype
):
raise
NotImplementedError
(
"Метод get_value должен быть реализован"
)
def
set_value
(
self
,
key
,
value
,
gtype
):
raise
NotImplementedError
(
"Метод set_value должен быть реализован"
)
class
GSettingsBackend
(
Backend
):
def
get_value
(
self
,
key
,
gtype
):
schema_name
,
key_name
=
key
.
rsplit
(
'.'
,
1
)
schema
=
Gio
.
Settings
.
new
(
schema_name
)
print
(
f
"[DEBUG] Получение значения: schema={schema_name}, key={key_name}, gtype={gtype}"
)
try
:
value
=
schema
.
get_value
(
key_name
)
return
value
.
unpack
()
except
Exception
as
e
:
print
(
f
"[ERROR] Ошибка при получении значения {key}: {e}"
)
return
None
def
set_value
(
self
,
schema_key
,
value
,
gtype
):
schema_name
,
key_name
=
schema_key
.
rsplit
(
'.'
,
1
)
schema
=
Gio
.
Settings
.
new
(
schema_name
)
print
(
f
"[DEBUG] Установка значения: schema={schema_name}, key={key_name}, value={value}, gtype={gtype}"
)
try
:
schema
.
set_value
(
key_name
,
GLib
.
Variant
(
gtype
,
value
))
except
Exception
as
e
:
print
(
f
"[ERROR] Ошибка при установке значения {schema_key}: {e}"
)
class
BackendFactory
:
def
__init__
(
self
):
self
.
backends
=
{
'gsettings'
:
GSettingsBackend
(),
}
def
get_backend
(
self
,
name
):
return
self
.
backends
.
get
(
name
)
backend_factory
=
BackendFactory
()
src/settings/tools/__init__.py
0 → 100644
View file @
3da4c51e
src/settings/tools/yml_tools.py
0 → 100644
View file @
3da4c51e
import
os
import
yaml
def
load_yaml_files_from_directory
(
directory
):
yaml_data
=
[]
for
root
,
_
,
files
in
os
.
walk
(
directory
):
for
file
in
files
:
if
file
.
endswith
(
".yml"
)
or
file
.
endswith
(
".yaml"
):
file_path
=
os
.
path
.
join
(
root
,
file
)
with
open
(
file_path
,
'r'
,
encoding
=
'utf-8'
)
as
f
:
try
:
data
=
yaml
.
safe_load
(
f
)
if
data
:
yaml_data
.
extend
(
data
)
except
yaml
.
YAMLError
as
e
:
print
(
f
"Ошибка при чтении файла {file_path}: {e}"
)
return
yaml_data
def
merge_categories_by_name
(
categories_data
):
categories_dict
=
{}
for
category_data
in
categories_data
:
category_name
=
category_data
[
'name'
]
if
category_name
not
in
categories_dict
:
categories_dict
[
category_name
]
=
category_data
else
:
categories_dict
[
category_name
][
'sections'
]
.
extend
(
category_data
[
'sections'
])
return
list
(
categories_dict
.
values
())
src/settings/widgets/BaseWidget.py
0 → 100644
View file @
3da4c51e
class
BaseWidget
:
def
__init__
(
self
,
setting
):
self
.
setting
=
setting
def
create_row
(
self
):
raise
NotImplementedError
(
"Метод create_row должен быть реализован в подклассе"
)
src/settings/widgets/BooleanWidget.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
from
.BaseWidget
import
BaseWidget
class
BooleanWidget
(
BaseWidget
):
def
create_row
(
self
):
row
=
Adw
.
SwitchRow
(
title
=
self
.
setting
.
name
,
subtitle
=
self
.
setting
.
help
)
current_value
=
self
.
setting
.
_get_backend_value
()
row
.
set_active
(
current_value
==
self
.
setting
.
map
.
get
(
True
))
row
.
connect
(
"notify::active"
,
self
.
_on_boolean_toggled
)
return
row
def
_on_boolean_toggled
(
self
,
switch
,
_
):
value
=
self
.
setting
.
map
.
get
(
True
)
if
switch
.
get_active
()
else
self
.
setting
.
map
.
get
(
False
)
self
.
setting
.
_set_backend_value
(
value
)
src/settings/widgets/ChoiceWidget.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
,
Gtk
from
.BaseWidget
import
BaseWidget
class
ChoiceWidget
(
BaseWidget
):
def
create_row
(
self
):
row
=
Adw
.
ComboRow
(
title
=
self
.
setting
.
name
,
subtitle
=
self
.
setting
.
help
)
row
.
set_model
(
Gtk
.
StringList
.
new
(
list
(
self
.
setting
.
map
.
keys
())))
row
.
set_selected
(
self
.
setting
.
_get_selected_row_index
())
row
.
connect
(
"notify::selected"
,
self
.
_on_choice_changed
)
return
row
def
_on_choice_changed
(
self
,
combo_row
,
_
):
selected_value
=
list
(
self
.
setting
.
map
.
values
())[
combo_row
.
get_selected
()]
self
.
setting
.
_set_backend_value
(
selected_value
)
src/settings/widgets/EntryWidget.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
from
.BaseWidget
import
BaseWidget
class
EntryWidget
(
BaseWidget
):
def
create_row
(
self
):
row
=
Adw
.
EntryRow
(
title
=
self
.
setting
.
name
)
row
.
set_show_apply_button
(
True
)
row
.
set_text
(
self
.
setting
.
_get_backend_value
())
row
.
connect
(
"apply"
,
self
.
_on_text_changed
)
return
row
def
_on_text_changed
(
self
,
entry_row
):
self
.
setting
.
_set_backend_value
(
entry_row
.
get_text
())
src/settings/widgets/__init__.py
0 → 100644
View file @
3da4c51e
from
.BooleanWidget
import
BooleanWidget
from
.ChoiceWidget
import
ChoiceWidget
from
.EntryWidget
import
EntryWidget
class
WidgetFactory
:
widget_map
=
{
'choice'
:
ChoiceWidget
,
'boolean'
:
BooleanWidget
,
'entry'
:
EntryWidget
}
@staticmethod
def
create_widget
(
setting
):
widget_class
=
WidgetFactory
.
widget_map
.
get
(
setting
.
type
)
if
widget_class
:
return
widget_class
(
setting
)
else
:
print
(
f
"Неизвестный тип виджета: {setting.type}"
)
return
None
src/window.blp
View file @
3da4c51e
...
...
@@ -25,7 +25,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
child: Box {
Adw.NavigationSplitView {
content: Adw.NavigationPage {
Stack
main
_pagestack {}
Stack
settings
_pagestack {}
};
hexpand: true;
...
...
@@ -38,7 +38,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
margin-top: 8;
StackSidebar {
stack:
main
_pagestack;
stack:
settings
_pagestack;
}
}
};
...
...
@@ -46,8 +46,15 @@ template $TuneitWindow: Adw.ApplicationWindow {
};
icon-name: "preferences-system";
name: "main";
title: "main";
name: "settings";
title: _("Settings");
}
Adw.ViewStackPage {
child: Box {};
icon-name: "preferences-system";
name: "shop";
title: _("Shop");
}
}
};
...
...
src/window.py
View file @
3da4c51e
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment