2018-06-03 12:28:11 -05:00
|
|
|
// 3 june 2018
|
|
|
|
#import "uipriv_darwin.h"
|
2018-06-03 19:55:08 -05:00
|
|
|
#import "table.h"
|
2018-06-03 12:28:11 -05:00
|
|
|
|
|
|
|
// values from interface builder
|
|
|
|
#define textColumnLeading 2
|
|
|
|
#define textColumnTrailing 2
|
2018-06-03 13:13:32 -05:00
|
|
|
#define imageColumnLeading 3
|
|
|
|
#define imageTextColumnLeading 7
|
2018-06-03 15:50:00 -05:00
|
|
|
#define checkboxTextColumnLeading 0
|
|
|
|
// these aren't provided by IB; let's just choose one
|
|
|
|
#define checkboxColumnLeading imageColumnLeading
|
2018-06-03 17:34:29 -05:00
|
|
|
#define progressBarColumnLeading imageColumnLeading
|
|
|
|
#define progressBarColumnTrailing progressBarColumnLeading
|
2018-06-04 19:09:09 -05:00
|
|
|
#define buttonColumnLeading imageColumnLeading
|
|
|
|
#define buttonColumnTrailing buttonColumnLeading
|
2018-06-03 12:28:11 -05:00
|
|
|
|
2018-06-03 19:55:08 -05:00
|
|
|
@implementation uiprivTableCellView
|
2018-06-03 12:28:11 -05:00
|
|
|
|
|
|
|
- (void)uiprivUpdate:(NSInteger)row
|
|
|
|
{
|
|
|
|
[self doesNotRecognizeSelector:_cmd];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-03 18:59:05 -05:00
|
|
|
@implementation uiprivTableColumn
|
|
|
|
|
2018-06-03 19:55:08 -05:00
|
|
|
- (uiprivTableCellView *)uiprivMakeCellView
|
2018-06-03 18:59:05 -05:00
|
|
|
{
|
2018-06-03 19:55:08 -05:00
|
|
|
[self doesNotRecognizeSelector:_cmd];
|
2018-06-03 22:06:44 -05:00
|
|
|
return nil; // appease compiler
|
2018-06-03 18:59:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-03 15:50:00 -05:00
|
|
|
struct textColumnCreateParams {
|
2018-06-03 12:28:11 -05:00
|
|
|
uiTable *t;
|
|
|
|
uiTableModel *m;
|
|
|
|
|
2018-06-03 15:50:00 -05:00
|
|
|
BOOL makeTextField;
|
|
|
|
int textModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
int textEditableModelColumn;
|
2018-06-03 15:50:00 -05:00
|
|
|
uiTableTextColumnOptionalParams textParams;
|
2018-06-03 12:28:11 -05:00
|
|
|
|
2018-06-24 13:46:24 -05:00
|
|
|
BOOL makeImageView;
|
2018-06-03 15:50:00 -05:00
|
|
|
int imageModelColumn;
|
2018-06-03 13:13:32 -05:00
|
|
|
|
2018-06-03 15:50:00 -05:00
|
|
|
BOOL makeCheckbox;
|
|
|
|
int checkboxModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
int checkboxEditableModelColumn;
|
2018-06-03 15:50:00 -05:00
|
|
|
};
|
2018-06-03 13:13:32 -05:00
|
|
|
|
2018-06-03 19:55:08 -05:00
|
|
|
@interface uiprivTextImageCheckboxTableCellView : uiprivTableCellView {
|
2018-06-03 13:13:32 -05:00
|
|
|
uiTable *t;
|
|
|
|
uiTableModel *m;
|
2018-06-03 15:50:00 -05:00
|
|
|
|
2018-06-03 13:13:32 -05:00
|
|
|
NSTextField *tf;
|
|
|
|
int textModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
int textEditableModelColumn;
|
2018-06-03 15:50:00 -05:00
|
|
|
uiTableTextColumnOptionalParams textParams;
|
|
|
|
|
|
|
|
NSImageView *iv;
|
|
|
|
int imageModelColumn;
|
|
|
|
|
|
|
|
NSButton *cb;
|
|
|
|
int checkboxModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
int checkboxEditableModelColumn;
|
2018-06-03 13:13:32 -05:00
|
|
|
}
|
2018-06-03 15:50:00 -05:00
|
|
|
- (id)initWithFrame:(NSRect)r params:(struct textColumnCreateParams *)p;
|
|
|
|
- (IBAction)uiprivOnTextFieldAction:(id)sender;
|
|
|
|
- (IBAction)uiprivOnCheckboxAction:(id)sender;
|
2018-06-03 13:13:32 -05:00
|
|
|
@end
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
@implementation uiprivTextImageCheckboxTableCellView
|
2018-06-03 13:13:32 -05:00
|
|
|
|
2018-06-03 15:50:00 -05:00
|
|
|
- (id)initWithFrame:(NSRect)r params:(struct textColumnCreateParams *)p
|
2018-06-03 13:13:32 -05:00
|
|
|
{
|
2018-06-03 22:06:44 -05:00
|
|
|
self = [super initWithFrame:r];
|
2018-06-03 13:13:32 -05:00
|
|
|
if (self) {
|
2018-06-04 19:03:05 -05:00
|
|
|
NSMutableArray *constraints;
|
2018-06-03 15:50:00 -05:00
|
|
|
|
|
|
|
self->t = p->t;
|
|
|
|
self->m = p->m;
|
2018-06-04 19:03:05 -05:00
|
|
|
constraints = [NSMutableArray new];
|
2018-06-03 13:13:32 -05:00
|
|
|
|
|
|
|
self->tf = nil;
|
2018-06-03 15:50:00 -05:00
|
|
|
if (p->makeTextField) {
|
|
|
|
self->textModelColumn = p->textModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
self->textEditableModelColumn = p->textEditableModelColumn;
|
2018-06-03 15:50:00 -05:00
|
|
|
self->textParams = p->textParams;
|
|
|
|
|
2018-06-03 13:13:32 -05:00
|
|
|
self->tf = uiprivNewLabel(@"");
|
|
|
|
// TODO set wrap and ellipsize modes?
|
|
|
|
[self->tf setTarget:self];
|
2018-06-03 15:50:00 -05:00
|
|
|
[self->tf setAction:@selector(uiprivOnTextFieldAction:)];
|
2018-06-04 19:03:05 -05:00
|
|
|
[self->tf setTranslatesAutoresizingMaskIntoConstraints:NO];
|
2018-06-03 13:13:32 -05:00
|
|
|
[self addSubview:self->tf];
|
2018-06-03 15:50:00 -05:00
|
|
|
|
2018-06-04 19:09:09 -05:00
|
|
|
// TODO for all three controls: set hugging and compression resistance properly
|
2018-06-04 19:03:05 -05:00
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeLeading,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->tf, NSLayoutAttributeLeading,
|
|
|
|
1, -textColumnLeading,
|
|
|
|
@"uiTable cell text leading constraint")];
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeTop,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->tf, NSLayoutAttributeTop,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell text top constraint")];
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeTrailing,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->tf, NSLayoutAttributeTrailing,
|
|
|
|
1, textColumnTrailing,
|
|
|
|
@"uiTable cell text trailing constraint")];
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeBottom,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->tf, NSLayoutAttributeBottom,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell text bottom constraint")];
|
|
|
|
}
|
2018-06-03 15:50:00 -05:00
|
|
|
|
|
|
|
self->iv = nil;
|
2018-06-24 13:46:24 -05:00
|
|
|
if (p->makeImageView) {
|
2018-06-04 17:17:05 -05:00
|
|
|
self->imageModelColumn = p->imageModelColumn;
|
|
|
|
|
2018-06-03 15:50:00 -05:00
|
|
|
self->iv = [[NSImageView alloc] initWithFrame:NSZeroRect];
|
|
|
|
[self->iv setImageFrameStyle:NSImageFrameNone];
|
|
|
|
[self->iv setImageAlignment:NSImageAlignCenter];
|
|
|
|
[self->iv setImageScaling:NSImageScaleProportionallyDown];
|
|
|
|
[self->iv setAnimates:NO];
|
|
|
|
[self->iv setEditable:NO];
|
2018-06-04 19:03:05 -05:00
|
|
|
[self->iv setTranslatesAutoresizingMaskIntoConstraints:NO];
|
|
|
|
[self addSubview:self->iv];
|
|
|
|
|
|
|
|
[constraints addObject:uiprivMkConstraint(self->iv, NSLayoutAttributeWidth,
|
2018-06-03 15:50:00 -05:00
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->iv, NSLayoutAttributeHeight,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable image squareness constraint")];
|
2018-06-04 19:03:05 -05:00
|
|
|
if (self->tf != nil) {
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeLeading,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->iv, NSLayoutAttributeLeading,
|
|
|
|
1, -imageColumnLeading,
|
|
|
|
@"uiTable cell image leading constraint")];
|
|
|
|
[constraints replaceObjectAtIndex:0
|
|
|
|
withObject:uiprivMkConstraint(self->iv, NSLayoutAttributeTrailing,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->tf, NSLayoutAttributeLeading,
|
|
|
|
1, -imageTextColumnLeading,
|
|
|
|
@"uiTable cell image-text spacing constraint")];
|
|
|
|
} else
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeCenterX,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->iv, NSLayoutAttributeCenterX,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell image centering constraint")];
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeTop,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->iv, NSLayoutAttributeTop,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell image top constraint")];
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeBottom,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->iv, NSLayoutAttributeBottom,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell image bottom constraint")];
|
2018-06-03 15:50:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
self->cb = nil;
|
|
|
|
if (p->makeCheckbox) {
|
2018-06-04 17:17:05 -05:00
|
|
|
self->checkboxModelColumn = p->checkboxModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
self->checkboxEditableModelColumn = p->checkboxEditableModelColumn;
|
2018-06-04 17:17:05 -05:00
|
|
|
|
2018-06-03 15:50:00 -05:00
|
|
|
self->cb = [[NSButton alloc] initWithFrame:NSZeroRect];
|
|
|
|
[self->cb setTitle:@""];
|
|
|
|
[self->cb setButtonType:NSSwitchButton];
|
|
|
|
// doesn't seem to have an associated bezel style
|
|
|
|
[self->cb setBordered:NO];
|
|
|
|
[self->cb setTransparent:NO];
|
|
|
|
uiDarwinSetControlFont(self->cb, NSRegularControlSize);
|
2018-06-04 19:03:05 -05:00
|
|
|
[self->cb setTranslatesAutoresizingMaskIntoConstraints:NO];
|
2018-06-03 15:50:00 -05:00
|
|
|
[self addSubview:self->cb];
|
|
|
|
|
2018-06-04 19:03:05 -05:00
|
|
|
if (self->tf != nil) {
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeLeading,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->cb, NSLayoutAttributeLeading,
|
|
|
|
1, -imageColumnLeading,
|
|
|
|
@"uiTable cell checkbox leading constraint")];
|
|
|
|
[constraints replaceObjectAtIndex:0
|
|
|
|
withObject:uiprivMkConstraint(self->cb, NSLayoutAttributeTrailing,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->tf, NSLayoutAttributeLeading,
|
|
|
|
1, -imageTextColumnLeading,
|
|
|
|
@"uiTable cell checkbox-text spacing constraint")];
|
|
|
|
} else
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeCenterX,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->cb, NSLayoutAttributeCenterX,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell checkbox centering constraint")];
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeTop,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->cb, NSLayoutAttributeTop,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell checkbox top constraint")];
|
|
|
|
[constraints addObject:uiprivMkConstraint(self, NSLayoutAttributeBottom,
|
2018-06-03 13:13:32 -05:00
|
|
|
NSLayoutRelationEqual,
|
2018-06-04 19:03:05 -05:00
|
|
|
self->cb, NSLayoutAttributeBottom,
|
2018-06-03 13:13:32 -05:00
|
|
|
1, 0,
|
2018-06-04 19:03:05 -05:00
|
|
|
@"uiTable cell checkbox bottom constraint")];
|
2018-06-03 13:13:32 -05:00
|
|
|
}
|
|
|
|
|
2018-06-04 19:03:05 -05:00
|
|
|
[self addConstraints:constraints];
|
|
|
|
|
2018-06-03 13:13:32 -05:00
|
|
|
// take advantage of NSTableCellView-provided accessibility features
|
|
|
|
if (self->tf != nil)
|
|
|
|
[self setTextField:self->tf];
|
2018-06-03 15:50:00 -05:00
|
|
|
if (self->iv != nil)
|
|
|
|
[self setImageView:self->iv];
|
2018-06-03 13:13:32 -05:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
2018-06-03 15:50:00 -05:00
|
|
|
if (self->cb != nil) {
|
|
|
|
[self->cb release];
|
|
|
|
self->cb = nil;
|
|
|
|
}
|
|
|
|
if (self->iv != nil) {
|
|
|
|
[self->iv release];
|
|
|
|
self->iv = nil;
|
|
|
|
}
|
2018-06-03 13:13:32 -05:00
|
|
|
if (self->tf != nil) {
|
|
|
|
[self->tf release];
|
|
|
|
self->tf = nil;
|
|
|
|
}
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)uiprivUpdate:(NSInteger)row
|
|
|
|
{
|
2018-06-23 19:19:30 -05:00
|
|
|
uiTableValue *value;
|
2018-06-03 15:50:00 -05:00
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
if (self->tf != nil) {
|
2018-06-03 15:50:00 -05:00
|
|
|
NSString *str;
|
2018-06-03 22:06:44 -05:00
|
|
|
NSColor *color;
|
2018-06-24 13:22:05 -05:00
|
|
|
double r, g, b, a;
|
2018-06-03 15:50:00 -05:00
|
|
|
|
2018-06-23 22:35:42 -05:00
|
|
|
value = uiprivTableModelCellValue(self->m, row, self->textModelColumn);
|
2018-06-23 19:19:30 -05:00
|
|
|
str = uiprivToNSString(uiTableValueString(value));
|
|
|
|
uiFreeTableValue(value);
|
2018-06-03 15:50:00 -05:00
|
|
|
[self->tf setStringValue:str];
|
|
|
|
|
2018-06-24 10:41:19 -05:00
|
|
|
[self->tf setEditable:uiprivTableModelCellEditable(self->m, row, self->textEditableModelColumn)];
|
2018-06-03 15:50:00 -05:00
|
|
|
|
2018-06-24 13:22:05 -05:00
|
|
|
color = [NSColor controlTextColor];
|
|
|
|
if (uiprivTableModelColorIfProvided(self->m, row, self->textParams.ColorModelColumn, &r, &g, &b, &a))
|
|
|
|
color = [NSColor colorWithSRGBRed:r green:g blue:b alpha:a];
|
2018-06-03 22:06:44 -05:00
|
|
|
[self->tf setTextColor:color];
|
2018-06-03 20:39:49 -05:00
|
|
|
// we don't own color in ether case; don't release
|
2018-06-03 15:50:00 -05:00
|
|
|
}
|
|
|
|
if (self->iv != nil) {
|
2018-06-03 16:39:02 -05:00
|
|
|
uiImage *img;
|
|
|
|
|
2018-06-23 22:35:42 -05:00
|
|
|
value = uiprivTableModelCellValue(self->m, row, self->imageModelColumn);
|
2018-06-23 19:19:30 -05:00
|
|
|
img = uiTableValueImage(value);
|
|
|
|
uiFreeTableValue(value);
|
2018-06-03 16:39:02 -05:00
|
|
|
[self->iv setImage:uiprivImageNSImage(img)];
|
2018-06-03 15:50:00 -05:00
|
|
|
}
|
|
|
|
if (self->cb != nil) {
|
2018-06-23 22:48:47 -05:00
|
|
|
value = uiprivTableModelCellValue(self->m, row, self->checkboxModelColumn);
|
2018-06-23 19:19:30 -05:00
|
|
|
if (uiTableValueInt(value) != 0)
|
2018-06-03 15:50:00 -05:00
|
|
|
[self->cb setState:NSOnState];
|
|
|
|
else
|
|
|
|
[self->cb setState:NSOffState];
|
2018-06-23 19:19:30 -05:00
|
|
|
uiFreeTableValue(value);
|
2018-06-03 13:13:32 -05:00
|
|
|
|
2018-06-24 10:41:19 -05:00
|
|
|
[self->cb setEnabled:uiprivTableModelCellEditable(self->m, row, self->checkboxEditableModelColumn)];
|
2018-06-03 15:50:00 -05:00
|
|
|
}
|
2018-06-03 13:13:32 -05:00
|
|
|
}
|
|
|
|
|
2018-06-03 15:50:00 -05:00
|
|
|
- (IBAction)uiprivOnTextFieldAction:(id)sender
|
2018-06-03 13:13:32 -05:00
|
|
|
{
|
|
|
|
NSInteger row;
|
2018-06-23 19:19:30 -05:00
|
|
|
uiTableValue *value;
|
2018-06-03 13:13:32 -05:00
|
|
|
|
|
|
|
row = [self->t->tv rowForView:self->tf];
|
2018-06-23 19:19:30 -05:00
|
|
|
value = uiNewTableValueString([[self->tf stringValue] UTF8String]);
|
2018-06-23 22:35:42 -05:00
|
|
|
uiprivTableModelSetCellValue(self->m, row, self->textModelColumn, value);
|
2018-06-23 19:19:30 -05:00
|
|
|
uiFreeTableValue(value);
|
2018-06-03 13:13:32 -05:00
|
|
|
// always refresh the value in case the model rejected it
|
2018-06-04 21:15:05 -05:00
|
|
|
// TODO document that we do this, but not for the whole row (or decide to do both, or do neither...)
|
2018-06-03 13:13:32 -05:00
|
|
|
[self uiprivUpdate:row];
|
2018-06-03 15:50:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)uiprivOnCheckboxAction:(id)sender
|
|
|
|
{
|
|
|
|
NSInteger row;
|
2018-06-23 19:19:30 -05:00
|
|
|
uiTableValue *value;
|
2018-06-03 15:50:00 -05:00
|
|
|
|
|
|
|
row = [self->t->tv rowForView:self->cb];
|
2018-06-23 19:19:30 -05:00
|
|
|
value = uiNewTableValueInt([self->cb state] != NSOffState);
|
2018-06-23 22:35:42 -05:00
|
|
|
uiprivTableModelSetCellValue(self->m, row, self->checkboxModelColumn, value);
|
2018-06-23 19:19:30 -05:00
|
|
|
uiFreeTableValue(value);
|
2018-06-03 15:50:00 -05:00
|
|
|
// always refresh the value in case the model rejected it
|
|
|
|
[self uiprivUpdate:row];
|
2018-06-03 12:28:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-03 21:37:36 -05:00
|
|
|
@interface uiprivTextImageCheckboxTableColumn : uiprivTableColumn {
|
|
|
|
struct textColumnCreateParams params;
|
|
|
|
}
|
|
|
|
- (id)initWithIdentifier:(NSString *)ident params:(struct textColumnCreateParams *)p;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation uiprivTextImageCheckboxTableColumn
|
|
|
|
|
|
|
|
- (id)initWithIdentifier:(NSString *)ident params:(struct textColumnCreateParams *)p
|
|
|
|
{
|
|
|
|
self = [super initWithIdentifier:ident];
|
|
|
|
if (self)
|
|
|
|
self->params = *p;
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
- (uiprivTableCellView *)uiprivMakeCellView
|
2018-06-03 21:37:36 -05:00
|
|
|
{
|
2018-06-03 22:06:44 -05:00
|
|
|
uiprivTableCellView *cv;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
|
|
|
cv = [[uiprivTextImageCheckboxTableCellView alloc] initWithFrame:NSZeroRect params:&(self->params)];
|
|
|
|
[cv setIdentifier:[self identifier]];
|
|
|
|
return cv;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-03 19:55:08 -05:00
|
|
|
@interface uiprivProgressBarTableCellView : uiprivTableCellView {
|
2018-06-03 17:34:29 -05:00
|
|
|
uiTable *t;
|
|
|
|
uiTableModel *m;
|
|
|
|
NSProgressIndicator *p;
|
|
|
|
int modelColumn;
|
|
|
|
}
|
|
|
|
- (id)initWithFrame:(NSRect)r table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc;
|
|
|
|
@end
|
|
|
|
|
2018-06-03 19:55:08 -05:00
|
|
|
@implementation uiprivProgressBarTableCellView
|
2018-06-03 17:34:29 -05:00
|
|
|
|
|
|
|
- (id)initWithFrame:(NSRect)r table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc
|
|
|
|
{
|
|
|
|
self = [super initWithFrame:r];
|
|
|
|
if (self) {
|
|
|
|
self->t = table;
|
|
|
|
self->m = model;
|
|
|
|
self->modelColumn = mc;
|
|
|
|
|
|
|
|
self->p = [[NSProgressIndicator alloc] initWithFrame:NSZeroRect];
|
|
|
|
[self->p setControlSize:NSRegularControlSize];
|
|
|
|
[self->p setBezeled:YES];
|
|
|
|
[self->p setStyle:NSProgressIndicatorBarStyle];
|
2018-06-04 19:09:09 -05:00
|
|
|
[self->p setTranslatesAutoresizingMaskIntoConstraints:NO];
|
|
|
|
[self addSubview:self->p];
|
|
|
|
|
|
|
|
// TODO set hugging and compression resistance properly
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeLeading,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->p, NSLayoutAttributeLeading,
|
|
|
|
1, -progressBarColumnLeading,
|
|
|
|
@"uiTable cell progressbar leading constraint")];
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeTop,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->p, NSLayoutAttributeTop,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell progressbar top constraint")];
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeTrailing,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->p, NSLayoutAttributeTrailing,
|
|
|
|
1, progressBarColumnTrailing,
|
|
|
|
@"uiTable cell progressbar trailing constraint")];
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeBottom,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->p, NSLayoutAttributeBottom,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell progressbar bottom constraint")];
|
2018-06-03 17:34:29 -05:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
[self->p release];
|
|
|
|
self->p = nil;
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)uiprivUpdate:(NSInteger)row
|
|
|
|
{
|
2018-06-23 19:19:30 -05:00
|
|
|
uiTableValue *value;
|
|
|
|
int progress;
|
2018-06-03 17:34:29 -05:00
|
|
|
|
2018-06-23 22:35:42 -05:00
|
|
|
value = uiprivTableModelCellValue(self->m, row, self->modelColumn);
|
2018-06-23 19:19:30 -05:00
|
|
|
progress = uiTableValueInt(value);
|
|
|
|
uiFreeTableValue(value);
|
|
|
|
if (progress == -1) {
|
2018-06-03 17:34:29 -05:00
|
|
|
[self->p setIndeterminate:YES];
|
|
|
|
[self->p startAnimation:self->p];
|
2018-06-23 19:19:30 -05:00
|
|
|
} else if (progress == 100) {
|
2018-06-03 17:34:29 -05:00
|
|
|
[self->p setIndeterminate:NO];
|
|
|
|
[self->p setMaxValue:101];
|
|
|
|
[self->p setDoubleValue:101];
|
|
|
|
[self->p setDoubleValue:100];
|
|
|
|
[self->p setMaxValue:100];
|
|
|
|
} else {
|
|
|
|
[self->p setIndeterminate:NO];
|
2018-06-23 19:19:30 -05:00
|
|
|
[self->p setDoubleValue:(progress + 1)];
|
|
|
|
[self->p setDoubleValue:progress];
|
2018-06-03 17:34:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-03 21:37:36 -05:00
|
|
|
@interface uiprivProgressBarTableColumn : uiprivTableColumn {
|
2018-06-03 22:06:44 -05:00
|
|
|
uiTable *t;
|
|
|
|
// TODO remove the need for this given t (or make t not require m, one of the two)
|
|
|
|
uiTableModel *m;
|
2018-06-03 21:37:36 -05:00
|
|
|
int modelColumn;
|
|
|
|
}
|
2018-06-03 22:06:44 -05:00
|
|
|
- (id)initWithIdentifier:(NSString *)ident table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc;
|
2018-06-03 21:37:36 -05:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation uiprivProgressBarTableColumn
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
- (id)initWithIdentifier:(NSString *)ident table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc
|
2018-06-03 21:37:36 -05:00
|
|
|
{
|
|
|
|
self = [super initWithIdentifier:ident];
|
2018-06-03 22:06:44 -05:00
|
|
|
if (self) {
|
|
|
|
self->t = table;
|
|
|
|
self->m = model;
|
2018-06-03 21:37:36 -05:00
|
|
|
self->modelColumn = mc;
|
2018-06-03 22:06:44 -05:00
|
|
|
}
|
2018-06-03 21:37:36 -05:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
- (uiprivTableCellView *)uiprivMakeCellView
|
2018-06-03 21:37:36 -05:00
|
|
|
{
|
2018-06-03 22:06:44 -05:00
|
|
|
uiprivTableCellView *cv;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
cv = [[uiprivProgressBarTableCellView alloc] initWithFrame:NSZeroRect table:self->t model:self->m modelColumn:self->modelColumn];
|
2018-06-03 21:37:36 -05:00
|
|
|
[cv setIdentifier:[self identifier]];
|
|
|
|
return cv;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-03 19:55:08 -05:00
|
|
|
@interface uiprivButtonTableCellView : uiprivTableCellView {
|
2018-06-03 18:21:01 -05:00
|
|
|
uiTable *t;
|
|
|
|
uiTableModel *m;
|
|
|
|
NSButton *b;
|
|
|
|
int modelColumn;
|
|
|
|
int editableColumn;
|
|
|
|
}
|
|
|
|
- (id)initWithFrame:(NSRect)r table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc editableColumn:(int)ec;
|
|
|
|
- (IBAction)uiprivOnClicked:(id)sender;
|
|
|
|
@end
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
@implementation uiprivButtonTableCellView
|
2018-06-03 18:21:01 -05:00
|
|
|
|
|
|
|
- (id)initWithFrame:(NSRect)r table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc editableColumn:(int)ec
|
|
|
|
{
|
|
|
|
self = [super initWithFrame:r];
|
|
|
|
if (self) {
|
|
|
|
self->t = table;
|
|
|
|
self->m = model;
|
|
|
|
self->modelColumn = mc;
|
|
|
|
self->editableColumn = ec;
|
|
|
|
|
|
|
|
self->b = [[NSButton alloc] initWithFrame:NSZeroRect];
|
|
|
|
[self->b setButtonType:NSMomentaryPushInButton];
|
|
|
|
[self->b setBordered:YES];
|
|
|
|
[self->b setBezelStyle:NSRoundRectBezelStyle];
|
|
|
|
uiDarwinSetControlFont(self->b, NSRegularControlSize);
|
|
|
|
[self->b setTarget:self];
|
|
|
|
[self->b setAction:@selector(uiprivOnClicked:)];
|
2018-06-04 19:09:09 -05:00
|
|
|
[self->b setTranslatesAutoresizingMaskIntoConstraints:NO];
|
|
|
|
[self addSubview:self->b];
|
|
|
|
|
|
|
|
// TODO set hugging and compression resistance properly
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeLeading,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->b, NSLayoutAttributeLeading,
|
|
|
|
1, -buttonColumnLeading,
|
|
|
|
@"uiTable cell button leading constraint")];
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeTop,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->b, NSLayoutAttributeTop,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell button top constraint")];
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeTrailing,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->b, NSLayoutAttributeTrailing,
|
|
|
|
1, buttonColumnTrailing,
|
|
|
|
@"uiTable cell button trailing constraint")];
|
|
|
|
[self addConstraint:uiprivMkConstraint(self, NSLayoutAttributeBottom,
|
|
|
|
NSLayoutRelationEqual,
|
|
|
|
self->b, NSLayoutAttributeBottom,
|
|
|
|
1, 0,
|
|
|
|
@"uiTable cell button bottom constraint")];
|
2018-06-03 18:21:01 -05:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
2018-06-03 22:06:44 -05:00
|
|
|
[self->b release];
|
|
|
|
self->b = nil;
|
2018-06-03 18:21:01 -05:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)uiprivUpdate:(NSInteger)row
|
|
|
|
{
|
2018-06-23 19:19:30 -05:00
|
|
|
uiTableValue *value;
|
2018-06-03 18:21:01 -05:00
|
|
|
NSString *str;
|
|
|
|
|
2018-06-23 22:35:42 -05:00
|
|
|
value = uiprivTableModelCellValue(self->m, row, self->modelColumn);
|
2018-06-23 19:19:30 -05:00
|
|
|
str = uiprivToNSString(uiTableValueString(value));
|
|
|
|
uiFreeTableValue(value);
|
2018-06-03 18:21:01 -05:00
|
|
|
[self->b setTitle:str];
|
|
|
|
|
2018-06-24 10:41:19 -05:00
|
|
|
[self->b setEnabled:uiprivTableModelCellEditable(self->m, row, self->editableColumn)];
|
2018-06-03 18:21:01 -05:00
|
|
|
}
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
- (IBAction)uiprivOnClicked:(id)sender
|
2018-06-03 18:21:01 -05:00
|
|
|
{
|
2018-06-04 21:14:05 -05:00
|
|
|
NSInteger row;
|
|
|
|
|
|
|
|
row = [self->t->tv rowForView:self->b];
|
2018-06-23 22:35:42 -05:00
|
|
|
uiprivTableModelSetCellValue(self->m, row, self->modelColumn, NULL);
|
2018-06-04 21:14:05 -05:00
|
|
|
// TODO document we DON'T update the cell after doing this
|
2018-06-24 13:46:24 -05:00
|
|
|
// TODO or decide what to do instead
|
2018-06-03 18:21:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-03 21:37:36 -05:00
|
|
|
@interface uiprivButtonTableColumn : uiprivTableColumn {
|
2018-06-03 22:06:44 -05:00
|
|
|
uiTable *t;
|
|
|
|
uiTableModel *m;
|
2018-06-03 21:37:36 -05:00
|
|
|
int modelColumn;
|
|
|
|
int editableColumn;
|
|
|
|
}
|
2018-06-03 22:06:44 -05:00
|
|
|
- (id)initWithIdentifier:(NSString *)ident table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc editableColumn:(int)ec;
|
2018-06-03 21:37:36 -05:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation uiprivButtonTableColumn
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
- (id)initWithIdentifier:(NSString *)ident table:(uiTable *)table model:(uiTableModel *)model modelColumn:(int)mc editableColumn:(int)ec
|
2018-06-03 21:37:36 -05:00
|
|
|
{
|
|
|
|
self = [super initWithIdentifier:ident];
|
|
|
|
if (self) {
|
2018-06-03 22:06:44 -05:00
|
|
|
self->t = table;
|
|
|
|
self->m = model;
|
2018-06-03 21:37:36 -05:00
|
|
|
self->modelColumn = mc;
|
|
|
|
self->editableColumn = ec;
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
- (uiprivTableCellView *)uiprivMakeCellView
|
2018-06-03 21:37:36 -05:00
|
|
|
{
|
2018-06-03 22:06:44 -05:00
|
|
|
uiprivTableCellView *cv;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
2018-06-03 22:06:44 -05:00
|
|
|
cv = [[uiprivButtonTableCellView alloc] initWithFrame:NSZeroRect table:self->t model:self->m modelColumn:self->modelColumn editableColumn:self->editableColumn];
|
2018-06-03 21:37:36 -05:00
|
|
|
[cv setIdentifier:[self identifier]];
|
|
|
|
return cv;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2018-06-24 08:52:01 -05:00
|
|
|
void uiTableAppendTextColumn(uiTable *t, const char *name, int textModelColumn, int textEditableModelColumn, uiTableTextColumnOptionalParams *textParams)
|
2018-06-03 21:37:36 -05:00
|
|
|
{
|
|
|
|
struct textColumnCreateParams p;
|
|
|
|
uiprivTableColumn *col;
|
|
|
|
NSString *str;
|
|
|
|
|
|
|
|
memset(&p, 0, sizeof (struct textColumnCreateParams));
|
|
|
|
p.t = t;
|
|
|
|
p.m = t->m;
|
|
|
|
|
|
|
|
p.makeTextField = YES;
|
|
|
|
p.textModelColumn = textModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
p.textEditableModelColumn = textEditableModelColumn;
|
|
|
|
if (textParams != NULL)
|
|
|
|
p.textParams = *textParams;
|
2018-06-23 23:45:54 -05:00
|
|
|
else
|
|
|
|
p.textParams = uiprivDefaultTextColumnOptionalParams;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
|
|
|
str = [NSString stringWithUTF8String:name];
|
2018-06-03 22:06:44 -05:00
|
|
|
col = [[uiprivTextImageCheckboxTableColumn alloc] initWithIdentifier:str params:&p];
|
2018-06-03 21:37:36 -05:00
|
|
|
[col setTitle:str];
|
2018-06-03 22:06:44 -05:00
|
|
|
[t->tv addTableColumn:col];
|
2018-06-03 21:37:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void uiTableAppendImageColumn(uiTable *t, const char *name, int imageModelColumn)
|
|
|
|
{
|
|
|
|
struct textColumnCreateParams p;
|
|
|
|
uiprivTableColumn *col;
|
|
|
|
NSString *str;
|
|
|
|
|
|
|
|
memset(&p, 0, sizeof (struct textColumnCreateParams));
|
|
|
|
p.t = t;
|
|
|
|
p.m = t->m;
|
|
|
|
|
2018-06-24 13:46:24 -05:00
|
|
|
p.makeImageView = YES;
|
2018-06-03 21:37:36 -05:00
|
|
|
p.imageModelColumn = imageModelColumn;
|
|
|
|
|
|
|
|
str = [NSString stringWithUTF8String:name];
|
2018-06-03 22:06:44 -05:00
|
|
|
col = [[uiprivTextImageCheckboxTableColumn alloc] initWithIdentifier:str params:&p];
|
2018-06-03 21:37:36 -05:00
|
|
|
[col setTitle:str];
|
2018-06-03 22:06:44 -05:00
|
|
|
[t->tv addTableColumn:col];
|
2018-06-03 21:37:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void uiTableAppendImageTextColumn(uiTable *t, const char *name, int imageModelColumn, int textModelColumn, int textEditableModelColumn, uiTableTextColumnOptionalParams *textParams)
|
|
|
|
{
|
|
|
|
struct textColumnCreateParams p;
|
|
|
|
uiprivTableColumn *col;
|
|
|
|
NSString *str;
|
|
|
|
|
|
|
|
memset(&p, 0, sizeof (struct textColumnCreateParams));
|
|
|
|
p.t = t;
|
|
|
|
p.m = t->m;
|
|
|
|
|
|
|
|
p.makeTextField = YES;
|
|
|
|
p.textModelColumn = textModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
p.textEditableModelColumn = textEditableModelColumn;
|
2018-06-23 23:45:54 -05:00
|
|
|
if (textParams != NULL)
|
|
|
|
p.textParams = *textParams;
|
|
|
|
else
|
|
|
|
p.textParams = uiprivDefaultTextColumnOptionalParams;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
2018-06-24 13:46:24 -05:00
|
|
|
p.makeImageView = YES;
|
2018-06-03 21:37:36 -05:00
|
|
|
p.imageModelColumn = imageModelColumn;
|
|
|
|
|
|
|
|
str = [NSString stringWithUTF8String:name];
|
2018-06-03 22:06:44 -05:00
|
|
|
col = [[uiprivTextImageCheckboxTableColumn alloc] initWithIdentifier:str params:&p];
|
2018-06-03 21:37:36 -05:00
|
|
|
[col setTitle:str];
|
2018-06-03 22:06:44 -05:00
|
|
|
[t->tv addTableColumn:col];
|
2018-06-03 21:37:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void uiTableAppendCheckboxColumn(uiTable *t, const char *name, int checkboxModelColumn, int checkboxEditableModelColumn)
|
|
|
|
{
|
|
|
|
struct textColumnCreateParams p;
|
|
|
|
uiprivTableColumn *col;
|
|
|
|
NSString *str;
|
|
|
|
|
|
|
|
memset(&p, 0, sizeof (struct textColumnCreateParams));
|
|
|
|
p.t = t;
|
|
|
|
p.m = t->m;
|
|
|
|
|
|
|
|
p.makeCheckbox = YES;
|
|
|
|
p.checkboxModelColumn = checkboxModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
p.checkboxEditableModelColumn = checkboxEditableModelColumn;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
|
|
|
str = [NSString stringWithUTF8String:name];
|
2018-06-03 22:06:44 -05:00
|
|
|
col = [[uiprivTextImageCheckboxTableColumn alloc] initWithIdentifier:str params:&p];
|
2018-06-03 21:37:36 -05:00
|
|
|
[col setTitle:str];
|
2018-06-03 22:06:44 -05:00
|
|
|
[t->tv addTableColumn:col];
|
2018-06-03 21:37:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void uiTableAppendCheckboxTextColumn(uiTable *t, const char *name, int checkboxModelColumn, int checkboxEditableModelColumn, int textModelColumn, int textEditableModelColumn, uiTableTextColumnOptionalParams *textParams)
|
|
|
|
{
|
|
|
|
struct textColumnCreateParams p;
|
|
|
|
uiprivTableColumn *col;
|
|
|
|
NSString *str;
|
|
|
|
|
|
|
|
memset(&p, 0, sizeof (struct textColumnCreateParams));
|
|
|
|
p.t = t;
|
|
|
|
p.m = t->m;
|
|
|
|
|
|
|
|
p.makeTextField = YES;
|
|
|
|
p.textModelColumn = textModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
p.textEditableModelColumn = textEditableModelColumn;
|
2018-06-23 23:45:54 -05:00
|
|
|
if (textParams != NULL)
|
|
|
|
p.textParams = *textParams;
|
|
|
|
else
|
|
|
|
p.textParams = uiprivDefaultTextColumnOptionalParams;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
|
|
|
p.makeCheckbox = YES;
|
|
|
|
p.checkboxModelColumn = checkboxModelColumn;
|
2018-06-24 08:52:01 -05:00
|
|
|
p.checkboxEditableModelColumn = checkboxEditableModelColumn;
|
2018-06-03 21:37:36 -05:00
|
|
|
|
|
|
|
str = [NSString stringWithUTF8String:name];
|
2018-06-03 22:06:44 -05:00
|
|
|
col = [[uiprivTextImageCheckboxTableColumn alloc] initWithIdentifier:str params:&p];
|
2018-06-03 21:37:36 -05:00
|
|
|
[col setTitle:str];
|
2018-06-03 22:06:44 -05:00
|
|
|
[t->tv addTableColumn:col];
|
2018-06-03 21:37:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void uiTableAppendProgressBarColumn(uiTable *t, const char *name, int progressModelColumn)
|
|
|
|
{
|
|
|
|
uiprivTableColumn *col;
|
|
|
|
NSString *str;
|
|
|
|
|
|
|
|
str = [NSString stringWithUTF8String:name];
|
2018-06-03 22:06:44 -05:00
|
|
|
col = [[uiprivProgressBarTableColumn alloc] initWithIdentifier:str table:t model:t->m modelColumn:progressModelColumn];
|
2018-06-03 21:37:36 -05:00
|
|
|
[col setTitle:str];
|
2018-06-03 22:06:44 -05:00
|
|
|
[t->tv addTableColumn:col];
|
2018-06-03 21:37:36 -05:00
|
|
|
}
|
|
|
|
|
2018-06-24 08:52:01 -05:00
|
|
|
void uiTableAppendButtonColumn(uiTable *t, const char *name, int buttonModelColumn, int buttonClickableModelColumn)
|
2018-06-03 21:37:36 -05:00
|
|
|
{
|
|
|
|
uiprivTableColumn *col;
|
|
|
|
NSString *str;
|
|
|
|
|
|
|
|
str = [NSString stringWithUTF8String:name];
|
2018-06-24 08:52:01 -05:00
|
|
|
col = [[uiprivButtonTableColumn alloc] initWithIdentifier:str table:t model:t->m modelColumn:buttonModelColumn editableColumn:buttonClickableModelColumn];
|
2018-06-03 21:37:36 -05:00
|
|
|
[col setTitle:str];
|
2018-06-03 22:06:44 -05:00
|
|
|
[t->tv addTableColumn:col];
|
2018-06-03 21:37:36 -05:00
|
|
|
}
|