From e15f2097df6301408dde36001333ba866d490adb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 31 Mar 2020 11:21:47 +0900 Subject: [PATCH] [qwaq] Move scroll bar management into View Putting it in Editor worked as a proof of concept, but it seems those always turn out to need tweaking like this because the concept proves itself to be generally worthwhile :P --- ruamoko/qwaq/editor/editor.h | 5 +--- ruamoko/qwaq/editor/editor.r | 53 +++++++++++++++++------------------- ruamoko/qwaq/ui/scrollbar.h | 4 +-- ruamoko/qwaq/ui/scrollbar.r | 10 +++---- ruamoko/qwaq/ui/view.h | 9 ++++++ ruamoko/qwaq/ui/view.r | 44 +++++++++++++++++++++++++++++- 6 files changed, 85 insertions(+), 40 deletions(-) diff --git a/ruamoko/qwaq/editor/editor.h b/ruamoko/qwaq/editor/editor.h index 3a2cd48c5..b5bd4b7d5 100644 --- a/ruamoko/qwaq/editor/editor.h +++ b/ruamoko/qwaq/editor/editor.h @@ -7,25 +7,22 @@ @class Editor; @class EditBuffer; @class ListenerGroup; -@class ScrollBar; @interface Editor : View { EditBuffer *buffer; DrawBuffer *linebuffer; - ScrollBar *vScrollBar; eb_sel_t selection; unsigned base_index; // top left corner unsigned line_index; // current line unsigned char_index; // current character unsigned old_cind; // previous character - Point scroll; + Point base; Point cursor; unsigned line_count; string filename; } +(Editor *)withRect:(Rect)rect file:(string)filename; --setVerticalScrollBar:(ScrollBar *)scrollbar; -(string)filename; -scrollUp:(unsigned) count; -scrollDown:(unsigned) count; diff --git a/ruamoko/qwaq/editor/editor.r b/ruamoko/qwaq/editor/editor.r index 0f6e3283c..d66407564 100644 --- a/ruamoko/qwaq/editor/editor.r +++ b/ruamoko/qwaq/editor/editor.r @@ -17,6 +17,7 @@ linebuffer = [[DrawBuffer buffer: { xlen, 1 }] retain]; growMode = gfGrowHi; options = ofCanFocus | ofRelativeEvents; + [onViewScrolled addListener:self :@selector(onScroll:)]; return self; } @@ -25,19 +26,6 @@ return [[[self alloc] initWithRect:rect file:filename] autorelease]; } --setVerticalScrollBar:(ScrollBar *)scrollbar -{ - [scrollbar retain]; - [[vScrollBar onScroll] removeListener:self :@selector(onScroll:)]; - [vScrollBar release]; - - vScrollBar = scrollbar; - [vScrollBar setRange:line_count]; - [vScrollBar setPageStep: ylen]; - [[vScrollBar onScroll] addListener:self :@selector(onScroll:)]; - return self; -} - -(void)dealloc { [vScrollBar release]; @@ -57,7 +45,7 @@ unsigned lind = base_index; int *lbuf = [linebuffer buffer]; for (int y = 0; y < ylen; y++) { - lind = [buffer formatLine:lind from:scroll.x into:lbuf width:xlen + lind = [buffer formatLine:lind from:base.x into:lbuf width:xlen highlight:selection colors: {color_palette[047], color_palette[007]}]; [textContext blitFromBuffer: linebuffer to: {xpos, ypos + y} @@ -141,10 +129,10 @@ static int handleEvent (Editor *self, qwaq_event_t *event) -scrollLeft:(unsigned) count { - if (scroll.x > count) { - scroll.x -= count; + if (base.x > count) { + base.x -= count; } else { - scroll.x = 0; + base.x = 0; } [self redraw]; return self; @@ -152,10 +140,10 @@ static int handleEvent (Editor *self, qwaq_event_t *event) -scrollRight:(unsigned) count { - if (1024 - scroll.x > count) { - scroll.x += count; + if (1024 - base.x > count) { + base.x += count; } else { - scroll.x = 1024; + base.x = 1024; } [self redraw]; return self; @@ -163,24 +151,33 @@ static int handleEvent (Editor *self, qwaq_event_t *event) -scrollTo:(unsigned)target { - if (target > scroll.y) { - base_index = [buffer nextLine:base_index :target - scroll.y]; - } else if (target < scroll.y) { - base_index = [buffer prevLine:base_index :scroll.y - target]; + if (target > base.y) { + base_index = [buffer nextLine:base_index :target - base.y]; + } else if (target < base.y) { + base_index = [buffer prevLine:base_index :base.y - target]; } - scroll.y = target; + base.y = target; return self; } -(void)onScroll:(id)sender { - [self scrollTo:[sender index]]; + base.x = scroll.x; + [self scrollTo:scroll.y]; +} + +-setVerticalScrollBar:(ScrollBar *)scrollbar +{ + [super setVerticalScrollBar:scrollbar]; + [vScrollBar setRange:line_count]; + [vScrollBar setPageStep: ylen]; + return self; } -recenter:(int) force { if (!force) { - if (cursor.y >= scroll.y && cursor.y - scroll.y < ylen) { + if (cursor.y >= base.y && cursor.y - base.y < ylen) { return self; } } @@ -221,7 +218,7 @@ static int handleEvent (Editor *self, qwaq_event_t *event) if (pos.x < 0 || pos.y < 0 || pos.x >= xlen || pos.y >= ylen) { return nil; } - pos.x += scroll.x; + pos.x += base.x; unsigned lind = [buffer nextLine:base_index :pos.y]; unsigned cind = [buffer charPtr:lind at:pos.x]; eb_sel_t word = [buffer getWord: cind]; diff --git a/ruamoko/qwaq/ui/scrollbar.h b/ruamoko/qwaq/ui/scrollbar.h index bb0f5c25c..986646878 100644 --- a/ruamoko/qwaq/ui/scrollbar.h +++ b/ruamoko/qwaq/ui/scrollbar.h @@ -20,7 +20,7 @@ Button *forwardButton; Button *thumbTab; Group *objects; - ListenerGroup *onScroll; + ListenerGroup *onScrollBarModified; unsigned pageStep; unsigned singleStep; @@ -29,7 +29,7 @@ } +(ScrollBar *)horizontal:(unsigned)len at:(Point)pos; +(ScrollBar *)vertical:(unsigned)len at:(Point)pos; --(ListenerGroup *)onScroll; +-(ListenerGroup *)onScrollBarModified; -setRange:(unsigned)range; -setPageStep:(unsigned)pageStep; -setSingleStep:(unsigned)singleStep; diff --git a/ruamoko/qwaq/ui/scrollbar.r b/ruamoko/qwaq/ui/scrollbar.r index 4c080009d..411e7d344 100644 --- a/ruamoko/qwaq/ui/scrollbar.r +++ b/ruamoko/qwaq/ui/scrollbar.r @@ -13,7 +13,7 @@ options = ofRelativeEvents; buffer = [[DrawBuffer buffer:size] retain]; objects = [[Group withContext:buffer owner:self] retain]; - onScroll = [[ListenerGroup listener] retain]; + onScrollBarModified = [[ListenerGroup listener] retain]; vertical = xlen == 1; DrawBuffer *icons[3] = { [DrawBuffer buffer:{1, 1}], @@ -61,7 +61,7 @@ { [objects release]; [buffer release]; - [onScroll release]; + [onScrollBarModified release]; } +(ScrollBar *)horizontal:(unsigned)len at:(Point)pos @@ -80,9 +80,9 @@ return [[[self alloc] initWithRect:{pos, {1, len}}] autorelease]; } --(ListenerGroup *)onScroll +-(ListenerGroup *)onScrollBarModified { - return onScroll; + return onScrollBarModified; } -draw @@ -142,7 +142,7 @@ position_tab (ScrollBar *self) } if (index != oind) { - [onScroll respond:self]; + [onScrollBarModified respond:self]; position_tab (self); } return self; diff --git a/ruamoko/qwaq/ui/view.h b/ruamoko/qwaq/ui/view.h index 4752c4349..e0da51a28 100644 --- a/ruamoko/qwaq/ui/view.h +++ b/ruamoko/qwaq/ui/view.h @@ -10,6 +10,7 @@ @class Group; @class ListenerGroup; +@class ScrollBar; enum { ofCanFocus = 0x0001, @@ -59,6 +60,10 @@ enum { -(int) options; -(int) state; +-setVerticalScrollBar:(ScrollBar *)scrollbar; +-setHorizontalScrollBar:(ScrollBar *)scrollbar; +-(ListenerGroup *) onViewScrolled; + -(id)context; -setContext: (id) context; -draw; @@ -114,6 +119,10 @@ enum { ListenerGroup *onReceiveFocus; ListenerGroup *onReleaseFocus; ListenerGroup *onEvent; + ListenerGroup *onViewScrolled; + ScrollBar *hScrollBar; + ScrollBar *vScrollBar; + Point scroll; } +(View *)viewWithRect:(Rect)rect; +(View *)viewWithRect:(Rect)rect options:(int)options; diff --git a/ruamoko/qwaq/ui/view.r b/ruamoko/qwaq/ui/view.r index a6817b81d..ba2f170ad 100644 --- a/ruamoko/qwaq/ui/view.r +++ b/ruamoko/qwaq/ui/view.r @@ -1,7 +1,8 @@ #include "ui/curses.h" #include "ui/listener.h" -#include "ui/view.h" #include "ui/group.h" +#include "ui/scrollbar.h" +#include "ui/view.h" @implementation View @@ -20,6 +21,7 @@ static void view_init(View *self) self.onReceiveFocus = [ListenerGroup listener]; self.onReleaseFocus = [ListenerGroup listener]; self.onEvent = [ListenerGroup listener]; + self.onViewScrolled = [ListenerGroup listener]; } -init @@ -64,6 +66,7 @@ static void view_init(View *self) [onReceiveFocus release]; [onReleaseFocus release]; [onEvent release]; + [onViewScrolled release]; [super dealloc]; } @@ -88,6 +91,40 @@ static void view_init(View *self) return state; } +-(void)onScrollBarModified:(id)sender +{ + if (sender == vScrollBar) { + scroll.y = [sender index]; + } else if (sender == hScrollBar) { + scroll.x = [sender index]; + } + [onViewScrolled respond:self]; +} + +static void +setScrollBar (View *self, ScrollBar **sb, ScrollBar *scrollbar) +{ + SEL sel = @selector(onScrollBarModified:); + [scrollbar retain]; + [[*sb onScrollBarModified] removeListener:self :sel]; + [*sb release]; + + *sb = scrollbar; + [[*sb onScrollBarModified] addListener:self :sel]; +} + +-setVerticalScrollBar:(ScrollBar *)scrollbar +{ + setScrollBar (self, &vScrollBar, scrollbar); + return self; +} + +-setHorizontalScrollBar:(ScrollBar *)scrollbar +{ + setScrollBar (self, &hScrollBar, scrollbar); + return self; +} + static void updateScreenCursor (View *view) { @@ -321,6 +358,11 @@ updateScreenCursor (View *view) return onEvent; } +-(ListenerGroup *) onViewScrolled +{ + return onViewScrolled; +} + -handleEvent: (qwaq_event_t *) event { // give any listeners a chance to override or extend event handling