Skip to content

Commit 5d41c26

Browse files
Enoumydarylhjd
authored andcommitted
Implemented visual mode for mangadesk
1 parent 592a08c commit 5d41c26

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

app/ui/manga_page.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ func newMangaPage(manga *mangodex.Manga) *MangaPage {
109109
Info: info,
110110
Table: table,
111111
sWrap: &utils.SelectorWrapper{
112-
Selection: map[int]struct{}{},
112+
Selection: map[int]struct{}{},
113+
VisualStart: -1,
113114
},
114115
cWrap: &utils.ContextWrapper{
115116
Ctx: ctx,

app/ui/page_inputs.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ func (p *MangaPage) setHandlers(cancel context.CancelFunc) {
189189
return event
190190
})
191191

192+
p.Table.SetSelectionChangedFunc(func(row, _column int) {
193+
if p.sWrap.IsInVisualMode() {
194+
p.selectRange(min(row, p.sWrap.VisualStart), max(row, p.sWrap.VisualStart))
195+
}
196+
})
197+
192198
// Set table selected function.
193199
p.Table.SetSelectedFunc(func(row, _ int) {
194200
log.Println("Creating and showing confirm download modal...")
@@ -203,16 +209,26 @@ func (p *MangaPage) setHandlers(cancel context.CancelFunc) {
203209

204210
// Set table input captures.
205211
p.Table.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
212+
206213
switch event.Key() {
207214
case tcell.KeyCtrlE: // User selects this manga row.
208215
p.ctrlEInput()
216+
return event
209217
case tcell.KeyCtrlA: // User wants to toggle select All.
210218
p.ctrlAInput()
219+
return event
211220
case tcell.KeyCtrlR: // User wants to toggle read status for Selection.
212221
p.ctrlRInput()
222+
return event
213223
case tcell.KeyCtrlQ:
214224
p.ctrlQInput()
225+
return event
215226
}
227+
228+
if event.Rune() == 'v' || event.Rune() == 'V' {
229+
p.shiftVInput()
230+
}
231+
216232
return event
217233
})
218234
}
@@ -234,6 +250,51 @@ func (p *MangaPage) ctrlAInput() {
234250
p.markAll()
235251
}
236252

253+
func (p *MangaPage) selectRange(from, to int) {
254+
start := min(from, to)
255+
end := max(from, to)
256+
257+
for row := 1; row < p.Table.GetRowCount(); row++ {
258+
if row < start || row > end {
259+
if p.sWrap.HasSelection(row) {
260+
p.markUnselected(row)
261+
}
262+
} else {
263+
if !p.sWrap.HasSelection(row) {
264+
p.markSelected(row)
265+
}
266+
}
267+
}
268+
}
269+
270+
func min(a, b int) int {
271+
if a < b {
272+
return a
273+
}
274+
return b
275+
}
276+
277+
func max(a, b int) int {
278+
if a > b {
279+
return a
280+
}
281+
return b
282+
}
283+
284+
func (p *MangaPage) shiftVInput() {
285+
if p.sWrap.IsInVisualMode() {
286+
p.sWrap.StopVisualSelection()
287+
for row := 1; row < p.Table.GetRowCount(); row++ {
288+
if p.sWrap.HasSelection(row) {
289+
p.markUnselected(row)
290+
}
291+
}
292+
} else {
293+
row, _ := p.Table.GetSelection()
294+
p.sWrap.StartVisualSelection(row)
295+
}
296+
}
297+
237298
// ctrlRInput : Allows user to toggle read status for a chapter.
238299
func (p *MangaPage) ctrlRInput() {
239300
modal := confirmModal(utils.ToggleReadChapterModalID,

app/ui/utils/selector.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package utils
33
// SelectorWrapper : A wrapper to store selections. Used by the manga page to
44
// keep track of selections.
55
type SelectorWrapper struct {
6-
Selection map[int]struct{} // Keep track of which chapters have been selected by user.
7-
All bool // Keep track of whether user has selected All or not.
6+
Selection map[int]struct{} // Keep track of which chapters have been selected by user.
7+
All bool // Keep track of whether user has selected All or not.
8+
VisualStart int // Keeps track of the start of the visual selection. -1 If none.
89
}
910

1011
// HasSelections : Checks whether there are currently selections.
@@ -24,7 +25,6 @@ func (s *SelectorWrapper) CopySelection(row int) map[int]struct{} {
2425
if !s.HasSelections() {
2526
s.AddSelection(row)
2627
}
27-
2828
selection := map[int]struct{}{}
2929
for se := range s.Selection {
3030
selection[se] = struct{}{}
@@ -47,3 +47,15 @@ func (s *SelectorWrapper) AddSelection(row int) {
4747
func (s *SelectorWrapper) RemoveSelection(row int) {
4848
delete(s.Selection, row)
4949
}
50+
51+
func (s *SelectorWrapper) IsInVisualMode() bool {
52+
return s.VisualStart != -1
53+
}
54+
55+
func (s *SelectorWrapper) StartVisualSelection(row int) {
56+
s.VisualStart = row
57+
}
58+
59+
func (s *SelectorWrapper) StopVisualSelection() {
60+
s.VisualStart = -1
61+
}

0 commit comments

Comments
 (0)