Mercurial > dwindows
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: |