comparison mac/dw.m @ 949:451c71b7fdb1

Changed dw_window_capture() an dw_window_release() because the mouseDragged method does this already. Filter out mouseMoved() events for hits on non-render controls to reduce lag.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 01 May 2011 01:10:44 +0000
parents e48384ca49b7
children 73ff2daed8ca
comparison
equal deleted inserted replaced
948:e48384ca49b7 949:451c71b7fdb1
422 DWTimerHandler *DWHandler; 422 DWTimerHandler *DWHandler;
423 #if !defined(GARBAGE_COLLECT) 423 #if !defined(GARBAGE_COLLECT)
424 NSAutoreleasePool *pool; 424 NSAutoreleasePool *pool;
425 #endif 425 #endif
426 HWND _DWLastDrawable; 426 HWND _DWLastDrawable;
427 id _DWCapture;
428 HMTX DWRunMutex; 427 HMTX DWRunMutex;
429 HMTX DWThreadMutex; 428 HMTX DWThreadMutex;
430 HMTX DWThreadMutex2; 429 HMTX DWThreadMutex2;
431 DWTID DWThread = (DWTID)-1; 430 DWTID DWThread = (DWTID)-1;
432 DWTID _dw_mutex_locked = (DWTID)-1; 431 DWTID _dw_mutex_locked = (DWTID)-1;
685 @end 684 @end
686 685
687 @implementation DWWindow 686 @implementation DWWindow
688 -(void)sendEvent:(NSEvent *)theEvent { if([theEvent type] == NSKeyDown) { _event_handler(self, theEvent, 2); } [super sendEvent:theEvent]; } 687 -(void)sendEvent:(NSEvent *)theEvent { if([theEvent type] == NSKeyDown) { _event_handler(self, theEvent, 2); } [super sendEvent:theEvent]; }
689 -(void)keyDown:(NSEvent *)theEvent { } 688 -(void)keyDown:(NSEvent *)theEvent { }
690 -(void)mouseDragged:(NSEvent *)theEvent { if(_DWCapture == self) { _event_handler(self, theEvent, 5); } } 689 -(void)mouseDragged:(NSEvent *)theEvent { _event_handler(self, theEvent, 5); }
691 @end
692
693 /* Subclass for a top-level window */
694 @interface DWView : DWBox
695 #ifdef BUILDING_FOR_SNOW_LEOPARD
696 <NSWindowDelegate>
697 #endif
698 {
699 NSMenu *windowmenu;
700 NSSize oldsize;
701 }
702 -(BOOL)windowShouldClose:(id)sender;
703 -(void)setMenu:(NSMenu *)input;
704 -(void)windowDidBecomeMain:(id)sender;
705 -(void)menuHandler:(id)sender;
706 -(void)mouseDragged:(NSEvent *)theEvent;
707 @end
708
709 @implementation DWView
710 -(BOOL)windowShouldClose:(id)sender
711 {
712 if(_event_handler(sender, nil, 6) == FALSE)
713 return YES;
714 return NO;
715 }
716 - (void)viewDidMoveToWindow
717 {
718 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:NSWindowDidResizeNotification object:[self window]];
719 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeMain:) name:NSWindowDidBecomeMainNotification object:[self window]];
720 }
721 - (void)dealloc
722 {
723 if(windowmenu)
724 {
725 [windowmenu release];
726 }
727 [[NSNotificationCenter defaultCenter] removeObserver:self];
728 [super dealloc];
729 }
730 - (void)windowResized:(NSNotification *)notification;
731 {
732 NSSize size = [self frame].size;
733
734 if(oldsize.width != size.width || oldsize.height != size.height)
735 {
736 _do_resize(box, size.width, size.height);
737 _event_handler([self window], nil, 1);
738 oldsize.width = size.width;
739 oldsize.height = size.height;
740 _handle_resize_events(box);
741 }
742 }
743 -(void)showWindow
744 {
745 NSSize size = [self frame].size;
746
747 if(oldsize.width == size.width && oldsize.height == size.height)
748 {
749 _do_resize(box, size.width, size.height);
750 _handle_resize_events(box);
751 }
752
753 }
754 -(void)windowDidBecomeMain:(id)sender
755 {
756 if(windowmenu)
757 {
758 [DWApp setMainMenu:windowmenu];
759 }
760 else
761 {
762 [DWApp setMainMenu:DWMainMenu];
763 }
764 _event_handler(self, nil, 13);
765 }
766 -(void)setMenu:(NSMenu *)input { windowmenu = input; [windowmenu retain]; }
767 -(void)menuHandler:(id)sender { _event_handler(sender, nil, 8); }
768 -(void)mouseDragged:(NSEvent *)theEvent { if(_DWCapture == self) { _event_handler(self, theEvent, 5); } }
769 -(void)mouseMoved:(NSEvent *)theEvent
770 {
771 id hit = [self hitTest:[theEvent locationInWindow]];
772
773 if(_DWCapture == hit)
774 {
775 _event_handler(hit, theEvent, 5);
776 }
777 }
778 @end
779
780 /* Subclass for a button type */
781 @interface DWButton : NSButton
782 {
783 void *userdata;
784 NSButtonType buttonType;
785 DWBox *parent;
786 }
787 -(void *)userdata;
788 -(void)setUserdata:(void *)input;
789 -(void)buttonClicked:(id)sender;
790 -(void)setButtonType:(NSButtonType)input;
791 -(NSButtonType)buttonType;
792 -(void)setParent:(DWBox *)input;
793 -(DWBox *)parent;
794 @end
795
796 @implementation DWButton
797 -(void *)userdata { return userdata; }
798 -(void)setUserdata:(void *)input { userdata = input; }
799 -(void)buttonClicked:(id)sender
800 {
801 _event_handler(self, nil, 8);
802 if([self buttonType] == NSRadioButton)
803 {
804 DWBox *viewbox = [self parent];
805 Box *thisbox = [viewbox box];
806 int z;
807
808 for(z=0;z<thisbox->count;z++)
809 {
810 if(thisbox->items[z].type != TYPEBOX)
811 {
812 id object = thisbox->items[z].hwnd;
813
814 if([object isMemberOfClass:[DWButton class]])
815 {
816 DWButton *button = object;
817
818 if(button != self && [button buttonType] == NSRadioButton)
819 {
820 [button setState:NSOffState];
821 }
822 }
823 }
824 }
825 }
826 }
827 -(void)setButtonType:(NSButtonType)input { buttonType = input; [super setButtonType:input]; }
828 -(NSButtonType)buttonType { return buttonType; }
829 -(void)setParent:(DWBox *)input { parent = input; }
830 -(DWBox *)parent { return parent; }
831 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
832 @end
833
834 /* Subclass for a progress type */
835 @interface DWPercent : NSProgressIndicator
836 {
837 void *userdata;
838 }
839 -(void *)userdata;
840 -(void)setUserdata:(void *)input;
841 @end
842
843 @implementation DWPercent
844 -(void *)userdata { return userdata; }
845 -(void)setUserdata:(void *)input { userdata = input; }
846 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
847 @end
848
849 /* Subclass for a scrollbox type */
850 @interface DWScrollBox : NSScrollView
851 {
852 void *userdata;
853 id box;
854 }
855 -(void *)userdata;
856 -(void)setUserdata:(void *)input;
857 -(void)setBox:(void *)input;
858 -(id)box;
859 @end
860
861 @implementation DWScrollBox
862 -(void *)userdata { return userdata; }
863 -(void)setUserdata:(void *)input { userdata = input; }
864 -(void)setBox:(void *)input { box = input; }
865 -(id)box { return box; }
866 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
867 @end
868
869 /* Subclass for a textfield that supports vertical centering */
870 @interface DWTextFieldCell : NSTextFieldCell
871 {
872 BOOL vcenter;
873 }
874 -(NSRect)drawingRectForBounds:(NSRect)theRect;
875 -(void)setVCenter:(BOOL)input;
876 @end
877
878 @implementation DWTextFieldCell
879 -(NSRect)drawingRectForBounds:(NSRect)theRect
880 {
881 /* Get the parent's idea of where we should draw */
882 NSRect newRect = [super drawingRectForBounds:theRect];
883
884 /* If we are being vertically centered */
885 if(vcenter)
886 {
887 /* Get our ideal size for current text */
888 NSSize textSize = [self cellSizeForBounds:theRect];
889
890 /* Center that in the proposed rect */
891 float heightDelta = newRect.size.height - textSize.height;
892 if (heightDelta > 0)
893 {
894 newRect.size.height -= heightDelta;
895 newRect.origin.y += (heightDelta / 2);
896 }
897 }
898
899 return newRect;
900 }
901 -(void)setVCenter:(BOOL)input { vcenter = input; }
902 @end
903
904 @interface DWEntryFieldFormatter : NSFormatter
905 {
906 int maxLength;
907 }
908 - (void)setMaximumLength:(int)len;
909 - (int)maximumLength;
910 @end
911
912 /* This formatter subclass will allow us to limit
913 * the text length in an entryfield.
914 */
915 @implementation DWEntryFieldFormatter
916 -(id)init
917 {
918 [super init];
919 maxLength = INT_MAX;
920 return self;
921 }
922 -(void)setMaximumLength:(int)len { maxLength = len; }
923 -(int)maximumLength { return maxLength; }
924 -(NSString *)stringForObjectValue:(id)object { return (NSString *)object; }
925 -(BOOL)getObjectValue:(id *)object forString:(NSString *)string errorDescription:(NSString **)error { *object = string; return YES; }
926 -(BOOL)isPartialStringValid:(NSString **)partialStringPtr
927 proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
928 originalString:(NSString *)origString
929 originalSelectedRange:(NSRange)origSelRange
930 errorDescription:(NSString **)error
931 {
932 if([*partialStringPtr length] > maxLength)
933 {
934 return NO;
935 }
936 return YES;
937 }
938 -(NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes { return nil; }
939 @end
940
941 /* Subclass for a entryfield type */
942 @interface DWEntryField : NSTextField
943 {
944 void *userdata;
945 id clickDefault;
946 }
947 -(void *)userdata;
948 -(void)setUserdata:(void *)input;
949 -(void)setClickDefault:(id)input;
950 @end
951
952 @implementation DWEntryField
953 -(void *)userdata { return userdata; }
954 -(void)setUserdata:(void *)input { userdata = input; }
955 -(void)setClickDefault:(id)input { clickDefault = input; }
956 -(void)keyUp:(NSEvent *)theEvent
957 {
958 unichar vk = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
959 if(clickDefault && vk == VK_RETURN)
960 {
961 [[self window] makeFirstResponder:clickDefault];
962 } else
963 {
964 [super keyUp:theEvent];
965 }
966 }
967 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
968 @end
969
970 /* Subclass for a entryfield password type */
971 @interface DWEntryFieldPassword : NSSecureTextField
972 {
973 void *userdata;
974 id clickDefault;
975 }
976 -(void *)userdata;
977 -(void)setUserdata:(void *)input;
978 -(void)setClickDefault:(id)input;
979 @end
980
981 @implementation DWEntryFieldPassword
982 -(void *)userdata { return userdata; }
983 -(void)setUserdata:(void *)input { userdata = input; }
984 -(void)setClickDefault:(id)input { clickDefault = input; }
985 -(void)keyUp:(NSEvent *)theEvent
986 {
987 if(clickDefault && [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == VK_RETURN)
988 {
989 [[self window] makeFirstResponder:clickDefault];
990 } else
991 {
992 [super keyUp:theEvent];
993 }
994 }
995 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
996 @end
997
998 /* Subclass for a Notebook control type */
999 @interface DWNotebook : NSTabView
1000 #ifdef BUILDING_FOR_SNOW_LEOPARD
1001 <NSTabViewDelegate>
1002 #endif
1003 {
1004 void *userdata;
1005 int pageid;
1006 }
1007 -(void *)userdata;
1008 -(void)setUserdata:(void *)input;
1009 -(int)pageid;
1010 -(void)setPageid:(int)input;
1011 -(void)tabView:(NSTabView *)notebook didSelectTabViewItem:(NSTabViewItem *)notepage;
1012 @end
1013
1014 /* Subclass for a Notebook page type */
1015 @interface DWNotebookPage : NSTabViewItem
1016 {
1017 void *userdata;
1018 int pageid;
1019 }
1020 -(void *)userdata;
1021 -(void)setUserdata:(void *)input;
1022 -(int)pageid;
1023 -(void)setPageid:(int)input;
1024 @end
1025
1026 @implementation DWNotebook
1027 -(void *)userdata { return userdata; }
1028 -(void)setUserdata:(void *)input { userdata = input; }
1029 -(int)pageid { return pageid; }
1030 -(void)setPageid:(int)input { pageid = input; }
1031 -(void)tabView:(NSTabView *)notebook didSelectTabViewItem:(NSTabViewItem *)notepage
1032 {
1033 id object = [notepage view];
1034 DWNotebookPage *page = (DWNotebookPage *)notepage;
1035
1036 if([object isMemberOfClass:[DWBox class]])
1037 {
1038 DWBox *view = object;
1039 Box *box = [view box];
1040 NSSize size = [view frame].size;
1041 _do_resize(box, size.width, size.height);
1042 _handle_resize_events(box);
1043 }
1044 _event_handler(self, (void *)[page pageid], 15);
1045 }
1046 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1047 @end
1048
1049 @implementation DWNotebookPage
1050 -(void *)userdata { return userdata; }
1051 -(void)setUserdata:(void *)input { userdata = input; }
1052 -(int)pageid { return pageid; }
1053 -(void)setPageid:(int)input { pageid = input; }
1054 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1055 @end
1056
1057 /* Subclass for a color chooser type */
1058 @interface DWColorChoose : NSColorPanel
1059 {
1060 DWDialog *dialog;
1061 NSColor *pickedcolor;
1062 }
1063 -(void)changeColor:(id)sender;
1064 -(void)setDialog:(DWDialog *)input;
1065 -(DWDialog *)dialog;
1066 @end
1067
1068 @implementation DWColorChoose
1069 -(void)changeColor:(id)sender { pickedcolor = [self color]; }
1070 -(BOOL)windowShouldClose:(id)window { DWDialog *d = dialog; dialog = nil; dw_dialog_dismiss(d, pickedcolor); [window orderOut:nil]; return NO; }
1071 -(void)setDialog:(DWDialog *)input { dialog = input; }
1072 -(DWDialog *)dialog { return dialog; }
1073 @end
1074
1075 /* Subclass for a splitbar type */
1076 @interface DWSplitBar : NSSplitView
1077 #ifdef BUILDING_FOR_SNOW_LEOPARD
1078 <NSSplitViewDelegate>
1079 #endif
1080 {
1081 void *userdata;
1082 float percent;
1083 }
1084 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification;
1085 -(void *)userdata;
1086 -(void)setUserdata:(void *)input;
1087 -(float)percent;
1088 -(void)setPercent:(float)input;
1089 @end
1090
1091 @implementation DWSplitBar
1092 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification
1093 {
1094 NSArray *views = [self subviews];
1095 id object;
1096
1097 for(object in views)
1098 {
1099 if([object isMemberOfClass:[DWBox class]])
1100 {
1101 DWBox *view = object;
1102 Box *box = [view box];
1103 NSSize size = [view frame].size;
1104 _do_resize(box, size.width, size.height);
1105 _handle_resize_events(box);
1106 }
1107 }
1108 }
1109 -(void *)userdata { return userdata; }
1110 -(void)setUserdata:(void *)input { userdata = input; }
1111 -(float)percent { return percent; }
1112 -(void)setPercent:(float)input { percent = input; }
1113 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1114 @end
1115
1116 /* Subclass for a slider type */
1117 @interface DWSlider : NSSlider
1118 {
1119 void *userdata;
1120 }
1121 -(void *)userdata;
1122 -(void)setUserdata:(void *)input;
1123 -(void)sliderChanged:(id)sender;
1124 @end
1125
1126 @implementation DWSlider
1127 -(void *)userdata { return userdata; }
1128 -(void)setUserdata:(void *)input { userdata = input; }
1129 -(void)sliderChanged:(id)sender { _event_handler(self, (void *)[self integerValue], 14); }
1130 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1131 @end
1132
1133 /* Subclass for a slider type */
1134 @interface DWScrollbar : NSScroller
1135 {
1136 void *userdata;
1137 double range;
1138 double visible;
1139 }
1140 -(void *)userdata;
1141 -(void)setUserdata:(void *)input;
1142 -(float)range;
1143 -(float)visible;
1144 -(void)setRange:(double)input1 andVisible:(double)input2;
1145 -(void)scrollerChanged:(id)sender;
1146 @end
1147
1148 @implementation DWScrollbar
1149 -(void *)userdata { return userdata; }
1150 -(void)setUserdata:(void *)input { userdata = input; }
1151 -(float)range { return range; }
1152 -(float)visible { return visible; }
1153 -(void)setRange:(double)input1 andVisible:(double)input2 { range = input1; visible = input2; }
1154 -(void)scrollerChanged:(id)sender
1155 {
1156 double max = (range - visible);
1157 double result = ([self doubleValue] * max);
1158 double newpos = result;
1159
1160 switch ([sender hitPart])
1161 {
1162
1163 case NSScrollerDecrementLine:
1164 if(newpos > 0)
1165 {
1166 newpos--;
1167 }
1168 break;
1169
1170 case NSScrollerIncrementLine:
1171 if(newpos < max)
1172 {
1173 newpos++;
1174 }
1175 break;
1176
1177 case NSScrollerDecrementPage:
1178 newpos -= visible;
1179 if(newpos < 0)
1180 {
1181 newpos = 0;
1182 }
1183 break;
1184
1185 case NSScrollerIncrementPage:
1186 newpos += visible;
1187 if(newpos > max)
1188 {
1189 newpos = max;
1190 }
1191 break;
1192
1193 default:
1194 ; /* do nothing */
1195 }
1196 int newposi = (int)newpos;
1197 newpos = (newpos - (double)newposi) > 0.5 ? (double)(newposi + 1) : (double)newposi;
1198 if(newpos != result)
1199 {
1200 [self setDoubleValue:(newpos/max)];
1201 }
1202 _event_handler(self, (void *)(int)newpos, 14);
1203 }
1204 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1205 @end 690 @end
1206 691
1207 /* Subclass for a render area type */ 692 /* Subclass for a render area type */
1208 @interface DWRender : NSControl 693 @interface DWRender : NSControl
1209 { 694 {
1239 -(void)mouseUp:(NSEvent *)theEvent { _event_handler(self, theEvent, 4); } 724 -(void)mouseUp:(NSEvent *)theEvent { _event_handler(self, theEvent, 4); }
1240 -(NSMenu *)menuForEvent:(NSEvent *)theEvent { _event_handler(self, theEvent, 3); return nil; } 725 -(NSMenu *)menuForEvent:(NSEvent *)theEvent { _event_handler(self, theEvent, 3); return nil; }
1241 -(void)rightMouseUp:(NSEvent *)theEvent { _event_handler(self, theEvent, 4); } 726 -(void)rightMouseUp:(NSEvent *)theEvent { _event_handler(self, theEvent, 4); }
1242 -(void)otherMouseDown:(NSEvent *)theEvent { _event_handler(self, theEvent, 3); } 727 -(void)otherMouseDown:(NSEvent *)theEvent { _event_handler(self, theEvent, 3); }
1243 -(void)otherMouseUp:(NSEvent *)theEvent { _event_handler(self, theEvent, 4); } 728 -(void)otherMouseUp:(NSEvent *)theEvent { _event_handler(self, theEvent, 4); }
1244 -(void)mouseDragged:(NSEvent *)theEvent { if(_DWCapture == self) { _event_handler(self, theEvent, 5); } } 729 -(void)mouseDragged:(NSEvent *)theEvent { _event_handler(self, theEvent, 5); }
1245 -(void)drawRect:(NSRect)rect { _event_handler(self, nil, 7); } 730 -(void)drawRect:(NSRect)rect { _event_handler(self, nil, 7); }
1246 -(void)keyDown:(NSEvent *)theEvent { _event_handler(self, theEvent, 2); } 731 -(void)keyDown:(NSEvent *)theEvent { _event_handler(self, theEvent, 2); }
1247 -(BOOL)isFlipped { return NO; } 732 -(BOOL)isFlipped { return NO; }
1248 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [font release]; [super dealloc]; } 733 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [font release]; [super dealloc]; }
1249 -(BOOL)acceptsFirstResponder { return YES; } 734 -(BOOL)acceptsFirstResponder { return YES; }
735 @end
736
737 /* Subclass for a top-level window */
738 @interface DWView : DWBox
739 #ifdef BUILDING_FOR_SNOW_LEOPARD
740 <NSWindowDelegate>
741 #endif
742 {
743 NSMenu *windowmenu;
744 NSSize oldsize;
745 }
746 -(BOOL)windowShouldClose:(id)sender;
747 -(void)setMenu:(NSMenu *)input;
748 -(void)windowDidBecomeMain:(id)sender;
749 -(void)menuHandler:(id)sender;
750 -(void)mouseDragged:(NSEvent *)theEvent;
751 @end
752
753 @implementation DWView
754 -(BOOL)windowShouldClose:(id)sender
755 {
756 if(_event_handler(sender, nil, 6) == FALSE)
757 return YES;
758 return NO;
759 }
760 - (void)viewDidMoveToWindow
761 {
762 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:NSWindowDidResizeNotification object:[self window]];
763 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeMain:) name:NSWindowDidBecomeMainNotification object:[self window]];
764 }
765 - (void)dealloc
766 {
767 if(windowmenu)
768 {
769 [windowmenu release];
770 }
771 [[NSNotificationCenter defaultCenter] removeObserver:self];
772 [super dealloc];
773 }
774 - (void)windowResized:(NSNotification *)notification;
775 {
776 NSSize size = [self frame].size;
777
778 if(oldsize.width != size.width || oldsize.height != size.height)
779 {
780 _do_resize(box, size.width, size.height);
781 _event_handler([self window], nil, 1);
782 oldsize.width = size.width;
783 oldsize.height = size.height;
784 _handle_resize_events(box);
785 }
786 }
787 -(void)showWindow
788 {
789 NSSize size = [self frame].size;
790
791 if(oldsize.width == size.width && oldsize.height == size.height)
792 {
793 _do_resize(box, size.width, size.height);
794 _handle_resize_events(box);
795 }
796
797 }
798 -(void)windowDidBecomeMain:(id)sender
799 {
800 if(windowmenu)
801 {
802 [DWApp setMainMenu:windowmenu];
803 }
804 else
805 {
806 [DWApp setMainMenu:DWMainMenu];
807 }
808 _event_handler(self, nil, 13);
809 }
810 -(void)setMenu:(NSMenu *)input { windowmenu = input; [windowmenu retain]; }
811 -(void)menuHandler:(id)sender { _event_handler(sender, nil, 8); }
812 -(void)mouseDragged:(NSEvent *)theEvent { _event_handler(self, theEvent, 5); }
813 -(void)mouseMoved:(NSEvent *)theEvent
814 {
815 id hit = [self hitTest:[theEvent locationInWindow]];
816
817 if([hit isMemberOfClass:[DWRender class]])
818 {
819 _event_handler(hit, theEvent, 5);
820 }
821 }
822 @end
823
824 /* Subclass for a button type */
825 @interface DWButton : NSButton
826 {
827 void *userdata;
828 NSButtonType buttonType;
829 DWBox *parent;
830 }
831 -(void *)userdata;
832 -(void)setUserdata:(void *)input;
833 -(void)buttonClicked:(id)sender;
834 -(void)setButtonType:(NSButtonType)input;
835 -(NSButtonType)buttonType;
836 -(void)setParent:(DWBox *)input;
837 -(DWBox *)parent;
838 @end
839
840 @implementation DWButton
841 -(void *)userdata { return userdata; }
842 -(void)setUserdata:(void *)input { userdata = input; }
843 -(void)buttonClicked:(id)sender
844 {
845 _event_handler(self, nil, 8);
846 if([self buttonType] == NSRadioButton)
847 {
848 DWBox *viewbox = [self parent];
849 Box *thisbox = [viewbox box];
850 int z;
851
852 for(z=0;z<thisbox->count;z++)
853 {
854 if(thisbox->items[z].type != TYPEBOX)
855 {
856 id object = thisbox->items[z].hwnd;
857
858 if([object isMemberOfClass:[DWButton class]])
859 {
860 DWButton *button = object;
861
862 if(button != self && [button buttonType] == NSRadioButton)
863 {
864 [button setState:NSOffState];
865 }
866 }
867 }
868 }
869 }
870 }
871 -(void)setButtonType:(NSButtonType)input { buttonType = input; [super setButtonType:input]; }
872 -(NSButtonType)buttonType { return buttonType; }
873 -(void)setParent:(DWBox *)input { parent = input; }
874 -(DWBox *)parent { return parent; }
875 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
876 @end
877
878 /* Subclass for a progress type */
879 @interface DWPercent : NSProgressIndicator
880 {
881 void *userdata;
882 }
883 -(void *)userdata;
884 -(void)setUserdata:(void *)input;
885 @end
886
887 @implementation DWPercent
888 -(void *)userdata { return userdata; }
889 -(void)setUserdata:(void *)input { userdata = input; }
890 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
891 @end
892
893 /* Subclass for a scrollbox type */
894 @interface DWScrollBox : NSScrollView
895 {
896 void *userdata;
897 id box;
898 }
899 -(void *)userdata;
900 -(void)setUserdata:(void *)input;
901 -(void)setBox:(void *)input;
902 -(id)box;
903 @end
904
905 @implementation DWScrollBox
906 -(void *)userdata { return userdata; }
907 -(void)setUserdata:(void *)input { userdata = input; }
908 -(void)setBox:(void *)input { box = input; }
909 -(id)box { return box; }
910 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
911 @end
912
913 /* Subclass for a textfield that supports vertical centering */
914 @interface DWTextFieldCell : NSTextFieldCell
915 {
916 BOOL vcenter;
917 }
918 -(NSRect)drawingRectForBounds:(NSRect)theRect;
919 -(void)setVCenter:(BOOL)input;
920 @end
921
922 @implementation DWTextFieldCell
923 -(NSRect)drawingRectForBounds:(NSRect)theRect
924 {
925 /* Get the parent's idea of where we should draw */
926 NSRect newRect = [super drawingRectForBounds:theRect];
927
928 /* If we are being vertically centered */
929 if(vcenter)
930 {
931 /* Get our ideal size for current text */
932 NSSize textSize = [self cellSizeForBounds:theRect];
933
934 /* Center that in the proposed rect */
935 float heightDelta = newRect.size.height - textSize.height;
936 if (heightDelta > 0)
937 {
938 newRect.size.height -= heightDelta;
939 newRect.origin.y += (heightDelta / 2);
940 }
941 }
942
943 return newRect;
944 }
945 -(void)setVCenter:(BOOL)input { vcenter = input; }
946 @end
947
948 @interface DWEntryFieldFormatter : NSFormatter
949 {
950 int maxLength;
951 }
952 - (void)setMaximumLength:(int)len;
953 - (int)maximumLength;
954 @end
955
956 /* This formatter subclass will allow us to limit
957 * the text length in an entryfield.
958 */
959 @implementation DWEntryFieldFormatter
960 -(id)init
961 {
962 [super init];
963 maxLength = INT_MAX;
964 return self;
965 }
966 -(void)setMaximumLength:(int)len { maxLength = len; }
967 -(int)maximumLength { return maxLength; }
968 -(NSString *)stringForObjectValue:(id)object { return (NSString *)object; }
969 -(BOOL)getObjectValue:(id *)object forString:(NSString *)string errorDescription:(NSString **)error { *object = string; return YES; }
970 -(BOOL)isPartialStringValid:(NSString **)partialStringPtr
971 proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
972 originalString:(NSString *)origString
973 originalSelectedRange:(NSRange)origSelRange
974 errorDescription:(NSString **)error
975 {
976 if([*partialStringPtr length] > maxLength)
977 {
978 return NO;
979 }
980 return YES;
981 }
982 -(NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes { return nil; }
983 @end
984
985 /* Subclass for a entryfield type */
986 @interface DWEntryField : NSTextField
987 {
988 void *userdata;
989 id clickDefault;
990 }
991 -(void *)userdata;
992 -(void)setUserdata:(void *)input;
993 -(void)setClickDefault:(id)input;
994 @end
995
996 @implementation DWEntryField
997 -(void *)userdata { return userdata; }
998 -(void)setUserdata:(void *)input { userdata = input; }
999 -(void)setClickDefault:(id)input { clickDefault = input; }
1000 -(void)keyUp:(NSEvent *)theEvent
1001 {
1002 unichar vk = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
1003 if(clickDefault && vk == VK_RETURN)
1004 {
1005 [[self window] makeFirstResponder:clickDefault];
1006 } else
1007 {
1008 [super keyUp:theEvent];
1009 }
1010 }
1011 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1012 @end
1013
1014 /* Subclass for a entryfield password type */
1015 @interface DWEntryFieldPassword : NSSecureTextField
1016 {
1017 void *userdata;
1018 id clickDefault;
1019 }
1020 -(void *)userdata;
1021 -(void)setUserdata:(void *)input;
1022 -(void)setClickDefault:(id)input;
1023 @end
1024
1025 @implementation DWEntryFieldPassword
1026 -(void *)userdata { return userdata; }
1027 -(void)setUserdata:(void *)input { userdata = input; }
1028 -(void)setClickDefault:(id)input { clickDefault = input; }
1029 -(void)keyUp:(NSEvent *)theEvent
1030 {
1031 if(clickDefault && [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == VK_RETURN)
1032 {
1033 [[self window] makeFirstResponder:clickDefault];
1034 } else
1035 {
1036 [super keyUp:theEvent];
1037 }
1038 }
1039 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1040 @end
1041
1042 /* Subclass for a Notebook control type */
1043 @interface DWNotebook : NSTabView
1044 #ifdef BUILDING_FOR_SNOW_LEOPARD
1045 <NSTabViewDelegate>
1046 #endif
1047 {
1048 void *userdata;
1049 int pageid;
1050 }
1051 -(void *)userdata;
1052 -(void)setUserdata:(void *)input;
1053 -(int)pageid;
1054 -(void)setPageid:(int)input;
1055 -(void)tabView:(NSTabView *)notebook didSelectTabViewItem:(NSTabViewItem *)notepage;
1056 @end
1057
1058 /* Subclass for a Notebook page type */
1059 @interface DWNotebookPage : NSTabViewItem
1060 {
1061 void *userdata;
1062 int pageid;
1063 }
1064 -(void *)userdata;
1065 -(void)setUserdata:(void *)input;
1066 -(int)pageid;
1067 -(void)setPageid:(int)input;
1068 @end
1069
1070 @implementation DWNotebook
1071 -(void *)userdata { return userdata; }
1072 -(void)setUserdata:(void *)input { userdata = input; }
1073 -(int)pageid { return pageid; }
1074 -(void)setPageid:(int)input { pageid = input; }
1075 -(void)tabView:(NSTabView *)notebook didSelectTabViewItem:(NSTabViewItem *)notepage
1076 {
1077 id object = [notepage view];
1078 DWNotebookPage *page = (DWNotebookPage *)notepage;
1079
1080 if([object isMemberOfClass:[DWBox class]])
1081 {
1082 DWBox *view = object;
1083 Box *box = [view box];
1084 NSSize size = [view frame].size;
1085 _do_resize(box, size.width, size.height);
1086 _handle_resize_events(box);
1087 }
1088 _event_handler(self, (void *)[page pageid], 15);
1089 }
1090 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1091 @end
1092
1093 @implementation DWNotebookPage
1094 -(void *)userdata { return userdata; }
1095 -(void)setUserdata:(void *)input { userdata = input; }
1096 -(int)pageid { return pageid; }
1097 -(void)setPageid:(int)input { pageid = input; }
1098 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1099 @end
1100
1101 /* Subclass for a color chooser type */
1102 @interface DWColorChoose : NSColorPanel
1103 {
1104 DWDialog *dialog;
1105 NSColor *pickedcolor;
1106 }
1107 -(void)changeColor:(id)sender;
1108 -(void)setDialog:(DWDialog *)input;
1109 -(DWDialog *)dialog;
1110 @end
1111
1112 @implementation DWColorChoose
1113 -(void)changeColor:(id)sender { pickedcolor = [self color]; }
1114 -(BOOL)windowShouldClose:(id)window { DWDialog *d = dialog; dialog = nil; dw_dialog_dismiss(d, pickedcolor); [window orderOut:nil]; return NO; }
1115 -(void)setDialog:(DWDialog *)input { dialog = input; }
1116 -(DWDialog *)dialog { return dialog; }
1117 @end
1118
1119 /* Subclass for a splitbar type */
1120 @interface DWSplitBar : NSSplitView
1121 #ifdef BUILDING_FOR_SNOW_LEOPARD
1122 <NSSplitViewDelegate>
1123 #endif
1124 {
1125 void *userdata;
1126 float percent;
1127 }
1128 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification;
1129 -(void *)userdata;
1130 -(void)setUserdata:(void *)input;
1131 -(float)percent;
1132 -(void)setPercent:(float)input;
1133 @end
1134
1135 @implementation DWSplitBar
1136 -(void)splitViewDidResizeSubviews:(NSNotification *)aNotification
1137 {
1138 NSArray *views = [self subviews];
1139 id object;
1140
1141 for(object in views)
1142 {
1143 if([object isMemberOfClass:[DWBox class]])
1144 {
1145 DWBox *view = object;
1146 Box *box = [view box];
1147 NSSize size = [view frame].size;
1148 _do_resize(box, size.width, size.height);
1149 _handle_resize_events(box);
1150 }
1151 }
1152 }
1153 -(void *)userdata { return userdata; }
1154 -(void)setUserdata:(void *)input { userdata = input; }
1155 -(float)percent { return percent; }
1156 -(void)setPercent:(float)input { percent = input; }
1157 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1158 @end
1159
1160 /* Subclass for a slider type */
1161 @interface DWSlider : NSSlider
1162 {
1163 void *userdata;
1164 }
1165 -(void *)userdata;
1166 -(void)setUserdata:(void *)input;
1167 -(void)sliderChanged:(id)sender;
1168 @end
1169
1170 @implementation DWSlider
1171 -(void *)userdata { return userdata; }
1172 -(void)setUserdata:(void *)input { userdata = input; }
1173 -(void)sliderChanged:(id)sender { _event_handler(self, (void *)[self integerValue], 14); }
1174 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1175 @end
1176
1177 /* Subclass for a slider type */
1178 @interface DWScrollbar : NSScroller
1179 {
1180 void *userdata;
1181 double range;
1182 double visible;
1183 }
1184 -(void *)userdata;
1185 -(void)setUserdata:(void *)input;
1186 -(float)range;
1187 -(float)visible;
1188 -(void)setRange:(double)input1 andVisible:(double)input2;
1189 -(void)scrollerChanged:(id)sender;
1190 @end
1191
1192 @implementation DWScrollbar
1193 -(void *)userdata { return userdata; }
1194 -(void)setUserdata:(void *)input { userdata = input; }
1195 -(float)range { return range; }
1196 -(float)visible { return visible; }
1197 -(void)setRange:(double)input1 andVisible:(double)input2 { range = input1; visible = input2; }
1198 -(void)scrollerChanged:(id)sender
1199 {
1200 double max = (range - visible);
1201 double result = ([self doubleValue] * max);
1202 double newpos = result;
1203
1204 switch ([sender hitPart])
1205 {
1206
1207 case NSScrollerDecrementLine:
1208 if(newpos > 0)
1209 {
1210 newpos--;
1211 }
1212 break;
1213
1214 case NSScrollerIncrementLine:
1215 if(newpos < max)
1216 {
1217 newpos++;
1218 }
1219 break;
1220
1221 case NSScrollerDecrementPage:
1222 newpos -= visible;
1223 if(newpos < 0)
1224 {
1225 newpos = 0;
1226 }
1227 break;
1228
1229 case NSScrollerIncrementPage:
1230 newpos += visible;
1231 if(newpos > max)
1232 {
1233 newpos = max;
1234 }
1235 break;
1236
1237 default:
1238 ; /* do nothing */
1239 }
1240 int newposi = (int)newpos;
1241 newpos = (newpos - (double)newposi) > 0.5 ? (double)(newposi + 1) : (double)newposi;
1242 if(newpos != result)
1243 {
1244 [self setDoubleValue:(newpos/max)];
1245 }
1246 _event_handler(self, (void *)(int)newpos, 14);
1247 }
1248 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1250 @end 1249 @end
1251 1250
1252 /* Subclass for a MLE type */ 1251 /* Subclass for a MLE type */
1253 @interface DWMLE : NSTextView 1252 @interface DWMLE : NSTextView
1254 { 1253 {
7060 * Parameters: 7059 * Parameters:
7061 * handle: Handle to receive mouse input. 7060 * handle: Handle to receive mouse input.
7062 */ 7061 */
7063 void API dw_window_capture(HWND handle) 7062 void API dw_window_capture(HWND handle)
7064 { 7063 {
7065 id object = handle; 7064 /* Don't do anything for now */
7066
7067 _DWCapture = object;
7068 } 7065 }
7069 7066
7070 /* 7067 /*
7071 * Releases previous mouse capture. 7068 * Releases previous mouse capture.
7072 */ 7069 */
7073 void API dw_window_release(void) 7070 void API dw_window_release(void)
7074 { 7071 {
7075 if(_DWCapture) 7072 /* Don't do anything for now */
7076 {
7077 _DWCapture = nil;
7078 }
7079 } 7073 }
7080 7074
7081 /* 7075 /*
7082 * Changes a window's parent to newparent. 7076 * Changes a window's parent to newparent.
7083 * Parameters: 7077 * Parameters: