Skip to content

Commit a001692

Browse files
committed
feat: Port DescriptionWindow and WarningDialog to use subclassing
Signed-off-by: Felicitas Pojtinger <[email protected]>
1 parent ef09bda commit a001692

File tree

12 files changed

+273
-110
lines changed

12 files changed

+273
-110
lines changed

assets/resources/description.blp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using Gtk 4.0;
22
using Adw 1;
33

4-
Adw.Window description-window {
4+
template $DescriptionWindow: Adw.Window {
55
default-width: 450;
66
default-height: 250;
77
modal: true;

assets/resources/warning.blp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using Gtk 4.0;
22
using Adw 1;
33

4-
Adw.AlertDialog warning-dialog {
4+
template $WarningDialog: Adw.AlertDialog {
55
heading: _("No Media Player Could Be Found");
66
body: _("Please install mpv or configure the existing installation to be able to play media.");
77
default-response: "download-website";
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package components
2+
3+
import (
4+
"runtime"
5+
"unsafe"
6+
7+
"github.com/jwijenbergh/puregotk/v4/adw"
8+
"github.com/jwijenbergh/puregotk/v4/gdk"
9+
"github.com/jwijenbergh/puregotk/v4/glib"
10+
"github.com/jwijenbergh/puregotk/v4/gobject"
11+
"github.com/jwijenbergh/puregotk/v4/gtk"
12+
"github.com/pojntfx/multiplex/assets/resources"
13+
)
14+
15+
var (
16+
gTypeDescriptionWindow gobject.Type
17+
)
18+
19+
type DescriptionWindow struct {
20+
adw.Window
21+
22+
text *gtk.TextView
23+
headerbarTitle *gtk.Label
24+
headerbarSubtitle *gtk.Label
25+
}
26+
27+
func NewDescriptionWindow(transientFor *adw.ApplicationWindow) DescriptionWindow {
28+
var w gtk.Window
29+
transientFor.Cast(&w)
30+
31+
obj := gobject.NewObject(gTypeDescriptionWindow, "transient-for", w)
32+
33+
var v DescriptionWindow
34+
obj.Cast(&v)
35+
36+
return v
37+
}
38+
39+
func (d *DescriptionWindow) Text() *gtk.TextView {
40+
descW := (*DescriptionWindow)(unsafe.Pointer(d.Widget.GetData(dataKeyGoInstance)))
41+
return descW.text
42+
}
43+
44+
func (d *DescriptionWindow) HeaderbarTitle() *gtk.Label {
45+
descW := (*DescriptionWindow)(unsafe.Pointer(d.Widget.GetData(dataKeyGoInstance)))
46+
return descW.headerbarTitle
47+
}
48+
49+
func (d *DescriptionWindow) HeaderbarSubtitle() *gtk.Label {
50+
descW := (*DescriptionWindow)(unsafe.Pointer(d.Widget.GetData(dataKeyGoInstance)))
51+
return descW.headerbarSubtitle
52+
}
53+
54+
func init() {
55+
var classInit gobject.ClassInitFunc = func(tc *gobject.TypeClass, u uintptr) {
56+
typeClass := (*gtk.WidgetClass)(unsafe.Pointer(tc))
57+
typeClass.SetTemplateFromResource(resources.ResourceDescriptionPath)
58+
59+
typeClass.BindTemplateChildFull("description-text", false, 0)
60+
typeClass.BindTemplateChildFull("headerbar-title", false, 0)
61+
typeClass.BindTemplateChildFull("headerbar-subtitle", false, 0)
62+
63+
objClass := (*gobject.ObjectClass)(unsafe.Pointer(tc))
64+
65+
objClass.OverrideConstructed(func(o *gobject.Object) {
66+
parentObjClass := (*gobject.ObjectClass)(unsafe.Pointer(tc.PeekParent()))
67+
parentObjClass.GetConstructed()(o)
68+
69+
var parent adw.Window
70+
o.Cast(&parent)
71+
72+
parent.InitTemplate()
73+
74+
var (
75+
descriptionText gtk.TextView
76+
descriptionHeaderbarTitle gtk.Label
77+
descriptionHeaderbarSubtitle gtk.Label
78+
)
79+
parent.Widget.GetTemplateChild(gTypeDescriptionWindow, "description-text").Cast(&descriptionText)
80+
parent.Widget.GetTemplateChild(gTypeDescriptionWindow, "headerbar-title").Cast(&descriptionHeaderbarTitle)
81+
parent.Widget.GetTemplateChild(gTypeDescriptionWindow, "headerbar-subtitle").Cast(&descriptionHeaderbarSubtitle)
82+
83+
w := &DescriptionWindow{
84+
Window: parent,
85+
text: &descriptionText,
86+
headerbarTitle: &descriptionHeaderbarTitle,
87+
headerbarSubtitle: &descriptionHeaderbarSubtitle,
88+
}
89+
90+
ctrl := gtk.NewEventControllerKey()
91+
parent.AddController(&ctrl.EventController)
92+
93+
closeRequestCallback := func(gtk.Window) bool {
94+
parent.Close()
95+
parent.SetVisible(false)
96+
return true
97+
}
98+
parent.ConnectCloseRequest(&closeRequestCallback)
99+
100+
keyReleasedCallback := func(ctrl gtk.EventControllerKey, keyval, keycode uint, state gdk.ModifierType) {
101+
if keycode == keycodeEscape {
102+
parent.Close()
103+
parent.SetVisible(false)
104+
}
105+
}
106+
ctrl.ConnectKeyReleased(&keyReleasedCallback)
107+
108+
var pinner runtime.Pinner
109+
pinner.Pin(w)
110+
111+
var cleanupCallback glib.DestroyNotify = func(data uintptr) {
112+
pinner.Unpin()
113+
}
114+
o.SetDataFull(dataKeyGoInstance, uintptr(unsafe.Pointer(w)), &cleanupCallback)
115+
})
116+
}
117+
118+
var instanceInit gobject.InstanceInitFunc = func(ti *gobject.TypeInstance, tc *gobject.TypeClass) {}
119+
120+
var parentQuery gobject.TypeQuery
121+
gobject.NewTypeQuery(adw.WindowGLibType(), &parentQuery)
122+
123+
gTypeDescriptionWindow = gobject.TypeRegisterStaticSimple(
124+
parentQuery.Type,
125+
"DescriptionWindow",
126+
parentQuery.ClassSize,
127+
&classInit,
128+
parentQuery.InstanceSize+uint(unsafe.Sizeof(DescriptionWindow{}))+uint(unsafe.Sizeof(&DescriptionWindow{})),
129+
&instanceInit,
130+
0,
131+
)
132+
}

internal/components/main_window.go

Lines changed: 20 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/anacrolix/torrent"
2424
"github.com/jwijenbergh/puregotk/v4/adw"
25-
"github.com/jwijenbergh/puregotk/v4/gdk"
2625
"github.com/jwijenbergh/puregotk/v4/gio"
2726
"github.com/jwijenbergh/puregotk/v4/glib"
2827
"github.com/jwijenbergh/puregotk/v4/gobject"
@@ -111,13 +110,10 @@ type MainWindow struct {
111110
adapterCtx context.Context
112111
cancelAdapterCtx func()
113112

114-
descriptionWindow *adw.Window
115-
descriptionText *gtk.TextView
116-
descriptionHeaderbarTitle *gtk.Label
117-
descriptionHeaderbarSubtitle *gtk.Label
118-
warningDialog *adw.AlertDialog
119-
preferencesDialog *adw.PreferencesWindow
120-
mpvCommandInput *adw.EntryRow
113+
descriptionWindow DescriptionWindow
114+
warningDialog WarningDialog
115+
preferencesDialog *adw.PreferencesWindow
116+
mpvCommandInput *adw.EntryRow
121117
}
122118

123119
func NewMainWindow(
@@ -148,9 +144,9 @@ func NewMainWindow(
148144
v.cancel = cancel
149145
v.tmpDir = tmpDir
150146

151-
// TODO: Make these their own subclasses
152-
v.initializeDescriptionWindow()
153-
v.initializeWarningDialog()
147+
v.descriptionWindow = NewDescriptionWindow(&v.ApplicationWindow)
148+
v.warningDialog = NewWarningDialog()
149+
v.warningDialog.SetResponseCallback(v.onWarningDialogResponse)
154150

155151
v.preferencesDialog, v.mpvCommandInput = AddMainMenu(
156152
ctx,
@@ -219,60 +215,6 @@ func (w *MainWindow) setupSignalHandlers() {
219215
w.ApplicationWindow.ConnectShow(&onShow)
220216
}
221217

222-
func (w *MainWindow) initializeDescriptionWindow() {
223-
descriptionBuilder := gtk.NewBuilderFromResource(resources.ResourceDescriptionPath)
224-
defer descriptionBuilder.Unref()
225-
226-
var (
227-
descriptionWindow adw.Window
228-
descriptionText gtk.TextView
229-
descriptionHeaderbarTitle gtk.Label
230-
descriptionHeaderbarSubtitle gtk.Label
231-
)
232-
descriptionBuilder.GetObject("description-window").Cast(&descriptionWindow)
233-
descriptionBuilder.GetObject("description-text").Cast(&descriptionText)
234-
descriptionBuilder.GetObject("headerbar-title").Cast(&descriptionHeaderbarTitle)
235-
descriptionBuilder.GetObject("headerbar-subtitle").Cast(&descriptionHeaderbarSubtitle)
236-
237-
w.descriptionWindow = &descriptionWindow
238-
w.descriptionText = &descriptionText
239-
w.descriptionHeaderbarTitle = &descriptionHeaderbarTitle
240-
w.descriptionHeaderbarSubtitle = &descriptionHeaderbarSubtitle
241-
242-
ctrl := gtk.NewEventControllerKey()
243-
descriptionWindow.AddController(&ctrl.EventController)
244-
descriptionWindow.SetTransientFor(&w.ApplicationWindow.Window)
245-
246-
closeRequestCallback := func(gtk.Window) bool {
247-
descriptionWindow.Close()
248-
descriptionWindow.SetVisible(false)
249-
return true
250-
}
251-
descriptionWindow.ConnectCloseRequest(&closeRequestCallback)
252-
253-
keyReleasedCallback := func(ctrl gtk.EventControllerKey, keyval, keycode uint, state gdk.ModifierType) {
254-
if keycode == keycodeEscape {
255-
descriptionWindow.Close()
256-
descriptionWindow.SetVisible(false)
257-
}
258-
}
259-
ctrl.ConnectKeyReleased(&keyReleasedCallback)
260-
}
261-
262-
func (w *MainWindow) initializeWarningDialog() {
263-
warningBuilder := gtk.NewBuilderFromResource(resources.ResourceWarningPath)
264-
defer warningBuilder.Unref()
265-
266-
var warningDialog adw.AlertDialog
267-
warningBuilder.GetObject("warning-dialog").Cast(&warningDialog)
268-
269-
w.warningDialog = &warningDialog
270-
271-
responseCallback := func(dialog adw.AlertDialog, response string) {
272-
w.onWarningDialogResponse(response)
273-
}
274-
warningDialog.ConnectResponse(&responseCallback)
275-
}
276218

277219
func (w *MainWindow) onNext() {
278220
switch w.stack.GetVisibleChildName() {
@@ -413,16 +355,16 @@ func (w *MainWindow) onNext() {
413355
w.previousButton.SetVisible(true)
414356

415357
w.buttonHeaderbarTitle.SetLabel(w.torrentTitle)
416-
w.descriptionHeaderbarTitle.SetLabel(w.torrentTitle)
358+
w.descriptionWindow.HeaderbarTitle().SetLabel(w.torrentTitle)
417359

418360
w.mediaInfoDisplay.SetVisible(false)
419361
w.mediaInfoButton.SetVisible(true)
420362

421-
w.descriptionText.SetWrapMode(gtk.WrapWordValue)
363+
w.descriptionWindow.Text().SetWrapMode(gtk.WrapWordValue)
422364
if !utf8.Valid([]byte(w.torrentReadme)) || strings.TrimSpace(w.torrentReadme) == "" {
423-
w.descriptionText.GetBuffer().SetText(L(readmePlaceholder), -1)
365+
w.descriptionWindow.Text().GetBuffer().SetText(L(readmePlaceholder), -1)
424366
} else {
425-
w.descriptionText.GetBuffer().SetText(w.torrentReadme, -1)
367+
w.descriptionWindow.Text().GetBuffer().SetText(w.torrentReadme, -1)
426368
}
427369

428370
w.stack.SetVisibleChildName(mediaPageName)
@@ -592,24 +534,24 @@ func (w *MainWindow) onNext() {
592534
w.previousButton.SetVisible(true)
593535

594536
w.buttonHeaderbarTitle.SetLabel(w.torrentTitle)
595-
w.descriptionHeaderbarTitle.SetLabel(w.torrentTitle)
537+
w.descriptionWindow.HeaderbarTitle().SetLabel(w.torrentTitle)
596538

597539
w.mediaInfoDisplay.SetVisible(false)
598540
w.mediaInfoButton.SetVisible(true)
599541

600-
w.descriptionText.SetWrapMode(gtk.WrapWordValue)
542+
w.descriptionWindow.Text().SetWrapMode(gtk.WrapWordValue)
601543
if !utf8.Valid([]byte(w.torrentReadme)) || strings.TrimSpace(w.torrentReadme) == "" {
602-
w.descriptionText.GetBuffer().SetText(L("No README found."), -1)
544+
w.descriptionWindow.Text().GetBuffer().SetText(L("No README found."), -1)
603545
} else {
604-
w.descriptionText.GetBuffer().SetText(w.torrentReadme, -1)
546+
w.descriptionWindow.Text().GetBuffer().SetText(w.torrentReadme, -1)
605547
}
606548

607549
w.nextButton.SetVisible(false)
608550

609551
w.buttonHeaderbarSubtitle.SetVisible(true)
610-
w.descriptionHeaderbarSubtitle.SetVisible(true)
552+
w.descriptionWindow.HeaderbarSubtitle().SetVisible(true)
611553
w.buttonHeaderbarSubtitle.SetLabel(getDisplayPathWithoutRoot(w.selectedTorrentMedia))
612-
w.descriptionHeaderbarSubtitle.SetLabel(getDisplayPathWithoutRoot(w.selectedTorrentMedia))
554+
w.descriptionWindow.HeaderbarSubtitle().SetLabel(getDisplayPathWithoutRoot(w.selectedTorrentMedia))
613555

614556
w.stack.SetVisibleChildName(readyPageName)
615557
}()
@@ -618,9 +560,9 @@ func (w *MainWindow) onNext() {
618560
w.nextButton.SetVisible(false)
619561

620562
w.buttonHeaderbarSubtitle.SetVisible(true)
621-
w.descriptionHeaderbarSubtitle.SetVisible(true)
563+
w.descriptionWindow.HeaderbarSubtitle().SetVisible(true)
622564
w.buttonHeaderbarSubtitle.SetLabel(getDisplayPathWithoutRoot(w.selectedTorrentMedia))
623-
w.descriptionHeaderbarSubtitle.SetLabel(getDisplayPathWithoutRoot(w.selectedTorrentMedia))
565+
w.descriptionWindow.HeaderbarSubtitle().SetLabel(getDisplayPathWithoutRoot(w.selectedTorrentMedia))
624566

625567
w.stack.SetVisibleChildName(readyPageName)
626568
}
@@ -640,7 +582,7 @@ func (w *MainWindow) onPrevious(gtk.Button) {
640582
w.nextButton.SetVisible(true)
641583

642584
w.buttonHeaderbarSubtitle.SetVisible(false)
643-
w.descriptionHeaderbarSubtitle.SetVisible(false)
585+
w.descriptionWindow.HeaderbarSubtitle().SetVisible(false)
644586

645587
if !w.isNewSession {
646588
if w.adapter != nil {

0 commit comments

Comments
 (0)