/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2014 Olaf Wintermann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import "text.h"
#import "container.h"
@implementation TextChangeMgr
- (TextChangeMgr*)initWithValue:(UiText*)text context:(UiContext*)ctx {
value = text;
context = ctx;
last_length = 0;
return self;
}
- (NSUndoManager*)undoManagerForTextView:(NSTextView*)textview {
return (NSUndoManager*)value->undomgr;
}
- (NSRange)textView:(NSTextView *)textview
willChangeSelectionFromCharacterRange:(NSRange)oldrange
toCharacterRange:(NSRange)newrange
{
if(newrange.length != last_length) {
if(newrange.length == 0) {
ui_unset_group(context, UI_GROUP_SELECTION);
} else {
ui_set_group(context, UI_GROUP_SELECTION);
}
}
last_length = newrange.length;
return newrange;
}
@end
UIWIDGET ui_textarea(UiObject *obj, UiText *value) {
UiContainer *ct = uic_get_current_container(obj);
NSRect frame = ct->getframe(ct);
NSScrollView *scrollview = [[NSScrollView alloc] initWithFrame:frame];
[scrollview setHasVerticalScroller:YES];
//[scrollvew setHasHorizontalScroller:YES];
[scrollview setBorderType:NSNoBorder];
//[scrollview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
//frame.size.width = frame.size.width - 15;
NSTextView *textview = [[NSTextView alloc]initWithFrame:frame];
[textview setAllowsUndo:TRUE];
[textview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
[textview setFont:[NSFont fontWithName:@"Menlo" size:12]];
[scrollview setDocumentView:textview];
ct->add(ct, scrollview);
// bind value
if(value) {
value->get = ui_textarea_get;
value->set = ui_textarea_set;
value->getsubstr = ui_textarea_getsubstr;
value->insert = ui_textarea_insert;
value->position = ui_textarea_position;
value->selection = ui_textarea_selection;
value->length = ui_textarea_length;
value->value = NULL;
value->obj = textview;
TextChangeMgr *delegate = [[TextChangeMgr alloc]initWithValue:value context:obj->ctx];
[textview setDelegate:delegate];
NSUndoManager *undomgr = [[NSUndoManager alloc]init];
value->undomgr = undomgr;
}
return textview;
}
char* ui_textarea_get(UiText *text) {
if(text->value) {
free(text->value);
}
NSTextView *textview = (NSTextView*)text->obj;
NSString *str = [[textview textStorage]string];
size_t length = [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const char *cstr = [str UTF8String];
char *value = malloc(length + 1);
memcpy(value, cstr, length);
value[length] = '\0';
text->value = value;
return value;
}
void ui_textarea_set(UiText *text, char *str) {
if(text->value) {
free(text->value);
}
NSTextView *textview = (NSTextView*)text->obj;
NSString *s = [[NSString alloc]initWithUTF8String:str];
NSAttributedString *as = [[NSAttributedString alloc]initWithString:s];
[[textview textStorage] setAttributedString:as];
text->value = NULL;
}
char* ui_textarea_getsubstr(UiText *text, int begin, int end) {
if(text->value) {
free(text->value);
}
NSTextView *textview = (NSTextView*)text->obj;
NSString *str = [[textview textStorage]string];
NSRange range;
range.location = begin;
range.length = end - begin;
NSString *substr = [str substringWithRange:range];
size_t length = [substr lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const char *cstr = [substr UTF8String];
char *value = malloc(length + 1);
memcpy(value, cstr, length);
value[length] = '\0';
text->value = value;
return value;
}
void ui_textarea_insert(UiText *text, int pos, char *str) {
if(text->value) {
free(text->value);
}
NSTextView *textview = (NSTextView*)text->obj;
NSString *s = [[NSString alloc]initWithUTF8String:str];
NSAttributedString *as = [[NSAttributedString alloc]initWithString:s];
[[textview textStorage] insertAttributedString:as atIndex: pos];
text->value = NULL;
}
int ui_textarea_position(UiText *text) {
return [[[(NSTextView*)text->obj selectedRanges] objectAtIndex:0] rangeValue].location;
}
void ui_textarea_selection(UiText *text, int *begin, int *end) {
NSRange range = [[[(NSTextView*)text->obj selectedRanges] objectAtIndex:0] rangeValue];
*begin = range.location;
*end = range.location + range.length;
}
int ui_textarea_length(UiText *text) {
return [[(NSTextView*)text->obj textStorage] length];
}
void ui_text_undo(UiText *text) {
[(NSUndoManager*)text->undomgr undo];
}
void ui_text_redo(UiText *text) {
[(NSUndoManager*)text->undomgr redo];
}