#include #include "ruamoko/qwaq/ui/listener.h" #include "ruamoko/qwaq/ui/scrollbar.h" #include "ruamoko/qwaq/ui/tableview.h" @implementation TableViewColumn -initWithName:(string)name width:(int)width { if (!(self = [super init])) { return nil; } self.name = name; self.width = width; return self; } +(TableViewColumn *)named:(string)name { return [[[self alloc] initWithName:name width:-1] autorelease]; } +(TableViewColumn *)named:(string)name width:(int)width { return [[[self alloc] initWithName:name width:width] autorelease]; } -setGrowMode: (int) mode { growMode = mode; return self; } -(int)growMode { return growMode; } -(string)name { return name; } -(int)width { return width; } -setWidth:(int)width { self.width = width; return self; } -grow:(Extent)delta { if (growMode & gfGrowHiX) { width += delta.width; } return self; } @end @implementation TableView -initWithRect:(Rect)rect { if (!(self = [super initWithRect:rect])) { return nil; } options = ofCanFocus | ofRelativeEvents; columns = [[Array array] retain]; buffer = [[DrawBuffer buffer:size] retain]; [buffer bkgd:' ']; [onViewScrolled addListener:self :@selector(onScroll:)]; growMode = gfGrowHi; return self; } -(void)dealloc { [columns release]; [buffer release]; [dataSource release]; [super dealloc]; } +(TableView *)withRect:(Rect)rect { return [[[self alloc] initWithRect:rect] autorelease]; } -addColumn:(TableViewColumn *)column { [columns addObject:column]; columns_dirty = 1; return self; } -setDataSource:(id)dataSource { self.dataSource = [dataSource retain]; [[dataSource onRowCountChanged] addListener:self :@selector(onRowCountChanged:)]; [vScrollBar setRange:[dataSource numberOfRows:self]]; return self; } -(void)onRowCountChanged:(id)sender { [vScrollBar setRange:[sender numberOfRows:self]]; } -resize:(Extent)delta { Extent size = self.size; [super resize:delta]; [buffer resizeTo:self.size]; for (int i = [columns count]; i-- > 0; ) { [[columns objectAtIndex: i] grow: delta]; } return self; } -draw { View *cell; TableViewColumn *col; [super draw]; int numCols = [columns count]; int numRows = [dataSource numberOfRows:self]; [buffer clear]; for (int y = 0; y < ylen; y++) { for (int i = 0, x = 0; i < numCols; i++) { int row = base.y + y; if (row >= numRows) { break; } col = [columns objectAtIndex:i]; cell = [dataSource tableView:self forColumn:col row:row]; [[[[cell setContext:buffer] moveTo:{x, y}] resizeTo:{[col width], 1}] draw]; x += [col width]; } } [textContext blitFromBuffer:buffer to:pos from:[buffer rect]]; return self; } -(void)onScroll:(id)sender { if (base.y != scroll.y) { base.y = scroll.y; [self redraw]; } } static int handleEvent (TableView *self, qwaq_event_t *event) { if (event.what & qe_mouse) { if (event.what == qe_mouseclick) { if (event.mouse.buttons & (1 << 3)) { [self.vScrollBar page:1 dir:0]; return 1; } if (event.mouse.buttons & (1 << 4)) { [self.vScrollBar page:1 dir:1]; return 1; } #if 0 if (event.mouse.buttons & (1 << 5)) { [self scrollLeft: 1]; return 1; } if (event.mouse.buttons & (1 << 6)) { [self scrollRight: 1]; return 1; } #endif } } else if (event.what == qe_keydown) { #if 0 switch (event.key.code) { case QFK_PAGEUP: if (event.key.shift & qe_control) { [self moveBOT]; } else { [self pageUp]; } return 1; case QFK_PAGEDOWN: if (event.key.shift & qe_control) { [self moveEOT]; } else { [self pageDown]; } return 1; case QFK_UP: if (event.key.shift & qe_control) { [self linesUp]; } else { [self charUp]; } return 1; case QFK_DOWN: if (event.key.shift & qe_control) { [self linesDown]; } else { [self charDown]; } return 1; case QFK_LEFT: if (event.key.shift & qe_control) { [self wordLeft]; } else { [self charLeft]; } return 1; case QFK_RIGHT: if (event.key.shift & qe_control) { [self wordRight]; } else { [self charRight]; } return 1; case QFK_HOME: if (event.key.shift & qe_control) { [self moveBOS]; } else { [self moveBOL]; } return 1; case QFK_END: if (event.key.shift & qe_control) { [self moveEOS]; } else { [self moveEOL]; } return 1; } #endif } return 0; } -handleEvent:(qwaq_event_t *) event { [super handleEvent: event]; if (handleEvent (self, event)) { event.what = qe_none; } return self; } @end