From d3ad8525c47b97a351cee1c794b053475c80d4ae Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 16 Feb 2019 14:50:15 -0700 Subject: [PATCH 1/6] ignoring .vscode --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1adec08..20b13c9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ _build *.log *.install default.profraw +.vscode From 806a20bbee2da49f3d513cb7ea0b4185ec60fc6f Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 16 Feb 2019 15:27:05 -0700 Subject: [PATCH 2/6] text input work in progress --- renderer-macos/lib/Brisk_macos.re | 2 + renderer-macos/lib/bindings/BriskTextInput.re | 21 +++++++++++ renderer-macos/lib/components/TextInput.re | 37 +++++++++++++++++++ renderer-macos/lib/stubs/BriskTextInput.c | 29 +++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 renderer-macos/lib/bindings/BriskTextInput.re create mode 100644 renderer-macos/lib/components/TextInput.re create mode 100644 renderer-macos/lib/stubs/BriskTextInput.c diff --git a/renderer-macos/lib/Brisk_macos.re b/renderer-macos/lib/Brisk_macos.re index 0ee1a71..8bcea80 100644 --- a/renderer-macos/lib/Brisk_macos.re +++ b/renderer-macos/lib/Brisk_macos.re @@ -12,6 +12,7 @@ module Cocoa = { module BriskButton = BriskButton; module BriskImage = BriskImage; module BriskTextView = BriskTextView; + module BriskTextInput = BriskTextInput; module GCD = GCD; module BriskEffectView = BriskEffectView; @@ -24,3 +25,4 @@ module Text = Text; module Image = Image; module Button = Button; module EffectView = EffectView; +module TextInput = TextInput; diff --git a/renderer-macos/lib/bindings/BriskTextInput.re b/renderer-macos/lib/bindings/BriskTextInput.re new file mode 100644 index 0000000..7ff9bae --- /dev/null +++ b/renderer-macos/lib/bindings/BriskTextInput.re @@ -0,0 +1,21 @@ +type t = CocoaTypes.view; + +[@noalloc] external make: unit => t = "ml_BriskTextInput_make"; + +[@noalloc] +external setCallback: (t, unit => unit) => unit = "ml_BriskTextInput_setCallback"; + +let make = (~onChange=?, ()) => { + let input = make(); + + switch (onChange) { + | Some(callback) => + setCallback( + input, + UIEventCallback.make(callback), + ) + | None => () + }; + + input; +}; diff --git a/renderer-macos/lib/components/TextInput.re b/renderer-macos/lib/components/TextInput.re new file mode 100644 index 0000000..fc21eb6 --- /dev/null +++ b/renderer-macos/lib/components/TextInput.re @@ -0,0 +1,37 @@ +open Brisk; + +type attribute = [ Layout.style ]; + +type style = list(attribute); + +let component = nativeComponent("TextInput"); +let make = (~style= [], ~callback=() => (), children) => + component((_: Hooks.empty) => + { + make: () => { + let input = + BriskTextInput.( + make(~onChange=callback, ()) + ); + }, + configureInstance: (~isFirstRender as _, {view} as node) => { + style + |> List.iter(attribute => + switch (attribute) { + | #Layout.style => () + } + ); + node; + }, + children, + } + ); + +let createElement = (~style=[], ~callback=?, ~children, ()) => + element( + make( + ~style, + ~callback?, + listToElement(children) + ) + ); diff --git a/renderer-macos/lib/stubs/BriskTextInput.c b/renderer-macos/lib/stubs/BriskTextInput.c new file mode 100644 index 0000000..a58fc23 --- /dev/null +++ b/renderer-macos/lib/stubs/BriskTextInput.c @@ -0,0 +1,29 @@ +@interface BriskTextInput : NSTextInputContext + +@end + +@implementation NSTextInputContext +- (id)init { + self = [super init]; + return self; +} +@property(nonatomic, assign) value _callback; + +- (void)setCallback:(value)action; +@end + +NSTextInputContext *ml_BriskTextInput_make() { + BriskTextInput *input = [BriskTextInput new]; + retainView(input); + + return input; +} + +CAMLprim value ml_BriskTextInput_setCallback(BriskTextInput *input, value callback_v) { + CAMLparam1(callback_v); + value callback = callback_v; + + [input setCallback:callback]; + + CAMLreturn(Val_unit); +} From c3e1545f0c027e34efb019fb2fa8ad27b24f57cb Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 17 Feb 2019 00:11:38 -0700 Subject: [PATCH 3/6] added BriskTextInput --- renderer-macos/lib/dune | 1 + 1 file changed, 1 insertion(+) diff --git a/renderer-macos/lib/dune b/renderer-macos/lib/dune index 4e42776..8248fa6 100644 --- a/renderer-macos/lib/dune +++ b/renderer-macos/lib/dune @@ -25,6 +25,7 @@ BriskButton GCD BriskEffectView + BriskTextInput ) (c_flags (:standard -Wextra -Wall -Werror -O -g -std=c99 -pedantic-errors -Wsign-compare -Wshadow From 5ffa7de37d38bfe7c255a8ff917aa635ae46a1ea Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 17 Feb 2019 00:11:56 -0700 Subject: [PATCH 4/6] required methods in implementation --- renderer-macos/lib/stubs/BriskTextInput.c | 48 ++++++++++++++++------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/renderer-macos/lib/stubs/BriskTextInput.c b/renderer-macos/lib/stubs/BriskTextInput.c index a58fc23..dc4b39a 100644 --- a/renderer-macos/lib/stubs/BriskTextInput.c +++ b/renderer-macos/lib/stubs/BriskTextInput.c @@ -1,15 +1,43 @@ -@interface BriskTextInput : NSTextInputContext +#import "BriskStylableText.h" + +@interface BriskTextInput : NSTextInputContext @end @implementation NSTextInputContext -- (id)init { - self = [super init]; - return self; + +- (instancetype)initWithClient:(id)client { + //designated initializer +} + +- (BOOL)handleEvent:(NSEvent *)event { + //if system consumes event return YES +} + +- (void)activate { + //invoked when receiver gets activated +} + +- (void)deactivate { + //invoked when receiver gets deactivated +} + +- (void)discardMarkedText { + //Notifies the system to discard the current conversion session. The client should clear its marked range when sending this message. +} + +- (void)invalidateCharacterCoordinates { + //Notifies the text input system that information related to character positions, including the document's visual coordinates, text selection, and document contents, has been modified. Text engines implementing the NSTextInputClient protocol should send this message whenever any of these changes occur, and -[NSTextInputContext handleEvent:] will not otherwise be called. -handleEvent: serves as an implicit notification that any of these changes could have occurred. +} + ++ (nullable NSString *)localizedNameForInputSource:(NSTextInputSourceIdentifier)inputSourceIdentifier { + /**** Text Input source attributes ****/ +/* Returns the display name for inputSourceIdentifier. + */ } -@property(nonatomic, assign) value _callback; -- (void)setCallback:(value)action; +@dynamic currentInputContext; + @end NSTextInputContext *ml_BriskTextInput_make() { @@ -19,11 +47,3 @@ NSTextInputContext *ml_BriskTextInput_make() { return input; } -CAMLprim value ml_BriskTextInput_setCallback(BriskTextInput *input, value callback_v) { - CAMLparam1(callback_v); - value callback = callback_v; - - [input setCallback:callback]; - - CAMLreturn(Val_unit); -} From 59ec7184107d32e2a04e661d9e30acbdc6661b27 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 20 Feb 2019 00:26:12 -0700 Subject: [PATCH 5/6] cleaned up stub --- renderer-macos/lib/stubs/BriskTextInput.c | 38 ++--------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/renderer-macos/lib/stubs/BriskTextInput.c b/renderer-macos/lib/stubs/BriskTextInput.c index dc4b39a..cb374d6 100644 --- a/renderer-macos/lib/stubs/BriskTextInput.c +++ b/renderer-macos/lib/stubs/BriskTextInput.c @@ -1,42 +1,8 @@ -#import "BriskStylableText.h" - -@interface BriskTextInput : NSTextInputContext +@interface BriskTextInput : NSTextInputContext @end -@implementation NSTextInputContext - -- (instancetype)initWithClient:(id)client { - //designated initializer -} - -- (BOOL)handleEvent:(NSEvent *)event { - //if system consumes event return YES -} - -- (void)activate { - //invoked when receiver gets activated -} - -- (void)deactivate { - //invoked when receiver gets deactivated -} - -- (void)discardMarkedText { - //Notifies the system to discard the current conversion session. The client should clear its marked range when sending this message. -} - -- (void)invalidateCharacterCoordinates { - //Notifies the text input system that information related to character positions, including the document's visual coordinates, text selection, and document contents, has been modified. Text engines implementing the NSTextInputClient protocol should send this message whenever any of these changes occur, and -[NSTextInputContext handleEvent:] will not otherwise be called. -handleEvent: serves as an implicit notification that any of these changes could have occurred. -} - -+ (nullable NSString *)localizedNameForInputSource:(NSTextInputSourceIdentifier)inputSourceIdentifier { - /**** Text Input source attributes ****/ -/* Returns the display name for inputSourceIdentifier. - */ -} - -@dynamic currentInputContext; +@implementation BriskTextInput @end From 73c7d5b45d0f537af93f936011eef0df0751b89b Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 4 Mar 2019 14:57:53 -0700 Subject: [PATCH 6/6] just trying to et BriskTextInput to render --- renderer-macos/lib/bindings/BriskTextInput.re | 53 ++++++-- renderer-macos/lib/components/TextInput.re | 56 +++++---- renderer-macos/lib/stubs/BriskTextInput.c | 119 +++++++++++++++++- renderer-macos/lib/stubs/BriskTextInput.h | 12 ++ 4 files changed, 205 insertions(+), 35 deletions(-) create mode 100644 renderer-macos/lib/stubs/BriskTextInput.h diff --git a/renderer-macos/lib/bindings/BriskTextInput.re b/renderer-macos/lib/bindings/BriskTextInput.re index 7ff9bae..045f744 100644 --- a/renderer-macos/lib/bindings/BriskTextInput.re +++ b/renderer-macos/lib/bindings/BriskTextInput.re @@ -3,19 +3,50 @@ type t = CocoaTypes.view; [@noalloc] external make: unit => t = "ml_BriskTextInput_make"; [@noalloc] -external setCallback: (t, unit => unit) => unit = "ml_BriskTextInput_setCallback"; +external getTextWidth: t => [@unboxed] float = + "ml_BriskTextInput_getTextWidth_bc" "ml_BriskTextInput_getTextWidth"; -let make = (~onChange=?, ()) => { - let input = make(); +[@noalloc] +external getTextHeight: t => [@unboxed] float = + "ml_BriskTextInput_getTextHeight_bc" "ml_BriskTextInput_getTextHeight"; + +[@noalloc] +external setStringValue: (t, string) => unit = + "ml_BriskTextInput_setStringValue"; + +[@noalloc] +external setPlaceholder: (t, string) => unit = + "ml_BriskTextInput_setPlaceholder"; - switch (onChange) { - | Some(callback) => - setCallback( - input, - UIEventCallback.make(callback), - ) - | None => () - }; +[@noalloc] +external setBackgroundColor: + ( + t, + [@unboxed] float, + [@unboxed] float, + [@unboxed] float, + [@unboxed] float + ) => + unit = + "ml_BriskTextInput_setBackgroundColor_bc" + "ml_BriskTextInput_setBackgroundColor"; + +[@noalloc] +external setPadding: + ( + t, + [@unboxed] float, + [@unboxed] float, + [@unboxed] float, + [@unboxed] float + ) => + unit = + "ml_BriskTextInput_setPadding_bc" "ml_BriskTextInput_setPadding"; + +let make = (value, placeholder) => { + let input = make(); + setStringValue(input, value); + setPlaceholder(input, placeholder); input; }; diff --git a/renderer-macos/lib/components/TextInput.re b/renderer-macos/lib/components/TextInput.re index fc21eb6..4cbd9d9 100644 --- a/renderer-macos/lib/components/TextInput.re +++ b/renderer-macos/lib/components/TextInput.re @@ -1,37 +1,49 @@ open Brisk; -type attribute = [ Layout.style ]; +type attribute = [ Layout.style | Styles.textStyle | Styles.viewStyle]; type style = list(attribute); -let component = nativeComponent("TextInput"); -let make = (~style= [], ~callback=() => (), children) => +let component = nativeComponent("Text"); + +let measure = (node, _, _, _, _) => { + open Layout.FlexLayout.LayoutSupport.LayoutTypes; + + let {context: input}: node = node; + + let width = BriskTextInput.getTextWidth(input) |> int_of_float; + let height = BriskTextInput.getTextHeight(input) |> int_of_float; + + {width, height}; +}; + +let make = (~style=[], ~value, ~placeholder, children) => component((_: Hooks.empty) => { - make: () => { - let input = - BriskTextInput.( - make(~onChange=callback, ()) - ); - }, - configureInstance: (~isFirstRender as _, {view} as node) => { - style - |> List.iter(attribute => + make: () => { + let view = BriskTextInput.make(value, placeholder); + {view, layoutNode: Layout.Node.make(~measure, ~style, view)}; + }, + configureInstance: (~isFirstRender as _, {view} as node) => { + open Layout; + style + |> List.iter(attribute => switch (attribute) { + | `Padding({left, top, right, bottom}) => + BriskTextInput.setPadding(view, left, top, right, bottom) + | `Background(({r, g, b, a}: Color.t)) => + BriskTextInput.setBackgroundColor(view, r, g, b, a) + | #Styles.textStyle => Styles.setTextStyle(view, attribute) + | #Styles.viewStyle => Styles.setViewStyle(view, attribute) | #Layout.style => () } ); + Styles.commitTextStyle(view); node; - }, - children, + }, + children, } ); -let createElement = (~style=[], ~callback=?, ~children, ()) => - element( - make( - ~style, - ~callback?, - listToElement(children) - ) - ); +let createElement = (~style=[], ~value, ~placeholder, ~children, ()) => + element(make(~style, ~value, ~placeholder, listToElement(children))); diff --git a/renderer-macos/lib/stubs/BriskTextInput.c b/renderer-macos/lib/stubs/BriskTextInput.c index cb374d6..709b01e 100644 --- a/renderer-macos/lib/stubs/BriskTextInput.c +++ b/renderer-macos/lib/stubs/BriskTextInput.c @@ -1,15 +1,130 @@ -@interface BriskTextInput : NSTextInputContext +#import "BriskTextInput.h" + +@interface BriskTextInput : NSTextView @end @implementation BriskTextInput +@synthesize attributedString; +@synthesize attributedProps; +@synthesize paragraphStyle; +@synthesize placeholder; + +- (id)init { + self = [super init]; + if (self) { + self.attributedString = [[NSMutableAttributedString alloc] init]; + self.attributedProps = [NSMutableDictionary dictionary]; + self.paragraphStyle = + [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + + self.attributedProps[NSParagraphStyleAttributeName] = self.paragraphStyle; + self.placeholder = [[NSMutableAttributedString alloc] init]; + } + return self; +} + +- (BOOL)isEditable { + return YES; +} + +- (BOOL)isSelectable { + return YES; +} + +- (void)applyTextStyle { + NSRange range = NSMakeRange(0, self.attributedString.length); + + [self.attributedString setAttributes:self.attributedProps range:range]; + [[self textStorage] setAttributedString:self.attributedString]; +} + @end -NSTextInputContext *ml_BriskTextInput_make() { +BriskTextInput *ml_BriskTextInput_make() { BriskTextInput *input = [BriskTextInput new]; retainView(input); return input; } +double ml_BriskTextInput_getTextWidth(BriskTextInput *input) { + return (double)[input.attributedString size].width; +} + +double ml_BriskTextInput_getTextHeight(BriskTextInput *input) { + return (double)[input.attributedString size].height; +} + +CAMLprim value ml_BriskTextInput_getTextWidth_bc(BriskTextInput *input) { + CAMLparam0(); + CAMLreturn(caml_copy_double(ml_BriskTextInput_getTextWidth(input))); +} + +CAMLprim value ml_BriskTextInput_getTextHeight_bc(BriskTextInput *input) { + CAMLparam0(); + CAMLreturn(caml_copy_double(ml_BriskTextInput_getTextHeight(input))); +} + +CAMLprim value ml_BriskTextInput_setStringValue(BriskTextInput *input, + value str_v) { + CAMLparam1(str_v); + + NSString *str = [NSString stringWithUTF8String:String_val(str_v)]; + + [input.attributedString.mutableString setString:str]; + [input applyTextStyle]; + + CAMLreturn(Val_unit); +} + +CAMLprim value ml_BriskTextInput_setPlaceholder(BriskTextInput *input, + value str_v) { + CAMLparam1(str_v); + + NSString *str = [NSString stringWithUTF8String:String_val(str_v)]; + + [input.placeholder.mutableString setString:str]; + [input applyTextStyle]; + + CAMLreturn(Val_unit); +} + +void ml_BriskTextInput_setBackgroundColor(BriskTextInput *input, double red, + double green, double blue, + double alpha) { + NSColor *color = [NSColor colorWithRed:red green:green blue:blue alpha:alpha]; + [input setBackgroundColor:color]; +} + +CAMLprim value ml_BriskTextInput_setBackgroundColor_bc(BriskTextInput *input, + value red_v, + value green_v, + value blue_v, + value alpha_v) { + CAMLparam4(red_v, blue_v, green_v, alpha_v); + + ml_BriskTextInput_setBackgroundColor(input, Double_val(red_v), + Double_val(blue_v), Double_val(green_v), + Double_val(alpha_v)); + + CAMLreturn(Val_unit); +} + +void ml_BriskTextInput_setPadding(BriskTextInput *input, double left, double top, + __unused double right, + __unused double bottom) { + input.textContainerInset = CGSizeMake(left, top); +} + +CAMLprim value ml_BriskTextInput_setPadding_bc(BriskTextInput *input, value left_v, + value top_v, value right_v, + value bottom_v) { + CAMLparam4(left_v, top_v, right_v, bottom_v); + + ml_BriskTextInput_setPadding(input, Double_val(left_v), Double_val(top_v), + Double_val(right_v), Double_val(bottom_v)); + + CAMLreturn(Val_unit); +} diff --git a/renderer-macos/lib/stubs/BriskTextInput.h b/renderer-macos/lib/stubs/BriskTextInput.h new file mode 100644 index 0000000..a08f11b --- /dev/null +++ b/renderer-macos/lib/stubs/BriskTextInput.h @@ -0,0 +1,12 @@ +#import "BriskCocoa.h" + +@protocol BriskTextInputProtocol + +@property(nonatomic, retain) NSMutableAttributedString *attributedString; +@property(nonatomic, retain) NSMutableDictionary *attributedProps; +@property(nonatomic, retain) NSMutableParagraphStyle *paragraphStyle; +@property(nonatomic, retain) NSMutableAttributedString *placeholder; + +- (void)applyTextStyle; + +@end