Add desktop page
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 3 0 c -1.660156 0 -3 1.339844 -3 3 v 7 c 0 1.660156 1.339844 3 3 3 h 10 c 1.660156 0 3 -1.339844 3 -3 v -7 c 0 -1.660156 -1.339844 -3 -3 -3 z m 0 2 h 10 c 0.554688 0 1 0.445312 1 1 v 7 c 0 0.554688 -0.445312 1 -1 1 h -10 c -0.554688 0 -1 -0.445312 -1 -1 v -7 c 0 -0.554688 0.445312 -1 1 -1 z m 2 12 c -1.105469 0 -2 0.894531 -2 2 h 10 c 0 -1.105469 -0.894531 -2 -2 -2 z m 0 0" fill="#2e3436"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 543 B |
@@ -6,6 +6,7 @@ blueprints = custom_target('blueprints',
|
||||
'ui/main_window.blp',
|
||||
'ui/pages/choices.blp',
|
||||
'ui/pages/confirm.blp',
|
||||
'ui/pages/desktop.blp',
|
||||
'ui/pages/disk.blp',
|
||||
'ui/pages/done.blp',
|
||||
'ui/pages/encrypt.blp',
|
||||
@@ -23,6 +24,7 @@ blueprints = custom_target('blueprints',
|
||||
'ui/pages/summary.blp',
|
||||
'ui/pages/user.blp',
|
||||
'ui/pages/welcome.blp',
|
||||
'ui/widgets/desktop_entry.blp',
|
||||
'ui/widgets/device_row.blp',
|
||||
'ui/widgets/multi_selection_row.blp',
|
||||
'ui/widgets/page_wrapper.blp',
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<file>style.css</file>
|
||||
|
||||
<!-- Icons -->
|
||||
<file preprocess="xml-stripblanks">icon/scalable/actions/computer-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icon/scalable/actions/globe-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icon/scalable/actions/language-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">icon/scalable/actions/map-symbolic.svg</file>
|
||||
@@ -24,6 +25,7 @@
|
||||
|
||||
<file preprocess="xml-stripblanks">ui/pages/choices.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/pages/confirm.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/pages/desktop.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/pages/disk.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/pages/done.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/pages/encrypt.ui</file>
|
||||
@@ -42,6 +44,7 @@
|
||||
<file preprocess="xml-stripblanks">ui/pages/user.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/pages/welcome.ui</file>
|
||||
|
||||
<file preprocess="xml-stripblanks">ui/widgets/desktop_entry.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/widgets/device_row.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/widgets/multi_selection_row.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/widgets/page_wrapper.ui</file>
|
||||
|
||||
44
data/resources/ui/pages/desktop.blp
Normal file
44
data/resources/ui/pages/desktop.blp
Normal file
@@ -0,0 +1,44 @@
|
||||
using Gtk 4.0;
|
||||
using Gio 2.0;
|
||||
|
||||
Gio.ListStore model {}
|
||||
|
||||
template $DesktopPage: Box {
|
||||
orientation: vertical;
|
||||
spacing:12;
|
||||
|
||||
Picture selected_image {
|
||||
content-fit: contain;
|
||||
halign: center;
|
||||
height-request: 178;
|
||||
styles ["card"]
|
||||
}
|
||||
|
||||
Label selected_description {
|
||||
margin-end: 12;
|
||||
margin-start: 12;
|
||||
ellipsize: end;
|
||||
lines: 3;
|
||||
}
|
||||
|
||||
Button continue_button {
|
||||
/* Translators: On button, brackets will be replaced with desktop name. */
|
||||
label: _("_Use {}");
|
||||
focusable: true;
|
||||
receives-default: true;
|
||||
halign: center;
|
||||
valign: center;
|
||||
use-underline: true;
|
||||
clicked => $continue();
|
||||
styles ["suggested-action", "pill"]
|
||||
}
|
||||
|
||||
Grid grid {
|
||||
column-homogeneous: true;
|
||||
row-homogeneous: true;
|
||||
column-spacing: 12;
|
||||
row-spacing: 12;
|
||||
hexpand: true;
|
||||
}
|
||||
}
|
||||
|
||||
27
data/resources/ui/widgets/desktop_entry.blp
Normal file
27
data/resources/ui/widgets/desktop_entry.blp
Normal file
@@ -0,0 +1,27 @@
|
||||
using Gtk 4.0;
|
||||
|
||||
template $DesktopEntry: Button {
|
||||
overflow: hidden;
|
||||
styles ["card"]
|
||||
|
||||
child: Box {
|
||||
halign: center;
|
||||
orientation: vertical;
|
||||
|
||||
Picture image {
|
||||
content-fit: contain;
|
||||
halign: center;
|
||||
height-request: 80;
|
||||
}
|
||||
|
||||
Label name {
|
||||
ellipsize: none;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 6;
|
||||
margin-bottom: 6;
|
||||
|
||||
styles ["heading"]
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -58,6 +58,32 @@ minimum_disk_size: 5
|
||||
# Default: yes
|
||||
offer_disk_encryption: yes
|
||||
|
||||
# Provide multiple desktop environments to choose from
|
||||
#
|
||||
# name string Name of desktop. Translatable.
|
||||
# description string Optional. Short descripiton of the desktop.
|
||||
# image_path string Absolute path of an image to display.
|
||||
# keyword string Forwarded to the installation script as is.
|
||||
#
|
||||
# Default: [] (no desktop selection page)
|
||||
desktop:
|
||||
- name : 'GNOME'
|
||||
description : 'Simple desktop that can be personalized with extensions.'
|
||||
image_path : '/etc/os-installer/desktops/gnome.jpg'
|
||||
keyword : 'gnome'
|
||||
- name : 'KDE Plasma'
|
||||
description : 'Configurable desktop that is similar to Windows.'
|
||||
image_path : '/etc/os-installer/desktops/kde.png'
|
||||
keyword : 'kde'
|
||||
- name : 'Xfce'
|
||||
description : 'Lightweight desktop with focus on modularity.'
|
||||
image_path : '/etc/os-installer/desktops/xfce.png'
|
||||
keyword : 'xfce'
|
||||
- name : 'Enlightenment'
|
||||
description : 'Highly configurable, lightweight desktop for tinkerers.'
|
||||
image_path : '/etc/os-installer/desktops/enlightenment.png'
|
||||
keyword : 'enlightenment'
|
||||
|
||||
# gnome-initial-setup can handle user and locale setup.
|
||||
# These settings allow to disable these pages.
|
||||
#
|
||||
|
||||
BIN
example_config/desktops/enlightenment.png
Normal file
BIN
example_config/desktops/enlightenment.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
BIN
example_config/desktops/gnome.jpg
Normal file
BIN
example_config/desktops/gnome.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
BIN
example_config/desktops/kde.png
Normal file
BIN
example_config/desktops/kde.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 647 KiB |
BIN
example_config/desktops/xfce.png
Normal file
BIN
example_config/desktops/xfce.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 563 KiB |
@@ -3,6 +3,7 @@
|
||||
# This is an example installer script. For OS-Installer to use it, place it at:
|
||||
# /etc/os-installer/scripts/install.sh
|
||||
# The script gets called with the following environment variables set:
|
||||
# OSI_DESKTOP : Desktop keyword, or empty if 'desktop' was not configured
|
||||
# OSI_LOCALE : Locale to be used in the new system
|
||||
# OSI_DEVICE_PATH : Device path at which to install
|
||||
# OSI_DEVICE_IS_PARTITION : 1 if the specified device is a partition (0 -> disk)
|
||||
@@ -11,7 +12,8 @@
|
||||
# OSI_ENCRYPTION_PIN : The encryption pin to use (if encryption is set)
|
||||
|
||||
# sanity check that all variables were set
|
||||
if [ -z ${OSI_LOCALE+x} ] || \
|
||||
if [ -z ${OSI_DESKTOP+x} ] || \
|
||||
[ -z ${OSI_LOCALE+x} ] || \
|
||||
[ -z ${OSI_KEYBOARD_LAYOUT+x} ] || \
|
||||
[ -z ${OSI_DEVICE_PATH+x} ] || \
|
||||
[ -z ${OSI_DEVICE_IS_PARTITION+x} ] || \
|
||||
@@ -26,6 +28,7 @@ fi
|
||||
echo 'Installation started.'
|
||||
echo ''
|
||||
echo 'Variables set to:'
|
||||
echo 'OSI_DESKTOP ' $OSI_DESKTOP
|
||||
echo 'OSI_LOCALE ' $OSI_LOCALE
|
||||
echo 'OSI_KEYBOARD_LAYOUT ' $OSI_KEYBOARD_LAYOUT
|
||||
echo 'OSI_DEVICE_PATH ' $OSI_DEVICE_PATH
|
||||
|
||||
@@ -7,6 +7,7 @@ data/resources/ui/main_window.blp
|
||||
|
||||
data/resources/ui/pages/choices.blp
|
||||
data/resources/ui/pages/confirm.blp
|
||||
data/resources/ui/pages/desktop.blp
|
||||
data/resources/ui/pages/disk.blp
|
||||
data/resources/ui/pages/done.blp
|
||||
data/resources/ui/pages/encrypt.blp
|
||||
@@ -14,12 +15,10 @@ data/resources/ui/pages/failed.blp
|
||||
data/resources/ui/pages/filter.blp
|
||||
data/resources/ui/pages/install.blp
|
||||
data/resources/ui/pages/internet.blp
|
||||
data/resources/ui/pages/keyboard_language.blp
|
||||
data/resources/ui/pages/keyboard_layout.blp
|
||||
data/resources/ui/pages/keyboard_overview.blp
|
||||
data/resources/ui/pages/locale.blp
|
||||
data/resources/ui/pages/partition.blp
|
||||
data/resources/ui/pages/restart.blp
|
||||
data/resources/ui/pages/summary.blp
|
||||
data/resources/ui/pages/user.blp
|
||||
data/resources/ui/pages/welcome.blp
|
||||
|
||||
@@ -22,6 +22,8 @@ default_config = {
|
||||
# disk
|
||||
'minimum_disk_size': 5,
|
||||
'offer_disk_encryption': True,
|
||||
# desktop
|
||||
'desktop': [],
|
||||
# optional pages
|
||||
'skip_user': False,
|
||||
'skip_locale': False,
|
||||
@@ -43,6 +45,7 @@ internal_values = {
|
||||
'internet_connection': False,
|
||||
'use_encryption': False,
|
||||
'encryption_pin': '',
|
||||
'desktop_chosen': '',
|
||||
'user_name': '',
|
||||
'user_autologin': False,
|
||||
'user_password': '',
|
||||
|
||||
@@ -23,6 +23,7 @@ os_installer_sources = [
|
||||
'global_state.py',
|
||||
'main.py',
|
||||
'provider/choices_provider.py',
|
||||
'provider/desktop_provider.py',
|
||||
'provider/disk_provider.py',
|
||||
'provider/format_provider.py',
|
||||
'provider/internet_provider.py',
|
||||
@@ -33,6 +34,7 @@ os_installer_sources = [
|
||||
'ui/page_wrapper.py',
|
||||
'ui/pages/choices.py',
|
||||
'ui/pages/confirm.py',
|
||||
'ui/pages/desktop.py',
|
||||
'ui/pages/disk.py',
|
||||
'ui/pages/done.py',
|
||||
'ui/pages/encrypt.py',
|
||||
|
||||
38
src/provider/desktop_provider.py
Normal file
38
src/provider/desktop_provider.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from typing import NamedTuple
|
||||
|
||||
from .config import config
|
||||
from .preloadable import Preloadable
|
||||
|
||||
|
||||
class Desktop(NamedTuple):
|
||||
name: str
|
||||
description: str
|
||||
image_path: str
|
||||
keyword: str
|
||||
|
||||
|
||||
class DesktopProvider(Preloadable):
|
||||
def __init__(self):
|
||||
Preloadable.__init__(self, self._get_desktops)
|
||||
|
||||
def _get_desktops(self):
|
||||
self.desktops: list = []
|
||||
for entry in config.get('desktop'):
|
||||
if not set(entry).issuperset(['name', 'keyword', 'image_path']):
|
||||
print(f'Desktop choice not correctly configured: {entry}')
|
||||
continue
|
||||
description = entry['description'] if 'description' in entry else ''
|
||||
desktop = Desktop(entry['name'], description,
|
||||
entry['image_path'], entry['keyword'])
|
||||
self.desktops.append(desktop)
|
||||
|
||||
### public methods ###
|
||||
|
||||
def get_desktops(self):
|
||||
self.assert_preloaded()
|
||||
return self.desktops
|
||||
|
||||
|
||||
desktop_provider = DesktopProvider()
|
||||
@@ -3,12 +3,13 @@
|
||||
from threading import Thread
|
||||
|
||||
from .choices_provider import choices_provider
|
||||
from .desktop_provider import desktop_provider
|
||||
from .disk_provider import disk_provider
|
||||
from .internet_provider import internet_provider
|
||||
from .language_provider import language_provider
|
||||
|
||||
providers = [language_provider, internet_provider,
|
||||
disk_provider, choices_provider]
|
||||
disk_provider, desktop_provider, choices_provider]
|
||||
|
||||
|
||||
class PreloadManager:
|
||||
|
||||
@@ -9,6 +9,7 @@ from .config import config
|
||||
|
||||
from .choices import FeaturePage, SoftwarePage
|
||||
from .confirm import ConfirmPage
|
||||
from .desktop import DesktopPage
|
||||
from .disk import DiskPage
|
||||
from .done import DonePage
|
||||
from .encrypt import EncryptPage
|
||||
@@ -29,6 +30,8 @@ page_name_to_page_title = {
|
||||
# Translators: Page title
|
||||
'confirm': _('Confirmation'),
|
||||
# Translators: Page title
|
||||
'desktop': _('Desktop Selection'),
|
||||
# Translators: Page title
|
||||
'disk': _('Disk Selection'),
|
||||
# Translators: Page title
|
||||
'done': _('Installation Complete'),
|
||||
@@ -72,6 +75,7 @@ page_name_to_page_title = {
|
||||
|
||||
page_name_to_image = {
|
||||
'confirm': 'question-round-symbolic',
|
||||
'desktop': 'computer-symbolic',
|
||||
'disk': 'drive-harddisk-system-symbolic',
|
||||
'done': 'success-symbolic',
|
||||
'encrypt': 'dialog-password-symbolic',
|
||||
@@ -96,6 +100,7 @@ special_image_pages = {'internet', 'welcome'}
|
||||
|
||||
page_name_to_type = {
|
||||
'confirm': ConfirmPage,
|
||||
'desktop': DesktopPage,
|
||||
'disk': DiskPage,
|
||||
'done': DonePage,
|
||||
'encrypt': EncryptPage,
|
||||
|
||||
48
src/ui/pages/desktop.py
Normal file
48
src/ui/pages/desktop.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from gi.repository import Gtk
|
||||
|
||||
from .config import config
|
||||
from .global_state import global_state
|
||||
from .desktop_provider import desktop_provider
|
||||
from .widgets import DesktopEntry
|
||||
|
||||
|
||||
@Gtk.Template(resource_path='/com/github/p3732/os-installer/ui/pages/desktop.ui')
|
||||
class DesktopPage(Gtk.Box):
|
||||
__gtype_name__ = __qualname__
|
||||
|
||||
grid = Gtk.Template.Child()
|
||||
continue_button = Gtk.Template.Child()
|
||||
selected_description = Gtk.Template.Child()
|
||||
selected_image = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.button_label = self.continue_button.get_label()
|
||||
|
||||
number = 0
|
||||
for desktop in desktop_provider.get_desktops():
|
||||
if number == 0:
|
||||
self._set_selected_desktop(desktop)
|
||||
entry = DesktopEntry(desktop)
|
||||
entry.connect('clicked', self._desktop_activated)
|
||||
self.grid.attach(entry, number % 3, int(number/3), 1, 1)
|
||||
number += 1
|
||||
|
||||
def _set_selected_desktop(self, desktop):
|
||||
self.continue_button.set_label(self.button_label.format(desktop.name))
|
||||
self.selected_image.set_filename(desktop.image_path)
|
||||
self.selected_description.set_label(desktop.description)
|
||||
config.set('desktop_chosen', desktop.keyword)
|
||||
|
||||
### callbacks ###
|
||||
|
||||
def _desktop_activated(self, button):
|
||||
self._set_selected_desktop(button.desktop)
|
||||
|
||||
@Gtk.Template.Callback('continue')
|
||||
def _continue(self, object):
|
||||
if self.continue_button.is_sensitive():
|
||||
global_state.advance(self)
|
||||
@@ -12,6 +12,21 @@ def reset_model(model, new_values):
|
||||
model.splice(0, n_prev_items, new_values)
|
||||
|
||||
|
||||
@Gtk.Template(resource_path='/com/github/p3732/os-installer/ui/widgets/desktop_entry.ui')
|
||||
class DesktopEntry(Gtk.Button):
|
||||
__gtype_name__ = __qualname__
|
||||
|
||||
image = Gtk.Template.Child()
|
||||
name = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, desktop, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.desktop = desktop
|
||||
self.name.set_label(desktop.name)
|
||||
self.image.set_filename(desktop.image_path)
|
||||
|
||||
|
||||
@Gtk.Template(resource_path='/com/github/p3732/os-installer/ui/widgets/device_row.ui')
|
||||
class DeviceRow(Adw.ActionRow):
|
||||
__gtype_name__ = __qualname__
|
||||
|
||||
@@ -111,6 +111,7 @@ class OsInstallerWindow(Adw.ApplicationWindow):
|
||||
('disk', True),
|
||||
('partition', True),
|
||||
('encrypt', config.get('offer_disk_encryption')),
|
||||
('desktop', config.get('desktop')),
|
||||
('confirm', exists('/etc/os-installer/scripts/install.sh')),
|
||||
# configuration section
|
||||
('user', not config.get('skip_user')),
|
||||
|
||||
@@ -36,6 +36,7 @@ def create_envs(installation_step: InstallationStep):
|
||||
envs = []
|
||||
if with_install_envs:
|
||||
envs += [
|
||||
f'OSI_DESKTOP={_get("desktop_chosen")}',
|
||||
f'OSI_LOCALE={_get("locale")}',
|
||||
f'OSI_KEYBOARD_LAYOUT={_get("keyboard_layout")}',
|
||||
f'OSI_DEVICE_PATH={_get("disk")}',
|
||||
|
||||
Reference in New Issue
Block a user