Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
eepm-play-gui
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
0
Merge Requests
0
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
Vladimir Vaskov
eepm-play-gui
Commits
bf943160
Commit
bf943160
authored
Oct 07, 2024
by
Roman Alifanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
redesign + changing the color of the row when the state is changed
parent
6c288648
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
167 additions
and
71 deletions
+167
-71
command_runner.py
src/command_runner.py
+2
-2
eepm-play-gui.gresource.xml
src/eepm-play-gui.gresource.xml
+1
-0
logdialog.cmb
src/logdialog.cmb
+40
-0
logdialog.ui
src/logdialog.ui
+46
-0
window.cmb
src/window.cmb
+1
-1
window.py
src/window.py
+76
-67
window.ui
src/window.ui
+1
-1
No files found.
src/command_runner.py
View file @
bf943160
...
@@ -19,11 +19,11 @@ class CommandRunner:
...
@@ -19,11 +19,11 @@ class CommandRunner:
yes_no_chars
=
'yYдДnNнН'
yes_no_chars
=
'yYдДnNнН'
self
.
dialog
=
dialog
self
.
dialog
=
dialog
self
.
textbuffer
=
dialog
.
get_child
()
.
get_child
()
.
get_child
()
.
get_buffer
()
self
.
textbuffer
=
dialog
.
logdialog_textview
.
get_buffer
()
def
append_log
(
text
):
def
append_log
(
text
):
GLib
.
idle_add
(
self
.
textbuffer
.
insert_at_cursor
,
text
)
GLib
.
idle_add
(
self
.
textbuffer
.
insert_at_cursor
,
text
)
GLib
.
idle_add
(
dialog
.
get_child
()
.
get_child
()
.
get_child
()
.
scroll_to_mark
,
GLib
.
idle_add
(
dialog
.
logdialog_textview
.
scroll_to_mark
,
self
.
textbuffer
.
get_insert
(),
0
,
False
,
0.0
,
1.0
)
self
.
textbuffer
.
get_insert
(),
0
,
False
,
0.0
,
1.0
)
def
remove_ansi_escape_sequences
(
text
):
def
remove_ansi_escape_sequences
(
text
):
...
...
src/eepm-play-gui.gresource.xml
View file @
bf943160
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
<gresource
prefix=
"/ru/eepm/PlayGUI"
>
<gresource
prefix=
"/ru/eepm/PlayGUI"
>
<file>
style.css
</file>
<file>
style.css
</file>
<file
preprocess=
"xml-stripblanks"
>
window.ui
</file>
<file
preprocess=
"xml-stripblanks"
>
window.ui
</file>
<file
preprocess=
"xml-stripblanks"
>
logdialog.ui
</file>
<file
preprocess=
"xml-stripblanks"
>
gtk/help-overlay.ui
</file>
<file
preprocess=
"xml-stripblanks"
>
gtk/help-overlay.ui
</file>
</gresource>
</gresource>
</gresources>
</gresources>
src/logdialog.cmb
0 → 100644
View file @
bf943160
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<cambalache-project
version=
"0.92.0"
target_tk=
"gtk-4.0"
>
<ui>
(1,1,"logdialog.ui","logdialog.ui",None,None,None,None,None,None,None)
</ui>
<ui_library>
(1,"adwaita","1.0",None),
(1,"gtk","4.0",None),
(1,"libadwaita","1.5",None)
</ui_library>
<object>
(1,1,"AdwDialog","LogDialog",None,None,None,None,0,None,None),
(1,2,"AdwClamp",None,1,None,None,None,0,None,None),
(1,3,"GtkBox",None,2,None,None,None,0,None,None),
(1,4,"GtkScrolledWindow",None,3,None,None,None,0,None,None),
(1,5,"GtkTextView","logdialog_textview",4,None,None,None,0,"",None)
</object>
<object_property>
(1,1,"AdwDialog","can-close","false",0,None,None,None,None,None,None,None,None),
(1,1,"AdwDialog","follows-content-size","true",0,None,None,None,None,None,None,None,None),
(1,1,"AdwDialog","title","Лог выполнения",0,None,None,None,None,None,None,None,None),
(1,2,"AdwClamp","maximum-size","500",0,None,None,None,None,None,None,None,None),
(1,2,"GtkWidget","margin-bottom","12",0,None,None,None,None,None,None,None,None),
(1,2,"GtkWidget","margin-end","12",0,None,None,None,None,None,None,None,None),
(1,2,"GtkWidget","margin-start","12",0,None,None,None,None,None,None,None,None),
(1,2,"GtkWidget","margin-top","12",0,None,None,None,None,None,None,None,None),
(1,3,"GtkBox","spacing","12",0,None,None,None,None,None,None,None,None),
(1,3,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
(1,4,"GtkWidget","height-request","259",0,None,None,None,None,None,None,None,None),
(1,4,"GtkWidget","vexpand","true",0,None,None,None,None,None,None,None,None),
(1,4,"GtkWidget","width-request","304",0,None,None,None,None,None,None,None,None),
(1,5,"GtkTextView","cursor-visible","false",0,None,None,None,None,None,None,None,None),
(1,5,"GtkTextView","editable","false",0,None,None,None,None,None,None,None,None),
(1,5,"GtkTextView","monospace","True",0,None,None,None,None,None,None,None,None),
(1,5,"GtkWidget","can-focus","False",None,None,None,None,None,None,None,None,None),
(1,5,"GtkWidget","can-target","False",None,None,None,None,None,None,None,None,None),
(1,5,"GtkWidget","focus-on-click","False",None,None,None,None,None,None,None,None,None)
</object_property>
</cambalache-project>
src/logdialog.ui
0 → 100644
View file @
bf943160
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.92.0 -->
<interface>
<!-- interface-name logdialog.ui -->
<requires
lib=
"adwaita"
version=
"1.0"
/>
<requires
lib=
"gtk"
version=
"4.0"
/>
<requires
lib=
"libadwaita"
version=
"1.5"
/>
<template
class=
"LogDialog"
parent=
"AdwDialog"
>
<property
name=
"can-close"
>
false
</property>
<property
name=
"follows-content-size"
>
true
</property>
<property
name=
"title"
>
Лог выполнения
</property>
<child>
<object
class=
"AdwClamp"
>
<property
name=
"margin-bottom"
>
12
</property>
<property
name=
"margin-end"
>
12
</property>
<property
name=
"margin-start"
>
12
</property>
<property
name=
"margin-top"
>
12
</property>
<property
name=
"maximum-size"
>
500
</property>
<child>
<object
class=
"GtkBox"
>
<property
name=
"orientation"
>
vertical
</property>
<property
name=
"spacing"
>
12
</property>
<child>
<object
class=
"GtkScrolledWindow"
>
<property
name=
"height-request"
>
259
</property>
<property
name=
"vexpand"
>
true
</property>
<property
name=
"width-request"
>
304
</property>
<child>
<object
class=
"GtkTextView"
id=
"logdialog_textview"
>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"can-target"
>
False
</property>
<property
name=
"cursor-visible"
>
false
</property>
<property
name=
"editable"
>
false
</property>
<property
name=
"focus-on-click"
>
False
</property>
<property
name=
"monospace"
>
True
</property>
<!-- Custom object fragments -->
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>
src/window.cmb
View file @
bf943160
...
@@ -82,7 +82,7 @@
...
@@ -82,7 +82,7 @@
</object_data>
</object_data>
<object_data_arg>
<object_data_arg>
(1,7,"GtkWidget",2,2,"name","linked"),
(1,7,"GtkWidget",2,2,"name","linked"),
(1,12,"GtkWidget",2,2,"name","boxed-list"),
(1,12,"GtkWidget",2,2,"name","boxed-list
-separate
"),
(1,15,"GtkWidget",2,2,"name","boxed-list"),
(1,15,"GtkWidget",2,2,"name","boxed-list"),
(1,22,"GtkWidget",2,2,"name","suggested-action")
(1,22,"GtkWidget",2,2,"name","suggested-action")
</object_data_arg>
</object_data_arg>
...
...
src/window.py
View file @
bf943160
...
@@ -26,39 +26,54 @@ _ = gettext.gettext
...
@@ -26,39 +26,54 @@ _ = gettext.gettext
from
.appsmanager
import
ApplicationManager
from
.appsmanager
import
ApplicationManager
from
.command_runner
import
CommandRunner
from
.command_runner
import
CommandRunner
class
ApplicationRow
(
Adw
.
ActionRow
):
def
__init__
(
self
,
app
,
is_installed
,
on_toggle
):
super
()
.
__init__
(
title
=
app
[
'name'
],
subtitle
=
app
[
'dscr'
])
self
.
app
=
app
self
.
is_installed
=
is_installed
self
.
checkbox
=
Gtk
.
CheckButton
()
self
.
checkbox
.
add_css_class
(
"selection-mode"
)
self
.
checkbox
.
set_active
(
is_installed
)
self
.
checkbox
.
connect
(
"toggled"
,
self
.
on_checkbox_toggled
)
self
.
add_suffix
(
self
.
checkbox
)
self
.
on_toggle
=
on_toggle
# Callback for when the checkbox is toggled
def
on_checkbox_toggled
(
self
,
checkbox
):
self
.
on_toggle
(
self
.
app
[
'name'
],
checkbox
.
get_active
())
self
.
update_row_css
()
# Update the row's style when toggled
def
is_changed
(
self
):
"""Determine if the checkbox state has changed compared to the installed state."""
return
self
.
checkbox
.
get_active
()
!=
self
.
is_installed
def
update_row_css
(
self
):
"""Update the CSS classes for the row based on the checkbox state."""
for
css
in
[
"marked-for-install"
,
"marked-for-removal"
,
"unchanged"
]:
self
.
remove_css_class
(
css
)
# Add the appropriate class based on the current checkbox state
if
self
.
is_changed
():
if
self
.
checkbox
.
get_active
():
self
.
add_css_class
(
"marked-for-install"
)
print
(
"marked-for-install"
)
else
:
self
.
add_css_class
(
"marked-for-removal"
)
print
(
"marked-for-removal"
)
else
:
# self.add_css_class("unchanged")
print
(
"marked-unchanged"
)
@Gtk.Template
(
resource_path
=
'/ru/eepm/PlayGUI/logdialog.ui'
)
class
LogDialog
(
Adw
.
Dialog
):
class
LogDialog
(
Adw
.
Dialog
):
__gtype_name__
=
'LogDialog'
logdialog_textview
=
Gtk
.
Template
.
Child
()
def
__init__
(
self
,
win
,
**
kwargs
):
def
__init__
(
self
,
win
,
**
kwargs
):
super
()
.
__init__
(
**
kwargs
)
super
()
.
__init__
(
**
kwargs
)
self
.
set_title
(
"Лог выполнения"
)
self
.
set_can_close
(
False
)
self
.
set_follows_content_size
(
True
)
self
.
win
=
win
self
.
win
=
win
dialog_clamp
=
Adw
.
Clamp
(
margin_bottom
=
12
,
margin_end
=
12
,
margin_top
=
12
,
margin_start
=
12
,
maximum_size
=
500
)
textview
=
Gtk
.
TextView
()
textview
.
set_editable
(
False
)
textview
.
set_cursor_visible
(
False
)
textbuffer
=
textview
.
get_buffer
()
scrolled_window
=
Gtk
.
ScrolledWindow
(
width_request
=
304
,
height_request
=
259
)
scrolled_window
.
set_child
(
textview
)
scrolled_window
.
set_vexpand
(
True
)
dialog_clamp
.
set_child
(
scrolled_window
)
self
.
set_child
(
dialog_clamp
)
def
run
(
self
,
command
,
on_done
):
def
run
(
self
,
command
,
on_done
):
self
.
present
(
self
.
win
)
self
.
present
(
self
.
win
)
# Создание и передача функции обратного вызова для обновления UI
# Создание и передача функции обратного вызова для обновления UI
...
@@ -67,11 +82,10 @@ class LogDialog(Adw.Dialog):
...
@@ -67,11 +82,10 @@ class LogDialog(Adw.Dialog):
@Gtk.Template
(
resource_path
=
'/ru/eepm/PlayGUI/window.ui'
)
@Gtk.Template
(
resource_path
=
'/ru/eepm/PlayGUI/window.ui'
)
class
EepmPlayGuiWindow
(
Adw
.
ApplicationWindow
,
LogDialog
):
class
EepmPlayGuiWindow
(
Adw
.
ApplicationWindow
):
__gtype_name__
=
'EepmPlayGuiWindow'
__gtype_name__
=
'EepmPlayGuiWindow'
search_entry
=
Gtk
.
Template
.
Child
()
search_entry
=
Gtk
.
Template
.
Child
()
search_dropdown
=
Gtk
.
Template
.
Child
()
search_dropdown
=
Gtk
.
Template
.
Child
()
loading_spinner
=
Gtk
.
Template
.
Child
()
loading_spinner
=
Gtk
.
Template
.
Child
()
choice_listbox
=
Gtk
.
Template
.
Child
()
choice_listbox
=
Gtk
.
Template
.
Child
()
apply_button
=
Gtk
.
Template
.
Child
()
apply_button
=
Gtk
.
Template
.
Child
()
...
@@ -82,10 +96,10 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
...
@@ -82,10 +96,10 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
self
.
checkboxes
=
None
self
.
checkboxes
=
None
self
.
apply_button
.
connect
(
"activated"
,
self
.
on_apply_clicked
)
self
.
apply_button
.
connect
(
"activated"
,
self
.
on_apply_clicked
)
self
.
search_entry
.
connect
(
"search-changed"
,
self
.
on_search_changed
)
self
.
search_entry
.
connect
(
"search-changed"
,
self
.
on_search_changed
)
self
.
search_dropdown
.
connect
(
"notify::selected"
,
self
.
on_filter_changed
)
self
.
search_dropdown
.
connect
(
"notify::selected"
,
self
.
on_filter_changed
)
self
.
choice_listbox
.
set_filter_func
(
self
.
listbox_filter_func
)
self
.
choice_listbox
.
set_filter_func
(
self
.
listbox_filter_func
)
self
.
dialog
=
LogDialog
(
win
=
self
)
self
.
dialog
=
LogDialog
(
win
=
self
)
...
@@ -132,43 +146,39 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
...
@@ -132,43 +146,39 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
self
.
choice_listbox
.
remove_all
()
self
.
choice_listbox
.
remove_all
()
def
add_application_row
(
self
,
app
):
def
add_application_row
(
self
,
app
):
row
=
Adw
.
ActionRow
(
"""Adds an application row to the listbox."""
title
=
app
[
'name'
],
row
=
ApplicationRow
(
subtitle
=
app
[
'dscr'
]
app
=
app
,
is_installed
=
app
[
'name'
]
in
self
.
installed_apps
,
on_toggle
=
self
.
on_checkbox_toggled
)
)
checkbox
=
Gtk
.
CheckButton
()
checkbox
.
add_css_class
(
"selection-mode"
)
checkbox
.
set_active
(
app
[
'name'
]
in
self
.
installed_apps
)
checkbox
.
connect
(
"toggled"
,
self
.
on_checkbox_toggled
,
app
[
'name'
])
row
.
add_suffix
(
checkbox
)
self
.
choice_listbox
.
append
(
row
)
self
.
choice_listbox
.
append
(
row
)
self
.
checkboxes
[
app
[
'name'
]]
=
checkbox
self
.
checkboxes
[
app
[
'name'
]]
=
row
def
on_checkbox_toggled
(
self
,
checkbox
,
app_name
):
def
on_checkbox_toggled
(
self
,
app_name
,
active
):
active
=
checkbox
.
get_active
()
print
(
f
"{app_name} {'установлен' if active else 'снят'}"
)
print
(
f
"{app_name} {'установлен' if active else 'снят'}"
)
self
.
update_button_status
()
self
.
update_button_status
()
def
update_button_status
(
self
):
def
update_button_status
(
self
):
"""Update the button status based on the current selection."""
to_install
,
to_remove
=
self
.
get_install_remove_lists
()
to_install
,
to_remove
=
self
.
get_install_remove_lists
()
self
.
apply_button
.
remove_css_class
(
"suggested-action"
)
self
.
apply_button
.
remove_css_class
(
"destructive-action"
)
button_states
=
{
if
to_install
and
to_remove
:
(
True
,
True
):
(
_
(
"Remove and install applications"
),
"suggested-action"
),
self
.
apply_button
.
add_css_class
(
"suggested-action"
)
(
True
,
False
):
(
_
(
"Install applications"
),
"suggested-action"
),
self
.
apply_button
.
set_title
(
_
(
"Remove and install applications"
))
(
False
,
True
):
(
_
(
"Remove applications"
),
"destructive-action"
),
elif
to_install
:
(
False
,
False
):
(
_
(
"Update applications"
),
"suggested-action"
),
self
.
apply_button
.
add_css_class
(
"suggested-action"
)
}
self
.
apply_button
.
set_title
(
_
(
"Install applications"
))
elif
to_remove
:
title
,
css_class
=
button_states
[(
bool
(
to_install
),
bool
(
to_remove
))]
self
.
apply_button
.
add_css_class
(
"destructive-action"
)
self
.
apply_button
.
set_title
(
title
)
self
.
apply_button
.
set_title
(
_
(
"Remove applications"
))
else
:
# Remove all previous CSS classes in a loop
self
.
apply_button
.
add_css_class
(
"suggested-action"
)
for
css
in
[
"suggested-action"
,
"destructive-action"
]:
self
.
apply_button
.
set_title
(
_
(
"Update applications"
))
self
.
apply_button
.
remove_css_class
(
css
)
# Add the new CSS class
self
.
apply_button
.
add_css_class
(
css_class
)
def
on_search_changed
(
self
,
search_entry
):
def
on_search_changed
(
self
,
search_entry
):
self
.
choice_listbox
.
invalidate_filter
()
# Обновление фильтра при изменении поиска
self
.
choice_listbox
.
invalidate_filter
()
# Обновление фильтра при изменении поиска
...
@@ -177,7 +187,7 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
...
@@ -177,7 +187,7 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
self
.
choice_listbox
.
invalidate_filter
()
# Обновление фильтра при изменении фильтра
self
.
choice_listbox
.
invalidate_filter
()
# Обновление фильтра при изменении фильтра
def
listbox_filter_func
(
self
,
row
):
def
listbox_filter_func
(
self
,
row
):
"""Функция фильтрации для GtkListBox, которая проверяет текст и состояние фильтра"""
"""Функция фильтрации для GtkListBox, которая проверяет текст и состояние фильтра
.
"""
search_text
=
self
.
search_entry
.
get_text
()
.
lower
()
search_text
=
self
.
search_entry
.
get_text
()
.
lower
()
filter_option
=
self
.
search_dropdown
.
get_selected
()
filter_option
=
self
.
search_dropdown
.
get_selected
()
...
@@ -211,14 +221,14 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
...
@@ -211,14 +221,14 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
else
:
else
:
self
.
dialog
.
run
(
"pkexec epm play --update all"
,
on_done
=
self
.
update_ui
)
self
.
dialog
.
run
(
"pkexec epm play --update all"
,
on_done
=
self
.
update_ui
)
def
get_install_remove_lists
(
self
):
def
get_install_remove_lists
(
self
):
if
self
.
checkboxes
:
if
self
.
checkboxes
:
to_install
=
[
app_name
for
app_name
,
checkbox
in
self
.
checkboxes
.
items
()
if
checkbox
.
get_active
()
and
app_name
not
in
self
.
installed_apps
]
to_install
=
[
app_name
for
app_name
,
row
in
self
.
checkboxes
.
items
()
if
row
.
checkbox
.
get_active
()
and
app_name
not
in
self
.
installed_apps
]
to_remove
=
[
app_name
for
app_name
,
checkbox
in
self
.
checkboxes
.
items
()
if
not
checkbox
.
get_active
()
and
app_name
in
self
.
installed_apps
]
to_remove
=
[
app_name
for
app_name
,
row
in
self
.
checkboxes
.
items
()
if
not
row
.
checkbox
.
get_active
()
and
app_name
in
self
.
installed_apps
]
return
to_install
,
to_remove
return
to_install
,
to_remove
else
:
else
:
return
False
,
False
return
False
,
False
def
build_commands
(
self
,
to_install
,
to_remove
):
def
build_commands
(
self
,
to_install
,
to_remove
):
commands
=
[]
commands
=
[]
if
to_install
:
if
to_install
:
...
@@ -226,4 +236,3 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
...
@@ -226,4 +236,3 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow, LogDialog):
if
to_remove
:
if
to_remove
:
commands
.
append
(
f
"epm play --auto --remove {' '.join(to_remove)}"
)
commands
.
append
(
f
"epm play --auto --remove {' '.join(to_remove)}"
)
return
commands
return
commands
src/window.ui
View file @
bf943160
...
@@ -74,7 +74,7 @@
...
@@ -74,7 +74,7 @@
<child>
<child>
<object
class=
"GtkListBox"
id=
"choice_listbox"
>
<object
class=
"GtkListBox"
id=
"choice_listbox"
>
<style>
<style>
<class
name=
"boxed-list"
/>
<class
name=
"boxed-list
-separate
"
/>
</style>
</style>
</object>
</object>
</child>
</child>
...
...
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