UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2014 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #import <stdio.h> 30 #import <stdlib.h> 31 #import <string.h> 32 33 #import "text.h" 34 #import "container.h" 35 36 @implementation TextChangeMgr 37 38 - (TextChangeMgr*)initWithValue:(UiText*)text context:(UiContext*)ctx { 39 value = text; 40 context = ctx; 41 last_length = 0; 42 return self; 43 } 44 45 - (NSUndoManager*)undoManagerForTextView:(NSTextView*)textview { 46 return (NSUndoManager*)value->undomgr; 47 } 48 49 - (NSRange)textView:(NSTextView *)textview 50 willChangeSelectionFromCharacterRange:(NSRange)oldrange 51 toCharacterRange:(NSRange)newrange 52 { 53 if(newrange.length != last_length) { 54 if(newrange.length == 0) { 55 ui_unset_group(context, UI_GROUP_SELECTION); 56 } else { 57 ui_set_group(context, UI_GROUP_SELECTION); 58 } 59 } 60 61 last_length = newrange.length; 62 return newrange; 63 } 64 65 @end 66 67 68 UIWIDGET ui_textarea(UiObject *obj, UiText *value) { 69 UiContainer *ct = uic_get_current_container(obj); 70 71 NSRect frame = ct->getframe(ct); 72 73 NSScrollView *scrollview = [[NSScrollView alloc] initWithFrame:frame]; 74 [scrollview setHasVerticalScroller:YES]; 75 //[scrollvew setHasHorizontalScroller:YES]; 76 [scrollview setBorderType:NSNoBorder]; 77 //[scrollview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; 78 79 //frame.size.width = frame.size.width - 15; 80 NSTextView *textview = [[NSTextView alloc]initWithFrame:frame]; 81 [textview setAllowsUndo:TRUE]; 82 [textview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; 83 84 [textview setFont:[NSFont fontWithName:@"Menlo" size:12]]; 85 86 [scrollview setDocumentView:textview]; 87 88 ct->add(ct, scrollview); 89 90 // bind value 91 if(value) { 92 value->get = ui_textarea_get; 93 value->set = ui_textarea_set; 94 value->getsubstr = ui_textarea_getsubstr; 95 value->insert = ui_textarea_insert; 96 value->position = ui_textarea_position; 97 value->selection = ui_textarea_selection; 98 value->length = ui_textarea_length; 99 value->value = NULL; 100 value->obj = textview; 101 102 TextChangeMgr *delegate = [[TextChangeMgr alloc]initWithValue:value context:obj->ctx]; 103 [textview setDelegate:delegate]; 104 105 NSUndoManager *undomgr = [[NSUndoManager alloc]init]; 106 value->undomgr = undomgr; 107 } 108 109 return textview; 110 } 111 112 char* ui_textarea_get(UiText *text) { 113 if(text->value) { 114 free(text->value); 115 } 116 NSTextView *textview = (NSTextView*)text->obj; 117 NSString *str = [[textview textStorage]string]; 118 size_t length = [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 119 const char *cstr = [str UTF8String]; 120 char *value = malloc(length + 1); 121 memcpy(value, cstr, length); 122 value[length] = '\0'; 123 text->value = value; 124 return value; 125 } 126 127 void ui_textarea_set(UiText *text, char *str) { 128 if(text->value) { 129 free(text->value); 130 } 131 NSTextView *textview = (NSTextView*)text->obj; 132 NSString *s = [[NSString alloc]initWithUTF8String:str]; 133 NSAttributedString *as = [[NSAttributedString alloc]initWithString:s]; 134 [[textview textStorage] setAttributedString:as]; 135 text->value = NULL; 136 } 137 138 char* ui_textarea_getsubstr(UiText *text, int begin, int end) { 139 if(text->value) { 140 free(text->value); 141 } 142 NSTextView *textview = (NSTextView*)text->obj; 143 NSString *str = [[textview textStorage]string]; 144 NSRange range; 145 range.location = begin; 146 range.length = end - begin; 147 148 NSString *substr = [str substringWithRange:range]; 149 size_t length = [substr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 150 const char *cstr = [substr UTF8String]; 151 char *value = malloc(length + 1); 152 memcpy(value, cstr, length); 153 value[length] = '\0'; 154 text->value = value; 155 return value; 156 } 157 158 void ui_textarea_insert(UiText *text, int pos, char *str) { 159 if(text->value) { 160 free(text->value); 161 } 162 NSTextView *textview = (NSTextView*)text->obj; 163 NSString *s = [[NSString alloc]initWithUTF8String:str]; 164 NSAttributedString *as = [[NSAttributedString alloc]initWithString:s]; 165 [[textview textStorage] insertAttributedString:as atIndex: pos]; 166 text->value = NULL; 167 } 168 169 int ui_textarea_position(UiText *text) { 170 return [[[(NSTextView*)text->obj selectedRanges] objectAtIndex:0] rangeValue].location; 171 } 172 173 void ui_textarea_selection(UiText *text, int *begin, int *end) { 174 NSRange range = [[[(NSTextView*)text->obj selectedRanges] objectAtIndex:0] rangeValue]; 175 *begin = range.location; 176 *end = range.location + range.length; 177 } 178 179 int ui_textarea_length(UiText *text) { 180 return [[(NSTextView*)text->obj textStorage] length]; 181 } 182 183 void ui_text_undo(UiText *text) { 184 [(NSUndoManager*)text->undomgr undo]; 185 } 186 187 void ui_text_redo(UiText *text) { 188 [(NSUndoManager*)text->undomgr redo]; 189 } 190 191