/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2012 Olaf Wintermann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import <stdio.h>
#import <stdlib.h>
#import "tree.h"
#import "container.h"
#import "window.h"
#import "../common/context.h"
#import <ucx/utils.h>
@implementation UiTableDataSource
- (id)initWithData:(UiList*)list modelInfo:(UiModelInfo*)modelinfo {
data = list;
info = modelinfo;
lastSelection = NULL;
return self;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableview {
return data->count(data);
}
- (id)tableView: (NSTableView*)tableview
objectValueForTableColumn:(NSTableColumn*)column
row:(NSInteger)row
{
int column_index = [[column identifier]intValue];
void *row_data = data->get(data, row);
void *cell_data = info->getvalue(row_data, column_index);
BOOL f = false;
char *str = ui_type_to_string(info->types[column_index], cell_data, &f);
NSString *s = [[NSString alloc]initWithUTF8String:str];
return s;
}
- (void)tableView:(NSTableView *)tableview
setObjectValue:(id)object
forTableColumn:(NSTableColumn *)column
row:(NSInteger)row
{
int column_index = [[column identifier]intValue];
// TODO
}
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
NSTableView *tableview = (NSTableView*)notification.object;
// create selection object
UiListSelection *selection = malloc(sizeof(UiListSelection));
selection->count = [tableview numberOfSelectedRows];
selection->rows = calloc(selection->count, sizeof(int));
NSIndexSet *indices = [tableview selectedRowIndexes];
NSUInteger index = [indices firstIndex];
int i=0;
while (index!=NSNotFound) {
selection->rows[i] = index;
index = [indices indexGreaterThanIndex:index];
i++;
}
// create event object
UiEvent event;
NSWindow *activeWindow = [NSApp keyWindow];
if([activeWindow class] == [UiCocoaWindow class]) {
event.obj = [(UiCocoaWindow*)activeWindow object];
event.window = event.obj->window;
event.document = event.obj->ctx->document;
} else {
event.window = NULL;
event.document = NULL;
}
event.eventdata = selection;
event.intval = selection->count == 0 ? -1 : selection->rows[0];
// callback
info->selection(&event, info->userdata);
// cleanup
if(lastSelection) {
free(lastSelection->rows);
free(lastSelection);
}
lastSelection = selection;
}
- (void)handleDoubleAction:(id)sender {
// create event object
UiEvent event;
NSWindow *activeWindow = [NSApp keyWindow];
if([activeWindow class] == [UiCocoaWindow class]) {
event.obj = [(UiCocoaWindow*)activeWindow object];
event.window = event.obj->window;
event.document = event.obj->ctx->document;
} else {
event.window = NULL;
event.document = NULL;
}
event.eventdata = lastSelection;
event.intval = lastSelection->count == 0 ? -1 : lastSelection->rows[0];
info->activate(&event, info->userdata);
}
- (BOOL)tableView:(NSTableView *)tableview isGroupRow:(NSInteger)row {
return NO;
}
@end
UIWIDGET ui_table(UiObject *obj, UiList *model, UiModelInfo *modelinfo) {
UiContainer *ct = uic_get_current_container(obj);
NSRect frame = ct->getframe(ct);
NSScrollView *scrollview = [[NSScrollView alloc] initWithFrame:frame];
[scrollview setHasVerticalScroller:YES];
//[scrollvew setHasHorizontalScroller:YES];
[scrollview setBorderType:NSNoBorder];
//[scrollview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
NSTableView *tableview = [[NSTableView alloc]initWithFrame:frame];
[scrollview setDocumentView:tableview];
[tableview setAllowsMultipleSelection: YES];
//[tableview setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
// add columns
for(int i=0;i<modelinfo->columns;i++) {
NSString *cid = [[NSString alloc]initWithFormat: @"%d", i];
NSTableColumn *column = [[NSTableColumn alloc]initWithIdentifier:cid];
NSString *title = [[NSString alloc]initWithUTF8String: modelinfo->titles[i]];
[[column headerCell] setStringValue:title];
[tableview addTableColumn:column];
}
UiTableDataSource *source = [[UiTableDataSource alloc]initWithData:model modelInfo:modelinfo];
[tableview setDataSource:source];
[tableview setDelegate:source];
[tableview setDoubleAction:@selector(handleDoubleAction:)];
[tableview setTarget:source];
ct->add(ct, scrollview);
return scrollview;
}
UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
UiContainer *ct = uic_get_current_container(obj);
NSRect frame = ct->getframe(ct);
NSScrollView *scrollview = [[NSScrollView alloc] initWithFrame:frame];
[scrollview setHasVerticalScroller:YES];
[scrollview setBorderType:NSNoBorder];
NSTableView *tableview = [[NSTableView alloc]initWithFrame:frame];
[scrollview setDocumentView:tableview];
[tableview setAllowsMultipleSelection: NO];
// add single column
NSTableColumn *column = [[NSTableColumn alloc]initWithIdentifier:@"c"];
[tableview addTableColumn:column];
// create model info
UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, -1);
// add source
UiTableDataSource *source = [[UiTableDataSource alloc]initWithData:list->list modelInfo:modelinfo];
[tableview setDataSource:source];
[tableview setDelegate:source];
[tableview setDoubleAction:@selector(handleDoubleAction:)];
[tableview setTarget:source];
ct->add(ct, scrollview);
return scrollview;
}
UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr));
listptr->list = list;
return ui_listview_var(obj, listptr, getvalue, f, udata);
}
UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST);
if(var) {
UiListVar *value = var->value;
return ui_listview_var(obj, value->listptr, getvalue, f, udata);
} else {
// TODO: error
}
return NULL;
}
// TODO: motif code duplicate
char* ui_type_to_string(UiModelType type, void *data, BOOL *free) {
switch(type) {
case UI_STRING: *free = FALSE; return data;
case UI_INTEGER: {
*free = TRUE;
int *val = data;
sstr_t str = ucx_asprintf(ucx_default_allocator(), "%d", *val);
return str.ptr;
}
}
*free = FALSE;
return NULL;
}