mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
[qwaq] Add a scrollbar view
This commit is contained in:
parent
dff0fd983c
commit
5bc57518b7
8 changed files with 332 additions and 0 deletions
|
@ -40,6 +40,7 @@ qwaq_app_dat_src= \
|
|||
ui/listener.r \
|
||||
ui/proxyview.r \
|
||||
ui/rect.r \
|
||||
ui/scrollbar.r \
|
||||
ui/textcontext.r \
|
||||
ui/titlebar.r \
|
||||
ui/view.r \
|
||||
|
|
|
@ -85,6 +85,7 @@ typedef enum qwaq_commands_e {
|
|||
qwaq_cmd_wresize,
|
||||
qwaq_cmd_resizeterm,
|
||||
qwaq_cmd_mvwhline,
|
||||
qwaq_cmd_mvwvline,
|
||||
} qwaq_commands;
|
||||
|
||||
static const char *qwaq_command_names[]= {
|
||||
|
@ -118,6 +119,7 @@ static const char *qwaq_command_names[]= {
|
|||
"wresize",
|
||||
"resizeterm",
|
||||
"mvwhline"
|
||||
"mvwvline"
|
||||
};
|
||||
|
||||
static window_t *
|
||||
|
@ -615,6 +617,19 @@ cmd_mvwhline (qwaq_resources_t *res)
|
|||
mvwhline (window->win, y, x, ch, n);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_mvwvline (qwaq_resources_t *res)
|
||||
{
|
||||
int window_id = RB_PEEK_DATA (res->command_queue, 2);
|
||||
int x = RB_PEEK_DATA (res->command_queue, 3);
|
||||
int y = RB_PEEK_DATA (res->command_queue, 4);
|
||||
int ch = RB_PEEK_DATA (res->command_queue, 5);
|
||||
int n = RB_PEEK_DATA (res->command_queue, 6);
|
||||
|
||||
window_t *window = get_window (res, __FUNCTION__, window_id);
|
||||
mvwvline (window->win, y, x, ch, n);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_command (qwaq_resources_t *res, int len)
|
||||
{
|
||||
|
@ -757,6 +772,9 @@ process_commands (qwaq_resources_t *res)
|
|||
case qwaq_cmd_mvwhline:
|
||||
cmd_mvwhline (res);
|
||||
break;
|
||||
case qwaq_cmd_mvwvline:
|
||||
cmd_mvwvline (res);
|
||||
break;
|
||||
}
|
||||
pthread_mutex_lock (&res->command_cond.mut);
|
||||
RB_DROP_DATA (res->command_queue, len);
|
||||
|
@ -1109,6 +1127,33 @@ bi_mvwhline (progs_t *pr)
|
|||
qwaq_mvwhline (pr, window_id, x, y, ch, n);
|
||||
}
|
||||
|
||||
static void
|
||||
qwaq_mvwvline (progs_t *pr, int window_id, int x, int y, int ch, int n)
|
||||
{
|
||||
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
|
||||
|
||||
if (get_window (res, __FUNCTION__, window_id)) {
|
||||
int command[] = {
|
||||
qwaq_cmd_mvwvline, 0,
|
||||
window_id, x, y, ch, n
|
||||
};
|
||||
|
||||
command[1] = CMD_SIZE(command);
|
||||
qwaq_submit_command (res, command);
|
||||
}
|
||||
}
|
||||
static void
|
||||
bi_mvwvline (progs_t *pr)
|
||||
{
|
||||
int window_id = P_STRUCT (pr, qwaq_textcontext_t, 0).window;
|
||||
int x = P_INT (pr, 1);
|
||||
int y = P_INT (pr, 2);
|
||||
int ch = P_INT (pr, 3);
|
||||
int n = P_INT (pr, 4);
|
||||
|
||||
qwaq_mvwvline (pr, window_id, x, y, ch, n);
|
||||
}
|
||||
|
||||
static void
|
||||
qwaq_mvwaddstr (progs_t *pr, int window_id, int x, int y, const char *str)
|
||||
{
|
||||
|
@ -1821,6 +1866,18 @@ bi_i_TextContext__mvhline_ (progs_t *pr)
|
|||
qwaq_mvwhline (pr, window_id, pos->x, pos->y, ch, n);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_i_TextContext__mvvline_ (progs_t *pr)
|
||||
{
|
||||
__auto_type self = &P_STRUCT (pr, qwaq_textcontext_t, 0);
|
||||
int window_id = self->window;
|
||||
__auto_type pos = &P_PACKED (pr, Point, 2);
|
||||
int ch = P_INT (pr, 3);
|
||||
int n = P_INT (pr, 4);
|
||||
|
||||
qwaq_mvwvline (pr, window_id, pos->x, pos->y, ch, n);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_qwaq_clear (progs_t *pr, void *data)
|
||||
{
|
||||
|
@ -1875,6 +1932,7 @@ static builtin_t builtins[] = {
|
|||
{"wresize", bi_wresize, -1},
|
||||
{"resizeterm", bi_resizeterm, -1},
|
||||
{"mvwhline", bi_mvwhline, -1},
|
||||
{"mvwvline", bi_mvwvline, -1},
|
||||
|
||||
{"_c_TextContext__is_initialized", bi_c_TextContext__is_initialized, -1},
|
||||
{"_c_TextContext__max_colors", bi_c_TextContext__max_colors, -1},
|
||||
|
@ -1900,6 +1958,7 @@ static builtin_t builtins[] = {
|
|||
{"_i_TextContext__scrollok_", bi_i_TextContext__scrollok_, -1},
|
||||
{"_i_TextContext__border_", bi_i_TextContext__border_, -1},
|
||||
{"_i_TextContext__mvhline_", bi_i_TextContext__mvhline_, -1},
|
||||
{"_i_TextContext__mvvline_", bi_i_TextContext__mvvline_, -1},
|
||||
|
||||
{0}
|
||||
};
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
- (void) mvvprintf: (Point) pos, string fmt, @va_list args;
|
||||
- (void) mvaddch: (Point) pos, int ch;
|
||||
- (void) mvaddstr: (Point) pos, string str;
|
||||
- (void) mvhline:(Point)pos, int ch, int len;
|
||||
- (void) mvvline:(Point)pos, int ch, int len;
|
||||
@end
|
||||
|
||||
@interface DrawBuffer : Object <DrawBuffer, TextContext>
|
||||
|
|
|
@ -248,4 +248,20 @@
|
|||
[self addstr: str];
|
||||
}
|
||||
|
||||
- (void) mvhline:(Point)pos, int ch, int len
|
||||
{
|
||||
while (len-- > 0) {
|
||||
[self mvaddch:pos, ch];
|
||||
pos.x++;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mvvline:(Point)pos, int ch, int len
|
||||
{
|
||||
while (len-- > 0) {
|
||||
[self mvaddch:pos, ch];
|
||||
pos.y++;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
35
ruamoko/qwaq/ui/scrollbar.h
Normal file
35
ruamoko/qwaq/ui/scrollbar.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef __qwaq_ui_scrollbar_h
|
||||
#define __qwaq_ui_scrollbar_h
|
||||
|
||||
#include "ui/view.h"
|
||||
|
||||
@class Button;
|
||||
@class Group;
|
||||
@class ListenerGroup;
|
||||
|
||||
@interface ScrollBar : View
|
||||
{
|
||||
int vertical;
|
||||
int bgchar;
|
||||
Point mouseStart;
|
||||
Button *backButton;
|
||||
Button *forwardButton;
|
||||
Button *thumbTab;
|
||||
Group *objects;
|
||||
ListenerGroup *onScroll;
|
||||
|
||||
unsigned pageStep;
|
||||
unsigned singleStep;
|
||||
unsigned range;
|
||||
unsigned index;
|
||||
}
|
||||
+(ScrollBar *)horizontal:(unsigned)len at:(Point)pos;
|
||||
+(ScrollBar *)vertical:(unsigned)len at:(Point)pos;
|
||||
-(ListenerGroup *)onScroll;
|
||||
-setRange:(unsigned)range;
|
||||
-setPageStep:(unsigned)pageStep;
|
||||
-setSingleStep:(unsigned)singleStep;
|
||||
-setIndex:(unsigned)index;
|
||||
@end
|
||||
|
||||
#endif//__qwaq_ui_scrollbar_h
|
216
ruamoko/qwaq/ui/scrollbar.r
Normal file
216
ruamoko/qwaq/ui/scrollbar.r
Normal file
|
@ -0,0 +1,216 @@
|
|||
#include "ui/button.h"
|
||||
#include "ui/group.h"
|
||||
#include "ui/listener.h"
|
||||
#include "ui/scrollbar.h"
|
||||
|
||||
@implementation ScrollBar
|
||||
|
||||
-initWithRect:(Rect)rect
|
||||
{
|
||||
if (!(self = [super initWithRect:rect])) {
|
||||
return nil;
|
||||
}
|
||||
objects = [[Group withContext:textContext owner:self] retain];
|
||||
onScroll = [[ListenerGroup listener] retain];
|
||||
vertical = xlen == 1;
|
||||
DrawBuffer *icons[3] = {
|
||||
[DrawBuffer buffer:{1, 1}],
|
||||
[DrawBuffer buffer:{1, 1}],
|
||||
[DrawBuffer buffer:{1, 1}],
|
||||
};
|
||||
[icons[2] addch:acs_char (ACS_DIAMOND)];
|
||||
Point thumbPos;
|
||||
SEL thumbSel;
|
||||
growMode = gfGrowAll;
|
||||
if (vertical) {
|
||||
[icons[0]addch:acs_char (ACS_UARROW)];
|
||||
[icons[1]addch:acs_char (ACS_DARROW)];
|
||||
thumbPos = {0, 1};
|
||||
thumbSel = @selector(verticalSlide);
|
||||
growMode &= ~gfGrowLoY;
|
||||
} else {
|
||||
[icons[0]addch:acs_char (ACS_LARROW)];
|
||||
[icons[1]addch:acs_char (ACS_RARROW)];
|
||||
thumbPos = {1, 0};
|
||||
thumbSel = @selector(horizontalSlide);
|
||||
growMode &= ~gfGrowLoX;
|
||||
}
|
||||
bgchar = acs_char (ACS_CKBOARD);
|
||||
backButton = [Button withPos:{0, 0}
|
||||
releasedIcon:icons[0] pressedIcon:icons[0]];
|
||||
forwardButton = [Button withPos:{xlen - 1, ylen - 1}
|
||||
releasedIcon:icons[1] pressedIcon:icons[1]];
|
||||
thumbTab = [Button withPos:thumbPos
|
||||
releasedIcon:icons[2] pressedIcon:icons[2]];
|
||||
|
||||
[[backButton onPress] addListener:self :@selector(scrollBack:)];
|
||||
[[forwardButton onPress] addListener:self :@selector(scrollForward:)];
|
||||
[[thumbTab onPress] addListener:self :thumbSel];
|
||||
|
||||
singleStep = 1;
|
||||
|
||||
[objects insert:backButton];
|
||||
[objects insert:forwardButton];
|
||||
[objects insert:thumbTab];
|
||||
return self;
|
||||
}
|
||||
|
||||
+(ScrollBar *)horizontal:(unsigned)len at:(Point)pos
|
||||
{
|
||||
if (len == 1) {
|
||||
[self error:"can't make scrollbar of length 1"];
|
||||
}
|
||||
return [[[self alloc] initWithRect:{pos, {len, 1}}] autorelease];
|
||||
}
|
||||
|
||||
+(ScrollBar *)vertical:(unsigned)len at:(Point)pos
|
||||
{
|
||||
if (len == 1) {
|
||||
[self error:"can't make scrollbar of length 1"];
|
||||
}
|
||||
return [[[self alloc] initWithRect:{pos, {1, len}}] autorelease];
|
||||
}
|
||||
|
||||
-(ListenerGroup *)onScroll
|
||||
{
|
||||
return onScroll;
|
||||
}
|
||||
|
||||
-draw
|
||||
{
|
||||
if (vertical) {
|
||||
[self mvvline:pos, bgchar, ylen];
|
||||
} else {
|
||||
[self mvhline:pos, bgchar, xlen];
|
||||
}
|
||||
[super draw];
|
||||
[objects draw];
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
position_tab (ScrollBar *self)
|
||||
{
|
||||
Point p = {0, 0};
|
||||
Point o = [self.thumbTab origin];
|
||||
if (self.range > 0) {
|
||||
if (self.vertical) {
|
||||
p.y = 1 + self.index * (self.ylen - 2) / (self.range - 1);
|
||||
} else {
|
||||
p.x = 1 + self.index * (self.xlen - 2) / (self.range - 1);
|
||||
}
|
||||
}
|
||||
[self.thumbTab move:{p.x - o.x, p.y - o.y}];
|
||||
}
|
||||
|
||||
-resize:(Extent)delta
|
||||
{
|
||||
Extent size = self.size;
|
||||
[super resize:delta];
|
||||
delta = {self.size.width - size.width, self.size.height - size.height};
|
||||
[objects resize:delta];
|
||||
position_tab (self);
|
||||
return self;
|
||||
}
|
||||
|
||||
-page:(unsigned)step dir:(unsigned) dir
|
||||
{
|
||||
unsigned oind = index;
|
||||
|
||||
if (dir) {
|
||||
if (range - 1 - index < step) {
|
||||
step = range - 1 - index;
|
||||
}
|
||||
index += step;
|
||||
} else {
|
||||
if (index < step) {
|
||||
step = index;
|
||||
}
|
||||
index -= step;
|
||||
}
|
||||
|
||||
if (index != oind) {
|
||||
position_tab (self);
|
||||
[onScroll respond:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
page (ScrollBar *self, Point pos)
|
||||
{
|
||||
unsigned pageDir = 0;
|
||||
if (self.vertical) {
|
||||
if (pos.y < [self.thumbTab origin].y) {
|
||||
pageDir = 0;
|
||||
} else {
|
||||
pageDir = 1;
|
||||
}
|
||||
} else {
|
||||
if (pos.x < [self.thumbTab origin].x) {
|
||||
pageDir = 0;
|
||||
} else {
|
||||
pageDir = 1;
|
||||
}
|
||||
}
|
||||
[self page:self.pageStep dir:pageDir];
|
||||
}
|
||||
|
||||
-(void)scrollBack:(id)sender
|
||||
{
|
||||
[self page:singleStep dir:0];
|
||||
}
|
||||
|
||||
-(void)scrollForward:(id)sender
|
||||
{
|
||||
[self page:singleStep dir:1];
|
||||
}
|
||||
|
||||
-handleEvent:(qwaq_event_t *)event
|
||||
{
|
||||
[super handleEvent: event];
|
||||
[objects handleEvent: event];
|
||||
if (event.what == qe_mousedown) {
|
||||
[self grabMouse];
|
||||
mouseStart = {event.mouse.x, event.mouse.y};
|
||||
page(self, mouseStart);
|
||||
event.what = qe_none;
|
||||
} else if (event.what==qe_mouseauto) {
|
||||
page(self, mouseStart);
|
||||
event.what = qe_none;
|
||||
} else if (event.what == qe_mouseup) {
|
||||
[self releaseMouse];
|
||||
event.what = qe_none;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-setRange:(unsigned)range
|
||||
{
|
||||
self.range = range;
|
||||
return self;
|
||||
}
|
||||
|
||||
-setPageStep:(unsigned)pageStep
|
||||
{
|
||||
self.pageStep = pageStep;
|
||||
return self;
|
||||
}
|
||||
|
||||
-setSingleStep:(unsigned)singleStep
|
||||
{
|
||||
self.singleStep = singleStep;
|
||||
return self;
|
||||
}
|
||||
|
||||
-setIndex:(unsigned)index
|
||||
{
|
||||
if (index > self.index) {
|
||||
[self page:index - self.index dir:1];
|
||||
} else {
|
||||
[self page:self.index - index dir:0];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -55,6 +55,7 @@
|
|||
- (void) scrollok: (int) flag;
|
||||
- (void) border: (box_sides_t) sides, box_corners_t corners;
|
||||
- (void) mvhline: (Point) pos, int ch, int n;
|
||||
- (void) mvvline: (Point) pos, int ch, int n;
|
||||
-clearReact: (Rect) rect;
|
||||
@end
|
||||
|
||||
|
|
|
@ -163,6 +163,7 @@ static TextContext *screen;
|
|||
- (void) mvaddch: (Point) pos, int ch = #0;
|
||||
- (void) mvaddstr: (Point) pos, string str = #0;
|
||||
- (void) mvhline: (Point) pos, int ch, int n = #0;
|
||||
- (void) mvvline: (Point) pos, int ch, int n = #0;
|
||||
|
||||
- (void) resizeTo: (Extent) newSize = #0; // absolute size
|
||||
- (void) refresh = #0;
|
||||
|
@ -218,5 +219,6 @@ void wresize (window_t window, int width, int height) = #0;
|
|||
void resizeterm (int width, int height) = #0;
|
||||
Rect getwrect (window_t window) = #0;
|
||||
void mvwhline (window_t win, int x, int y, int ch, int n) = #0;
|
||||
void mvwvline (window_t win, int x, int y, int ch, int n) = #0;
|
||||
|
||||
void printf(string fmt, ...) = #0;
|
||||
|
|
Loading…
Reference in a new issue