From 055ea46337fd52a867c9392d3d8a768c4013a972 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 10 Jun 2021 12:13:55 +0900 Subject: [PATCH] [qwaq] Fix page up/down and deal with tabs --- ruamoko/qwaq/Makemodule.am | 2 + ruamoko/qwaq/debugger/debugger.h | 2 + ruamoko/qwaq/debugger/debugger.r | 5 + ruamoko/qwaq/editor/editor.h | 19 +++- ruamoko/qwaq/editor/editor.r | 152 +++++++++++++++++++++++++------ ruamoko/qwaq/editor/status.h | 23 +++++ ruamoko/qwaq/editor/status.r | 43 +++++++++ 7 files changed, 216 insertions(+), 30 deletions(-) create mode 100644 ruamoko/qwaq/editor/status.h create mode 100644 ruamoko/qwaq/editor/status.r diff --git a/ruamoko/qwaq/Makemodule.am b/ruamoko/qwaq/Makemodule.am index 8b2d29419..378eb8505 100644 --- a/ruamoko/qwaq/Makemodule.am +++ b/ruamoko/qwaq/Makemodule.am @@ -27,6 +27,7 @@ qwaq_app_dat_src= \ ruamoko/qwaq/debugger/typeencodings.r \ ruamoko/qwaq/editor/editbuffer.r \ ruamoko/qwaq/editor/editor.r \ + ruamoko/qwaq/editor/status.r \ ruamoko/qwaq/ui/button.r \ ruamoko/qwaq/ui/draw.r \ ruamoko/qwaq/ui/garray.r \ @@ -124,6 +125,7 @@ EXTRA_DIST += \ ruamoko/qwaq/debugger/views/voidview.h \ ruamoko/qwaq/editor/editbuffer.h \ ruamoko/qwaq/editor/editor.h \ + ruamoko/qwaq/editor/status.h \ ruamoko/qwaq/qwaq-app.h \ ruamoko/qwaq/qwaq.h \ ruamoko/qwaq/ui/button.h \ diff --git a/ruamoko/qwaq/debugger/debugger.h b/ruamoko/qwaq/debugger/debugger.h index 46c9cbeda..64dce073c 100644 --- a/ruamoko/qwaq/debugger/debugger.h +++ b/ruamoko/qwaq/debugger/debugger.h @@ -9,6 +9,7 @@ @class ProxyView; @class Editor; +@class EditStatus; @class ScrollBar; @class Window; @class Array; @@ -33,6 +34,7 @@ Window *source_window; ScrollBar *source_scrollbar; + EditStatus *source_status; ProxyView *file_proxy; Array *files; Editor *current_file; diff --git a/ruamoko/qwaq/debugger/debugger.r b/ruamoko/qwaq/debugger/debugger.r index aabb06889..6afa14e84 100644 --- a/ruamoko/qwaq/debugger/debugger.r +++ b/ruamoko/qwaq/debugger/debugger.r @@ -40,6 +40,9 @@ source_scrollbar = [ScrollBar vertical:s.height - 2 at:{s.width - 1, 1}]; [source_window insert:source_scrollbar]; + source_status = [EditStatus withRect:{{1, 0}, {2, 1}}]; + [source_window insert:source_status]; + return self; } @@ -77,6 +80,7 @@ [[current_file gotoLine:state.line - 1] highlightLine]; [[current_file onEvent] addListener: self :@selector(proxy_event::)]; [current_file setVerticalScrollBar:source_scrollbar]; + [current_file setStatusView:source_status]; //FIXME id? [source_window insertSelected: (View *) file_proxy]; [source_window setTitle:[current_file filename]]; @@ -111,6 +115,7 @@ [file_proxy setView:file]; [[file onEvent] addListener:self :@selector(proxy_event::)]; [file setVerticalScrollBar:source_scrollbar]; + [file setStatusView:source_status]; [source_window setTitle:[file filename]]; current_file = file; } diff --git a/ruamoko/qwaq/editor/editor.h b/ruamoko/qwaq/editor/editor.h index 8f86ef8d7..a30b2546d 100644 --- a/ruamoko/qwaq/editor/editor.h +++ b/ruamoko/qwaq/editor/editor.h @@ -2,15 +2,18 @@ #define __qwaq_editor_editor_h #include "ruamoko/qwaq/editor/editbuffer.h" +#include "ruamoko/qwaq/editor/status.h" #include "ruamoko/qwaq/ui/view.h" @class Editor; @class EditBuffer; @class ListenerGroup; +@class EditStatus; @interface Editor : View { EditBuffer *buffer; + EditStatus *status; DrawBuffer *linebuffer; eb_sel_t selection; unsigned base_index; // top left corner @@ -22,20 +25,28 @@ unsigned line_count; string filename; string filepath; + int modified; + CursorMode cursorMode; + + int virtualInsert; + int cursorThroughTabs; } +(Editor *)withRect:(Rect)rect file:(string)filename; +(Editor *)withRect:(Rect)rect file:(string)filename path:(string)filepath; -(string)filename; -(string)filepath; -(Point)cursor; +-setStatusView:(EditStatus *)status; -scrollUp:(unsigned) count; -scrollDown:(unsigned) count; -scrollLeft:(unsigned) count; -scrollRight:(unsigned) count; --cursorUp:(unsigned) count; --cursorDown:(unsigned) count; --cursorLeft:(unsigned) count; --cursorRight:(unsigned) count; +-pageUp; +-pageDown; +-charUp; +-charDown; +-charLeft; +-charRight; -recenter:(int) force; -gotoLine:(unsigned) line; diff --git a/ruamoko/qwaq/editor/editor.r b/ruamoko/qwaq/editor/editor.r index 75f786b9d..fc5a69993 100644 --- a/ruamoko/qwaq/editor/editor.r +++ b/ruamoko/qwaq/editor/editor.r @@ -25,6 +25,7 @@ options = ofCanFocus | ofRelativeEvents; [onViewScrolled addListener:self :@selector(onScroll:)]; [self setCursorVisible:1]; + return self; } @@ -69,6 +70,45 @@ return cursor; } +-setStatusView:(EditStatus *)status +{ + self.status = status; + [status setModified:modified]; + [status setCursorMode:cursorMode]; + [status redraw]; + return self; +} + +-trackCursor:(int)fwd +{ + unsigned tx = [buffer charPos:line_index at:char_index]; + + cursorMode &= ~cmVInsert; + if (tx != cursor.x) { + if (char_index < [buffer getEOT]) { + int c = [buffer getChar:char_index]; + + if (virtualInsert) { + if (c != '\t' || cursorThroughTabs) { + cursorMode |= cmVInsert; + goto done; + } + } + if (c == '\t' && fwd) { + tx = [buffer charPos:line_index at:++char_index]; + } + } else if (virtualInsert) { + cursorMode |= cmVInsert; + goto done; + } + cursor.x = tx; + } +done: + [status setCursorMode:cursorMode]; + [status redraw]; + return self; +} + -draw { [super draw]; @@ -116,22 +156,22 @@ handleEvent (Editor *self, qwaq_event_t *event) } else if (event.what == qe_keydown) { switch (event.key.code) { case QFK_PAGEUP: - [self scrollUp: self.ylen]; + [self pageUp]; return 1; case QFK_PAGEDOWN: - [self scrollDown: self.ylen]; + [self pageDown]; return 1; case QFK_UP: - [self cursorUp: 1]; + [self charUp]; return 1; case QFK_DOWN: - [self cursorDown: 1]; + [self charDown]; return 1; case QFK_LEFT: - [self cursorLeft: 1]; + [self charLeft]; return 1; case QFK_RIGHT: - [self cursorRight: 1]; + [self charRight]; return 1; } } @@ -150,23 +190,35 @@ handleEvent (Editor *self, qwaq_event_t *event) -scrollUp:(unsigned) count { + unsigned index; + unsigned lines; if (count == 1) { - base_index = [buffer prevLine: base_index]; + index = [buffer prevLine: base_index]; } else { - base_index = [buffer prevLine: base_index :count]; + index = [buffer prevLine: base_index :count]; } + lines = [buffer countLines: {index, base_index - index}]; + base.y -= lines; + base_index = index; [self redraw]; + [self moveCursor: {cursor.x - base.x, cursor.y - base.y}]; return self; } -scrollDown:(unsigned) count { + unsigned index; + unsigned lines; if (count == 1) { - base_index = [buffer nextLine: base_index]; + index = [buffer nextLine: base_index]; } else { - base_index = [buffer nextLine: base_index :count]; + index = [buffer nextLine: base_index :count]; } + lines = [buffer countLines: {base_index, index - base_index}]; + base.y += lines; + base_index = index; [self redraw]; + [self moveCursor: {cursor.x - base.x, cursor.y - base.y}]; return self; } @@ -207,15 +259,57 @@ handleEvent (Editor *self, qwaq_event_t *event) return self; } --cursorUp:(unsigned)count +-pageUp { [self recenter:0]; - if (count > cursor.y) { - count = cursor.y; + unsigned count = cursor.y; + + if (count > ylen) { + count = ylen; } - cursor.y -= count; - line_index = [buffer prevLine:line_index :count]; + if (count) { + cursor.y -= count; + [vScrollBar setIndex:[vScrollBar index] - count]; + line_index = [buffer prevLine:line_index :count]; + char_index = [buffer charPtr:line_index at:cursor.x]; + [self trackCursor:1]; + + [self moveCursor: {cursor.x - base.x, cursor.y - base.y}]; + } + return self; +} + +-pageDown +{ + [self recenter:0]; + unsigned count = line_count - cursor.y; + + if (count > ylen) { + count = ylen; + } + if (count) { + cursor.y += count; + [vScrollBar setIndex:[vScrollBar index] + count]; + line_index = [buffer nextLine:line_index :count]; + char_index = [buffer charPtr:line_index at:cursor.x]; + [self trackCursor:1]; + + [self moveCursor: {cursor.x - base.x, cursor.y - base.y}]; + } + return self; +} + +-charUp +{ + [self recenter:0]; + if (cursor.y < 1) { + return self; + } + cursor.y--; + line_index = [buffer prevLine:line_index :1]; char_index = [buffer charPtr:line_index at:cursor.x]; + [self trackCursor:1]; + if (base.y > cursor.y) { [vScrollBar setIndex:cursor.y]; } @@ -223,15 +317,17 @@ handleEvent (Editor *self, qwaq_event_t *event) return self; } --cursorDown:(unsigned)count +-charDown { [self recenter:0]; - if (count > line_count - cursor.y) { - count = line_count - cursor.y; + if (cursor.y >= line_count) { + return self; } - cursor.y += count; - line_index = [buffer nextLine:line_index :count]; + cursor.y++; + line_index = [buffer nextLine:line_index :1]; char_index = [buffer charPtr:line_index at:cursor.x]; + [self trackCursor:1]; + if (base.y + ylen - 1 < cursor.y) { [vScrollBar setIndex:cursor.y + 1 - ylen]; } @@ -239,14 +335,16 @@ handleEvent (Editor *self, qwaq_event_t *event) return self; } --cursorLeft:(unsigned)count +-charLeft { [self recenter:0]; - if (count > cursor.x) { - count = cursor.x; + if (cursor.x < 1) { + return self; } - cursor.x -= count; + cursor.x--; char_index = [buffer charPtr:line_index at:cursor.x]; + [self trackCursor:0]; + if (base.x > cursor.x) { [hScrollBar setIndex:cursor.x]; } @@ -254,12 +352,14 @@ handleEvent (Editor *self, qwaq_event_t *event) return self; } --cursorRight:(unsigned)count +-charRight { [self recenter:0]; // FIXME handle horizontal scrolling and how to deal with max scroll - cursor.x += count; + cursor.x++; char_index = [buffer charPtr:line_index at:cursor.x]; + [self trackCursor:1]; + if (base.x + xlen - 1 < cursor.x) { [hScrollBar setIndex:cursor.x + 1 - xlen]; } diff --git a/ruamoko/qwaq/editor/status.h b/ruamoko/qwaq/editor/status.h new file mode 100644 index 000000000..0c8dec1eb --- /dev/null +++ b/ruamoko/qwaq/editor/status.h @@ -0,0 +1,23 @@ +#ifndef __qwaq_editor_status_h +#define __qwaq_editor_status_h + +#include "ruamoko/qwaq/ui/view.h" + +typedef enum { + cmInsert, + cmTypeOver, + cmVInsert, + cmVTypeOver, +} CursorMode; + +@interface EditStatus : View +{ + CursorMode cursorMode; + int modified; +} ++(EditStatus *)withRect:(Rect)rect; +-setCursorMode:(CursorMode)mode; +-setModified:(int)modified; +@end + +#endif//__qwaq_editor_status_h diff --git a/ruamoko/qwaq/editor/status.r b/ruamoko/qwaq/editor/status.r new file mode 100644 index 000000000..1f9d1f09d --- /dev/null +++ b/ruamoko/qwaq/editor/status.r @@ -0,0 +1,43 @@ +#include "ruamoko/qwaq/editor/status.h" + +static int cursor_modes[] = { 'I', 'O', 'i', 'o' }; + +@implementation EditStatus + +-initWithRect:(Rect)rect +{ + if (!(self = [super initWithRect: rect])) { + return nil; + } + growMode = gfGrowNone; + return self; +} + ++(EditStatus *)withRect:(Rect)rect +{ + return [[self alloc] initWithRect:rect]; +} + +-setCursorMode:(CursorMode)mode +{ + cursorMode = mode; + return self; +} + +-setModified:(int)modified +{ + self.modified = modified; + return self; +} + +-draw +{ + [super draw]; + if (modified) { + [self mvaddch:{0, 0}, '*']; + } + [self mvaddch:{1, 0}, cursor_modes[cursorMode]]; + return self; +} + +@end