comparison mac/dw.m @ 1410:c607fd86e5c2

Initial code on the Mac to automatically calculate widget required sizes. OS/2 and Windows code coming soon.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 01 Dec 2011 21:37:03 +0000
parents ccd383e11ff8
children 22ba64e357de
comparison
equal deleted inserted replaced
1409:93eb987c05cf 1410:c607fd86e5c2
3506 range = [view bounds].size.width; 3506 range = [view bounds].size.width;
3507 } 3507 }
3508 return range; 3508 return range;
3509 } 3509 }
3510 3510
3511 /* Internal function to calculate the widget's required size..
3512 * These are the general rules for widget sizes:
3513 *
3514 * Scrolled(Container,Tree,MLE)/Render/Unspecified: 1x1
3515 * Entryfield/Combobox/Spinbutton: 150x(maxfontheight)
3516 * Spinbutton: 50x(maxfontheight)
3517 * Text/Status: (textwidth)x(textheight)
3518 */
3519 void _control_size(id handle, int *width, int *height)
3520 {
3521 int thiswidth = 1, thisheight = 1, extrawidth = 0, extraheight = 0;
3522 NSString *nsstr = nil;
3523 id object = handle;
3524
3525 if([object isMemberOfClass:[ DWSpinButton class]])
3526 object = [object textfield];
3527 /* Handle all the different button types */
3528 if([ object isKindOfClass:[ NSButton class ] ])
3529 {
3530 nsstr = [object title];
3531
3532 switch([object buttonType])
3533 {
3534 case NSSwitchButton:
3535 case NSRadioButton:
3536 extrawidth = 24;
3537 extraheight = 4;
3538 break;
3539 default:
3540 if([object isBordered])
3541 {
3542 extrawidth = 30;
3543 extraheight = 8;
3544 }
3545 else
3546 {
3547 extrawidth = 8;
3548 extraheight = 4;
3549 }
3550 break;
3551 }
3552 }
3553 /* If the control is an entryfield set width to 150 */
3554 else if([object isKindOfClass:[ NSTextField class ]] && [object isEditable])
3555 {
3556 NSFont *font = [object font];
3557 /* Spinbuttons don't need to be as wide */
3558 if([object isMemberOfClass:[ DWSpinButton class]])
3559 thiswidth = 50;
3560 else
3561 thiswidth = 150;
3562 if(font)
3563 thisheight = (int)[font boundingRectForFont].size.height;
3564 /* Spinbuttons don't need to be as wide */
3565 if([object isMemberOfClass:[ DWComboBox class]])
3566 extraheight = 4;
3567 }
3568 else if([ object isKindOfClass:[ NSControl class ] ])
3569 nsstr = [object stringValue];
3570
3571 if([object isKindOfClass:[ NSTextField class ]] && ![object isEditable])
3572 extrawidth = 8;
3573
3574 /* If we have a string...
3575 * calculate the size with the current font.
3576 */
3577 if(nsstr && [nsstr length])
3578 dw_font_text_extents_get(object, NULL, (char *)[nsstr UTF8String], &thiswidth, &thisheight);
3579
3580 NSLog(@"Class %@ Width %d Height %d Extra Width %d Extra Height %d\n", [object className], thiswidth, thisheight, extrawidth, extraheight);
3581 /* Set the requested sizes */
3582 if(width)
3583 *width = thiswidth + extrawidth;
3584 if(height)
3585 *height = thisheight + extraheight;
3586 }
3587
3511 /* Internal box packing function called by the other 3 functions */ 3588 /* Internal box packing function called by the other 3 functions */
3512 void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname) 3589 void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname)
3513 { 3590 {
3514 int _locked_by_me = FALSE; 3591 int _locked_by_me = FALSE;
3515 DW_MUTEX_LOCK; 3592 DW_MUTEX_LOCK;
3596 3673
3597 tmpitem[index].hwnd = item; 3674 tmpitem[index].hwnd = item;
3598 tmpitem[index].origwidth = tmpitem[index].width = width; 3675 tmpitem[index].origwidth = tmpitem[index].width = width;
3599 tmpitem[index].origheight = tmpitem[index].height = height; 3676 tmpitem[index].origheight = tmpitem[index].height = height;
3600 tmpitem[index].pad = pad; 3677 tmpitem[index].pad = pad;
3601 if(hsize) 3678 tmpitem[index].hsize = hsize ? SIZEEXPAND : SIZESTATIC;
3602 tmpitem[index].hsize = SIZEEXPAND; 3679 tmpitem[index].vsize = vsize ? SIZEEXPAND : SIZESTATIC;
3603 else 3680
3604 tmpitem[index].hsize = SIZESTATIC; 3681 /* If either of the parameters are -1 ... calculate the size */
3605 3682 if(width == -1 || height == -1)
3606 if(vsize) 3683 _control_size(object, width == -1 ? &tmpitem[index].width : NULL, height == -1 ? &tmpitem[index].height : NULL);
3607 tmpitem[index].vsize = SIZEEXPAND;
3608 else
3609 tmpitem[index].vsize = SIZESTATIC;
3610 3684
3611 thisbox->items = tmpitem; 3685 thisbox->items = tmpitem;
3612 3686
3613 /* Update the item count */ 3687 /* Update the item count */
3614 thisbox->count++; 3688 thisbox->count++;
7755 DWButton *button = handle; 7829 DWButton *button = handle;
7756 7830
7757 if(mask & DW_BS_NOBORDER) 7831 if(mask & DW_BS_NOBORDER)
7758 { 7832 {
7759 if(style & DW_BS_NOBORDER) 7833 if(style & DW_BS_NOBORDER)
7760 {
7761 [button setButtonType:NSMomentaryLight];
7762 [button setBordered:NO]; 7834 [button setBordered:NO];
7763 }
7764 else 7835 else
7765 {
7766 [button setButtonType:NSMomentaryPushInButton];
7767 [button setBordered:YES]; 7836 [button setBordered:YES];
7768 }
7769 } 7837 }
7770 } 7838 }
7771 else if([object isMemberOfClass:[DWMenuItem class]]) 7839 else if([object isMemberOfClass:[DWMenuItem class]])
7772 { 7840 {
7773 if(mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED)) 7841 if(mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED))
7949 return strdup([output UTF8String]); 8017 return strdup([output UTF8String]);
7950 } 8018 }
7951 return NULL; 8019 return NULL;
7952 } 8020 }
7953 8021
8022 /* Internal function to return a pointer to an item struct
8023 * with information about the packing information regarding object.
8024 */
8025 Item *_box_item(id object)
8026 {
8027 /* Find the item within the box it is packed into */
8028 if([object isKindOfClass:[DWBox class]] || [object isKindOfClass:[DWGroupBox class]] || [object isKindOfClass:[NSControl class]])
8029 {
8030 DWBox *parent = (DWBox *)[object superview];
8031
8032 /* Some controls are embedded in scrollviews...
8033 * so get the parent of the scrollview in that case.
8034 */
8035 if([object isKindOfClass:[NSTableView class]] && [parent isMemberOfClass:[NSClipView class]])
8036 {
8037 object = [parent superview];
8038 parent = (DWBox *)[object superview];
8039 }
8040
8041 if([parent isKindOfClass:[DWBox class]] || [parent isKindOfClass:[DWGroupBox class]])
8042 {
8043 Box *thisbox = [parent box];
8044 Item *thisitem = thisbox->items;
8045 int z;
8046
8047 for(z=0;z<thisbox->count;z++)
8048 {
8049 if(thisitem[z].hwnd == object)
8050 return &thisitem[z];
8051 }
8052 }
8053 }
8054 return NULL;
8055 }
8056
7954 /* 8057 /*
7955 * Sets the font used by a specified window (widget) handle. 8058 * Sets the font used by a specified window (widget) handle.
7956 * Parameters: 8059 * Parameters:
7957 * handle: The window (widget) handle. 8060 * handle: The window (widget) handle.
7958 * fontname: Name and size of the font in the form "size.fontname" 8061 * fontname: Name and size of the font in the form "size.fontname"
7983 { 8086 {
7984 DWRender *render = object; 8087 DWRender *render = object;
7985 8088
7986 [render setFont:font]; 8089 [render setFont:font];
7987 } 8090 }
7988 } 8091 else
7989 return 0; 8092 return DW_ERROR_UNKNOWN;
8093 /* If we changed the text... */
8094 Item *item = _box_item(handle);
8095
8096 /* Check to see if any of the sizes need to be recalculated */
8097 if(item && (item->origwidth == -1 || item->origheight == -1))
8098 _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL);
8099 return DW_ERROR_NONE;
8100 }
8101 return DW_ERROR_UNKNOWN;
7990 } 8102 }
7991 8103
7992 /* 8104 /*
7993 * Returns the current font for the specified window 8105 * Returns the current font for the specified window
7994 * Parameters: 8106 * Parameters:
8134 * handle: Handle to the window. 8246 * handle: Handle to the window.
8135 * text: The text associsated with a given window. 8247 * text: The text associsated with a given window.
8136 */ 8248 */
8137 void API dw_window_set_text(HWND handle, char *text) 8249 void API dw_window_set_text(HWND handle, char *text)
8138 { 8250 {
8139 int _locked_by_me = FALSE; 8251 id object = handle;
8140 DW_MUTEX_LOCK;
8141 NSObject *object = handle;
8142 8252
8143 if([object isMemberOfClass:[ DWSpinButton class]]) 8253 if([object isMemberOfClass:[ DWSpinButton class]])
8144 { 8254 {
8145 DWSpinButton *spinbutton = handle; 8255 DWSpinButton *spinbutton = handle;
8146 handle = object = [spinbutton textfield]; 8256 object = [spinbutton textfield];
8147 } 8257 }
8148 if([ object isKindOfClass:[ NSWindow class ] ] || [ object isKindOfClass:[ NSButton class ] ]) 8258 if([ object isKindOfClass:[ NSWindow class ] ] || [ object isKindOfClass:[ NSButton class ] ])
8149 { 8259 [object setTitle:[ NSString stringWithUTF8String:text ]];
8150 id window = handle;
8151 [window setTitle:[ NSString stringWithUTF8String:text ]];
8152 }
8153 else if([ object isKindOfClass:[ NSControl class ] ]) 8260 else if([ object isKindOfClass:[ NSControl class ] ])
8154 { 8261 {
8155 NSControl *control = handle; 8262 NSControl *control = handle;
8156 [control setStringValue:[ NSString stringWithUTF8String:text ]]; 8263 [control setStringValue:[ NSString stringWithUTF8String:text ]];
8157 } 8264 }
8158 else if([object isMemberOfClass:[DWGroupBox class]]) 8265 else if([object isMemberOfClass:[DWGroupBox class]])
8159 { 8266 {
8160 DWGroupBox *groupbox = handle; 8267 DWGroupBox *groupbox = handle;
8161 [groupbox setTitle:[NSString stringWithUTF8String:text]]; 8268 [groupbox setTitle:[NSString stringWithUTF8String:text]];
8162 } 8269 }
8163 DW_MUTEX_UNLOCK; 8270 else
8271 return;
8272 /* If we changed the text... */
8273 Item *item = _box_item(handle);
8274
8275 /* Check to see if any of the sizes need to be recalculated */
8276 if(item && (item->origwidth == -1 || item->origheight == -1))
8277 _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL);
8164 } 8278 }
8165 8279
8166 /* 8280 /*
8167 * Sets the text used for a given window's floating bubble help. 8281 * Sets the text used for a given window's floating bubble help.
8168 * Parameters: 8282 * Parameters: