Skip to content

Commit 63b66ca

Browse files
Add really useful app size dialog (#452)
1 parent ce87df6 commit 63b66ca

File tree

8 files changed

+366
-1
lines changed

8 files changed

+366
-1
lines changed

po/POTFILES.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ src/bz-addons-dialog.blp
77
src/bz-addons-dialog.c
88
src/bz-app-tile.blp
99
src/bz-app-tile.c
10+
src/bz-app-size-dialog.c
11+
src/bz-app-size-dialog.blp
1012
src/bz-application-map-factory.c
1113
src/bz-application.c
1214
src/bz-async-texture.c

src/bazaar.gresource.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<file preprocess="xml-stripblanks">bz-addons-dialog.ui</file>
1313
<file preprocess="xml-stripblanks">bz-app-tile.ui</file>
1414
<file preprocess="xml-stripblanks">bz-apps-page.ui</file>
15+
<file preprocess="xml-stripblanks">bz-app-size-dialog.ui</file>
1516
<file preprocess="xml-stripblanks">bz-browse-widget.ui</file>
1617
<file preprocess="xml-stripblanks">bz-curated-app-tile.ui</file>
1718
<file preprocess="xml-stripblanks">bz-category-tile.ui</file>

src/bz-app-size-dialog.blp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using Gtk 4.0;
2+
using Adw 1;
3+
4+
template $BzAppSizeDialog: Adw.Dialog {
5+
content-height: 500;
6+
content-width: 600;
7+
8+
child: Adw.ToolbarView {
9+
[top]
10+
Adw.HeaderBar {
11+
show-title: false;
12+
}
13+
14+
content: Adw.Clamp {
15+
maximum-size: 600;
16+
17+
child: Box {
18+
orientation: vertical;
19+
margin-top: 6;
20+
margin-bottom: 18;
21+
margin-start: 18;
22+
margin-end: 18;
23+
24+
Box {
25+
orientation: vertical;
26+
margin-bottom: 24;
27+
spacing: 12;
28+
29+
Box {
30+
halign: center;
31+
32+
styles [
33+
"title-1",
34+
"lozenge",
35+
"grey",
36+
]
37+
38+
Label size_label {
39+
margin-end: 8;
40+
margin-start: 8;
41+
margin-top: 6;
42+
margin-bottom: 6;
43+
label: _("--- MB");
44+
use-markup: true;
45+
}
46+
}
47+
48+
Label {
49+
styles [
50+
"title-2",
51+
]
52+
53+
label: _("Download Size");
54+
}
55+
}
56+
57+
Adw.PreferencesGroup comparisons_group {
58+
}
59+
};
60+
};
61+
};
62+
}

src/bz-app-size-dialog.c

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/* bz-app-size-dialog.c
2+
*
3+
* Copyright 2025 Adam Masciola, Alexander Vanhee
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
* SPDX-License-Identifier: GPL-3.0-or-later
19+
*/
20+
21+
#include "bz-app-size-dialog.h"
22+
#include "bz-entry.h"
23+
#include <glib/gi18n.h>
24+
25+
struct _BzAppSizeDialog
26+
{
27+
AdwDialog parent_instance;
28+
29+
BzEntry *entry;
30+
31+
GtkLabel *size_label;
32+
AdwPreferencesGroup *comparisons_group;
33+
};
34+
35+
G_DEFINE_FINAL_TYPE (BzAppSizeDialog, bz_app_size_dialog, ADW_TYPE_DIALOG)
36+
37+
enum
38+
{
39+
PROP_0,
40+
41+
PROP_ENTRY,
42+
43+
LAST_PROP
44+
};
45+
static GParamSpec *props[LAST_PROP] = { 0 };
46+
47+
typedef struct
48+
{
49+
const char *title;
50+
const char *subtitle;
51+
guint64 reference_size;
52+
} SizeComparison;
53+
54+
static const SizeComparison comparisons[] = {
55+
{ N_ ("Of the size of human DNA"), N_ ("3 billion base pairs"), 750000000 },
56+
{ N_ ("Of the Linux Kernel"), N_ ("linux-6.17.tar.xz"), 153382068 },
57+
{ N_ ("Of the Apollo 11 guidance computer"), N_ ("Total ROM and RAM"), 76800 },
58+
{ N_ ("Of the original Super Mario Bros"), N_ ("On the NES"), 40976 },
59+
{ N_ ("Of the size of Wikipedia"), N_ ("Without any media"), 25823490867 },
60+
};
61+
62+
static void update_size_display (BzAppSizeDialog *self);
63+
static void populate_comparisons (BzAppSizeDialog *self);
64+
65+
static void
66+
bz_app_size_dialog_dispose (GObject *object)
67+
{
68+
BzAppSizeDialog *self = BZ_APP_SIZE_DIALOG (object);
69+
70+
g_clear_object (&self->entry);
71+
72+
G_OBJECT_CLASS (bz_app_size_dialog_parent_class)->dispose (object);
73+
}
74+
75+
static void
76+
bz_app_size_dialog_get_property (GObject *object,
77+
guint prop_id,
78+
GValue *value,
79+
GParamSpec *pspec)
80+
{
81+
BzAppSizeDialog *self = BZ_APP_SIZE_DIALOG (object);
82+
83+
switch (prop_id)
84+
{
85+
case PROP_ENTRY:
86+
g_value_set_object (value, self->entry);
87+
break;
88+
default:
89+
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
90+
}
91+
}
92+
93+
static void
94+
bz_app_size_dialog_set_property (GObject *object,
95+
guint prop_id,
96+
const GValue *value,
97+
GParamSpec *pspec)
98+
{
99+
BzAppSizeDialog *self = BZ_APP_SIZE_DIALOG (object);
100+
101+
switch (prop_id)
102+
{
103+
case PROP_ENTRY:
104+
g_clear_object (&self->entry);
105+
self->entry = g_value_dup_object (value);
106+
update_size_display (self);
107+
populate_comparisons (self);
108+
break;
109+
default:
110+
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
111+
}
112+
}
113+
114+
static char *
115+
format_size (gpointer object, guint64 value)
116+
{
117+
g_autofree char *size_str = g_format_size (value);
118+
char *space = g_strrstr (size_str, "\xC2\xA0");
119+
120+
if (space != NULL)
121+
{
122+
*space = '\0';
123+
return g_strdup_printf ("%s <span font_size='x-small'>%s</span>",
124+
size_str, space + 2);
125+
}
126+
127+
return g_strdup (size_str);
128+
}
129+
130+
static char *
131+
format_percentage (double percentage)
132+
{
133+
int magnitude = (int) floor (log10 (fabs (percentage)));
134+
int decimals = CLAMP (2 - magnitude, 0, 3);
135+
136+
return g_strdup_printf ("%.*f<span font_size='x-small'>%%</span>", decimals, percentage);
137+
}
138+
139+
static void
140+
update_size_display (BzAppSizeDialog *self)
141+
{
142+
guint64 app_size = 0;
143+
g_autofree char *size_str = NULL;
144+
145+
if (self->entry == NULL)
146+
return;
147+
148+
app_size = bz_entry_get_size (self->entry);
149+
size_str = format_size (NULL, app_size);
150+
151+
gtk_label_set_markup (self->size_label, size_str);
152+
}
153+
154+
static AdwActionRow *
155+
create_comparison_row (const SizeComparison *comp,
156+
double percentage)
157+
{
158+
AdwActionRow *row = NULL;
159+
GtkLabel *prefix_label = NULL;
160+
g_autofree char *percentage_str = NULL;
161+
162+
row = ADW_ACTION_ROW (adw_action_row_new ());
163+
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), _ (comp->title));
164+
adw_action_row_set_subtitle (row, _ (comp->subtitle));
165+
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
166+
167+
percentage_str = format_percentage (percentage);
168+
prefix_label = GTK_LABEL (gtk_label_new (NULL));
169+
gtk_label_set_markup (prefix_label, percentage_str);
170+
gtk_widget_set_valign (GTK_WIDGET (prefix_label), GTK_ALIGN_CENTER);
171+
gtk_widget_add_css_class (GTK_WIDGET (prefix_label), "lozenge");
172+
gtk_widget_add_css_class (GTK_WIDGET (prefix_label), "title-4");
173+
gtk_widget_add_css_class (GTK_WIDGET (prefix_label), "grey");
174+
gtk_widget_set_size_request (GTK_WIDGET (prefix_label), 90, -1);
175+
176+
adw_action_row_add_prefix (row, GTK_WIDGET (prefix_label));
177+
178+
return row;
179+
}
180+
181+
static void
182+
populate_comparisons (BzAppSizeDialog *self)
183+
{
184+
guint64 app_size = 0;
185+
186+
if (self->entry == NULL)
187+
return;
188+
189+
app_size = bz_entry_get_size (self->entry);
190+
191+
if (app_size == 0)
192+
return;
193+
194+
for (guint i = 0; i < G_N_ELEMENTS (comparisons); i++)
195+
{
196+
const SizeComparison *comp = &comparisons[i];
197+
double percentage = (double) app_size / (double) comp->reference_size * 100.0;
198+
AdwActionRow *row = NULL;
199+
200+
row = create_comparison_row (comp, percentage);
201+
adw_preferences_group_add (self->comparisons_group, GTK_WIDGET (row));
202+
}
203+
}
204+
205+
static void
206+
bz_app_size_dialog_class_init (BzAppSizeDialogClass *klass)
207+
{
208+
GObjectClass *object_class = G_OBJECT_CLASS (klass);
209+
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
210+
211+
object_class->dispose = bz_app_size_dialog_dispose;
212+
object_class->get_property = bz_app_size_dialog_get_property;
213+
object_class->set_property = bz_app_size_dialog_set_property;
214+
215+
props[PROP_ENTRY] =
216+
g_param_spec_object (
217+
"entry",
218+
NULL, NULL,
219+
BZ_TYPE_ENTRY,
220+
G_PARAM_READWRITE);
221+
222+
g_object_class_install_properties (object_class, LAST_PROP, props);
223+
224+
gtk_widget_class_set_template_from_resource (widget_class, "/io/github/kolunmi/Bazaar/bz-app-size-dialog.ui");
225+
gtk_widget_class_bind_template_child (widget_class, BzAppSizeDialog, size_label);
226+
gtk_widget_class_bind_template_child (widget_class, BzAppSizeDialog, comparisons_group);
227+
}
228+
229+
static void
230+
bz_app_size_dialog_init (BzAppSizeDialog *self)
231+
{
232+
gtk_widget_init_template (GTK_WIDGET (self));
233+
}
234+
235+
AdwDialog *
236+
bz_app_size_dialog_new (BzEntry *entry)
237+
{
238+
BzAppSizeDialog *app_size_dialog = NULL;
239+
240+
app_size_dialog = g_object_new (
241+
BZ_TYPE_APP_SIZE_DIALOG,
242+
"entry", entry,
243+
NULL);
244+
245+
return ADW_DIALOG (app_size_dialog);
246+
}

src/bz-app-size-dialog.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* bz-app-size-dialog.h
2+
*
3+
* Copyright 2025 Adam Masciola, Alexander Vanhee
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
* SPDX-License-Identifier: GPL-3.0-or-later
19+
*/
20+
21+
#pragma once
22+
23+
#include "bz-entry.h"
24+
#include <adwaita.h>
25+
26+
G_BEGIN_DECLS
27+
28+
#define BZ_TYPE_APP_SIZE_DIALOG (bz_app_size_dialog_get_type ())
29+
30+
G_DECLARE_FINAL_TYPE (BzAppSizeDialog, bz_app_size_dialog, BZ, APP_SIZE_DIALOG, AdwDialog)
31+
32+
AdwDialog *
33+
bz_app_size_dialog_new (BzEntry *entry);
34+
35+
G_END_DECLS

src/bz-full-view.blp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,14 @@ template $BzFullView: Adw.Bin {
329329
Box {
330330
homogeneous: true;
331331

332-
Box download_size_tile {
332+
Button download_size_tile {
333333
styles [
334334
"context-tile",
335335
"flat",
336336
]
337337

338+
clicked => $size_cb(template);
339+
338340
Box {
339341
orientation: vertical;
340342
spacing: 4;

0 commit comments

Comments
 (0)