📄 osxctrls.m
字号:
assert(c && c->ctrl->generic.type == CTRL_CHECKBOX);
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_VALCHANGE);
}
- (void)radioChanged:(id)sender
{
struct fe_ctrl *c = find_widget(d, sender);
int j;
assert(c && c->radiobuttons);
for (j = 0; j < c->nradiobuttons; j++)
if (sender != c->radiobuttons[j])
[c->radiobuttons[j] setState:NSOffState];
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_VALCHANGE);
}
- (void)popupMenuSelected:(id)sender
{
struct fe_ctrl *c = find_widget(d, sender);
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_VALCHANGE);
}
- (void)controlTextDidChange:(NSNotification *)notification
{
id widget = [notification object];
struct fe_ctrl *c = find_widget(d, widget);
assert(c && c->ctrl->generic.type == CTRL_EDITBOX);
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_VALCHANGE);
}
- (void)controlTextDidEndEditing:(NSNotification *)notification
{
id widget = [notification object];
struct fe_ctrl *c = find_widget(d, widget);
assert(c && c->ctrl->generic.type == CTRL_EDITBOX);
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_REFRESH);
}
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
id widget = [notification object];
struct fe_ctrl *c = find_widget(d, widget);
assert(c && c->ctrl->generic.type == CTRL_LISTBOX);
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_SELCHANGE);
}
- (BOOL)tableView:(NSTableView *)aTableView
shouldEditTableColumn:(NSTableColumn *)aTableColumn
row:(int)rowIndex
{
return NO; /* no editing permitted */
}
- (void)listDoubleClicked:(id)sender
{
struct fe_ctrl *c = find_widget(d, sender);
assert(c && c->ctrl->generic.type == CTRL_LISTBOX);
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_ACTION);
}
- (void)dragListButton:(id)sender
{
struct fe_ctrl *c = find_widget(d, sender);
int direction, row, nrows;
assert(c && c->ctrl->generic.type == CTRL_LISTBOX &&
c->ctrl->listbox.draglist);
if (sender == c->button)
direction = -1; /* up */
else
direction = +1; /* down */
row = [c->tableview selectedRow];
nrows = [c->tableview numberOfRows];
if (row + direction < 0 || row + direction >= nrows) {
NSBeep();
return;
}
[[c->tableview dataSource] swap:row with:row+direction];
[c->tableview reloadData];
[c->tableview selectRow:row+direction byExtendingSelection:NO];
c->ctrl->generic.handler(c->ctrl, d, d->data, EVENT_VALCHANGE);
}
@end
void create_ctrls(void *dv, NSView *parent, struct controlset *s,
int *minw, int *minh)
{
struct fe_dlg *d = (struct fe_dlg *)dv;
int ccw[100]; /* cumulative column widths */
int cypos[100];
int ncols;
int wmin = 0, hmin = 0;
int i, j, cw, ch;
NSRect rect;
NSFont *textviewfont = nil;
int boxh = 0, boxw = 0;
if (!s->boxname && s->boxtitle) {
/* This controlset is a panel title. */
NSTextField *tf;
tf = [[NSTextField alloc] initWithFrame:NSMakeRect(0,0,1,1)];
[tf setEditable:NO];
[tf setSelectable:NO];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
[tf setStringValue:[NSString stringWithCString:s->boxtitle]];
[tf sizeToFit];
rect = [tf frame];
[parent addSubview:tf];
/*
* I'm going to store this NSTextField in the boxes tree,
* because I really can't face having a special tree234
* mapping controlsets to panel titles.
*/
add_box(d, s, tf);
*minw = rect.size.width;
*minh = rect.size.height;
return;
}
if (*s->boxname) {
/*
* Create an NSBox to contain this subset of controls.
*/
NSBox *box;
NSRect tmprect;
box = [[NSBox alloc] initWithFrame:NSMakeRect(0,0,1,1)];
if (s->boxtitle)
[box setTitle:[NSString stringWithCString:s->boxtitle]];
else
[box setTitlePosition:NSNoTitle];
add_box(d, s, box);
tmprect = [box frame];
[box setContentViewMargins:NSMakeSize(20,20)];
[box setFrameFromContentFrame:NSMakeRect(100,100,100,100)];
rect = [box frame];
[box setFrame:tmprect];
boxh = (int)(rect.size.height - 100);
boxw = (int)(rect.size.width - 100);
[parent addSubview:box];
if (s->boxtitle)
boxh += [[box titleFont] pointSize];
/*
* All subsequent controls will be placed within this box.
*/
parent = box;
}
ncols = 1;
ccw[0] = 0;
ccw[1] = 100;
cypos[0] = 0;
/*
* Now iterate through the controls themselves, create them,
* and add their width and height to the overall width/height
* calculation.
*/
for (i = 0; i < s->ncontrols; i++) {
union control *ctrl = s->ctrls[i];
struct fe_ctrl *c;
int colstart = COLUMN_START(ctrl->generic.column);
int colspan = COLUMN_SPAN(ctrl->generic.column);
int colend = colstart + colspan;
int ytop, wthis;
switch (ctrl->generic.type) {
case CTRL_COLUMNS:
for (j = 1; j < ncols; j++)
if (cypos[0] < cypos[j])
cypos[0] = cypos[j];
assert(ctrl->columns.ncols < lenof(ccw));
ccw[0] = 0;
for (j = 0; j < ctrl->columns.ncols; j++) {
ccw[j+1] = ccw[j] + (ctrl->columns.percentages ?
ctrl->columns.percentages[j] : 100);
cypos[j] = cypos[0];
}
ncols = ctrl->columns.ncols;
continue; /* no actual control created */
case CTRL_TABDELAY:
/*
* I'm currently uncertain that we can implement tab
* order in OS X.
*/
continue; /* no actual control created */
}
c = fe_ctrl_new(ctrl);
add234(d->byctrl, c);
cw = ch = 0;
switch (ctrl->generic.type) {
case CTRL_BUTTON:
case CTRL_CHECKBOX:
{
NSButton *b;
b = [[MyButton alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)];
[b setBezelStyle:NSRoundedBezelStyle];
if (ctrl->generic.type == CTRL_CHECKBOX)
[b setButtonType:NSSwitchButton];
[b setTitle:[NSString stringWithCString:ctrl->generic.label]];
if (ctrl->button.isdefault)
[b setKeyEquivalent:@"\r"];
else if (ctrl->button.iscancel)
[b setKeyEquivalent:@"\033"];
[b sizeToFit];
rect = [b frame];
[parent addSubview:b];
[b setTarget:d->rec];
if (ctrl->generic.type == CTRL_CHECKBOX)
[b setAction:@selector(checkboxChanged:)];
else
[b setAction:@selector(buttonPushed:)];
add_widget(d, c, b);
c->button = b;
cw = rect.size.width;
ch = rect.size.height;
}
break;
case CTRL_EDITBOX:
{
int editp = ctrl->editbox.percentwidth;
int labelp = editp == 100 ? 100 : 100 - editp;
NSTextField *tf;
NSComboBox *cb;
tf = [[NSTextField alloc] initWithFrame:NSMakeRect(0,0,1,1)];
[tf setEditable:NO];
[tf setSelectable:NO];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
[tf setStringValue:[NSString
stringWithCString:ctrl->generic.label]];
[tf sizeToFit];
rect = [tf frame];
[parent addSubview:tf];
c->label = tf;
cw = rect.size.width * 100 / labelp;
ch = rect.size.height;
if (ctrl->editbox.has_list) {
cb = [[NSComboBox alloc]
initWithFrame:NSMakeRect(0,0,1,1)];
[cb setStringValue:@"x"];
[cb sizeToFit];
rect = [cb frame];
[parent addSubview:cb];
c->combobox = cb;
} else {
if (ctrl->editbox.password)
tf = [NSSecureTextField alloc];
else
tf = [NSTextField alloc];
tf = [tf initWithFrame:NSMakeRect(0,0,1,1)];
[tf setEditable:YES];
[tf setSelectable:YES];
[tf setBordered:YES];
[tf setStringValue:@"x"];
[tf sizeToFit];
rect = [tf frame];
[parent addSubview:tf];
c->editbox = tf;
[tf setDelegate:d->rec];
add_widget(d, c, tf);
}
if (editp == 100) {
/* the edit box and its label are vertically separated */
ch += VSPACING + rect.size.height;
} else {
/* the edit box and its label are horizontally separated */
if (ch < rect.size.height)
ch = rect.size.height;
}
if (cw < rect.size.width * 100 / editp)
cw = rect.size.width * 100 / editp;
}
break;
case CTRL_TEXT:
{
NSTextView *tv;
int testwid;
if (!textviewfont) {
NSTextField *tf;
tf = [[NSTextField alloc] init];
textviewfont = [tf font];
[tf release];
}
testwid = (ccw[colend] - ccw[colstart]) * 3;
tv = [[NSTextView alloc]
initWithFrame:NSMakeRect(0,0,testwid,1)];
[tv setEditable:NO];
[tv setSelectable:NO];
//[tv setBordered:NO];
[tv setDrawsBackground:NO];
[tv setFont:textviewfont];
[tv setString:
[NSString stringWithCString:ctrl->generic.label]];
rect = [tv frame];
[tv sizeToFit];
[parent addSubview:tv];
c->textview = tv;
cw = rect.size.width;
ch = rect.size.height;
}
break;
case CTRL_RADIO:
{
NSTextField *tf;
int j;
if (ctrl->generic.label) {
tf = [[NSTextField alloc]
initWithFrame:NSMakeRect(0,0,1,1)];
[tf setEditable:NO];
[tf setSelectable:NO];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
[tf setStringValue:
[NSString stringWithCString:ctrl->generic.label]];
[tf sizeToFit];
rect = [tf frame];
[parent addSubview:tf];
c->label = tf;
cw = rect.size.width;
ch = rect.size.height;
} else {
cw = 0;
ch = -VSPACING; /* compensate for next advance */
}
c->nradiobuttons = ctrl->radio.nbuttons;
c->radiobuttons = snewn(ctrl->radio.nbuttons, NSButton *);
for (j = 0; j < ctrl->radio.nbuttons; j++) {
NSButton *b;
int ncols;
b = [[MyButton alloc] initWithFrame:NSMakeRect(0,0,1,1)];
[b setBezelStyle:NSRoundedBezelStyle];
[b setButtonType:NSRadioButton];
[b setTitle:[NSString
stringWithCString:ctrl->radio.buttons[j]]];
[b sizeToFit];
rect = [b frame];
[parent addSubview:b];
c->radiobuttons[j] = b;
[b setTarget:d->rec];
[b setAction:@selector(radioChanged:)];
add_widget(d, c, b);
/*
* Add to the height every time we place a
* button in column 0.
*/
if (j % ctrl->radio.ncolumns == 0) {
ch += rect.size.height + VSPACING;
}
/*
* Add to the width by working out how many
* columns this button spans.
*/
if (j == ctrl->radio.nbuttons - 1)
ncols = (ctrl->radio.ncolumns -
(j % ctrl->radio.ncolumns));
else
ncols = 1;
if (cw < rect.size.width * ctrl->radio.ncolumns / ncols)
cw = rect.size.width * ctrl->radio.ncolumns / ncols;
}
}
break;
case CTRL_FILESELECT:
case CTRL_FONTSELECT:
{
NSTextField *tf;
NSButton *b;
int kh;
tf = [[NSTextField alloc] initWithFrame:NSMakeRect(0,0,1,1)];
[tf setEditable:NO];
[tf setSelectable:NO];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
[tf setStringValue:[NSString
stringWithCString:ctrl->generic.label]];
[tf sizeToFit];
rect = [tf frame];
[parent addSubview:tf];
c->label = tf;
cw = rect.size.width;
ch = rect.size.height;
tf = [NSTextField alloc];
tf = [tf initWithFrame:NSMakeRect(0,0,1,1)];
if (ctrl->generic.type == CTRL_FILESELECT) {
[tf setEditable:YES];
[tf setSelectable:YES];
[tf setBordered:YES];
} else {
[tf setEditable:NO];
[tf setSelectable:NO];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
}
[tf setStringValue:@"x"];
[tf sizeToFit];
rect = [tf frame];
[parent addSubview:tf];
c->editbox = tf;
kh = rect.size.height;
if (cw < rect.size.width * 4 / 3)
cw = rect.size.width * 4 / 3;
b = [[MyButton alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)];
[b setBezelStyle:NSRoundedBezelStyle];
if (ctrl->generic.type == CTRL_FILESELECT)
[b setTitle:@"Browse..."];
else
[b setTitle:@"Change..."];
// [b setKeyEquivalent:somethingorother];
// [b setTarget:somethingorother];
// [b setAction:somethingorother];
[b sizeToFit];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -