http://www.newton-inc.com/dev/techinfo/qa/qa.htmclEditView (the children paragraph, polygon, and picture views containing text, shapes, and ink) to a soup and restore it later?viewChildren array for the clEditView, probably in the viewQuitScript. To restore, assign the array from the soup to the viewChildren slot, either at viewSetupFormScript or viewSetupChildrenScript time; or later followed by RedoChildren.viewChildren array. (For example, text has optional slots for fonts and tabs, shapes have optional slots for pen width, and new optional slots may be added in future versions.) Saving the whole array also allows you to gracefully handle templates in the viewChildren array that don't have an ink, points, or text slot. In the future, there may be children that represent other data types.clEditView? If I drag out a clParagraphView child in NTK, the text is not selectable even if I turn on vGesturesAllowed. clEditViews have special requirements. To create a text child of a clEditView that can be selected and modified by the user (as if it had been created by the user) you need to do the following: textTemplate := { viewStationery: 'para, viewBounds: RelBounds(20, 20, 100, 20), text: "Demo Text", }; AddView(self, textTemplate);
The view must be added dynamically (with AddView), because the clEditView expects to be able to modify the contents as the user edits this item. The template (textTemplate above) should also be created at run time, because the clEditView adds some slots to this template when creating the view. (Specifically it fills in the _proto slot based on the viewStationery value. The _proto slot will be set to protoParagraph) If you try to create too much at compile time, you will get -48214 (object is read only) errors when opening the edit view.viewStationery of 'para, a text slot, and a viewBounds slot. You can also set viewFont, styles, tabs, and other slots to make the text look as you would like.TieViews, do I simply remove the appropriate slots from the viewTie array?viewChangedScript to be called. This can happen without calling SetValue, for example, when the user writes into a view that has recognition enabled, the viewChangedScript will get called.UntieViews function, and call it if it exists, but if it does not, removing the pair of elements from the tied view's viewTie array is fine.FilterDialog and ModalDialog. (See the Q&A "FilterDialog and ModalDialog Limitations" for important information on those methods.)clParagraphView's viewIdleScript is fired off automatically. (For example, an operation which results in the creation or changing of a keyboard's input focus within the view will trigger the viewIdleScript.) Why does this happen and what can I do about it?clParagraphView class internally uses the idle event mechanism to implement some of its features. Unfortunately, any viewIdleScripts provided by developers also execute when the system idle events are processed. Only the "heavyweight" views do this, "lightweight" paragraph views (in other words, simple static text views) do not.viewIdleScript. You can either accept the extra idle script calls, or use another non-clParagraphView based view to implement your idle functions.theView:FilterDialog(), the part of the screen that was not covered by the theView no longer accepts any pen input. theView is a protoFloatNGo. Is there some trick?FilterDialog and ModalDialog when used to open views that are not immediate children of the root view. At this point we're not sure if we'll be able to fix the problem.FilterDialog or ModalDialog to open more than one non-child-of-root view at a time. Opening more than one at a time with either of these messages causes the state information from the first to be overwritten with the state information from the second. The result will be a failure to exit the modality when the views are closed.FilterDialog.BuildContext. This is the best solution because it avoids awkward situations when the child of an application is system-modal. (Application subviews should normally be only application-modal.)ModalDialog message instead of FilterDialog. ModalDialog does not have the child-of-root bug. (FilterDialog is preferred, since it uses fewer system resources and is faster.)view:FilterDialog();if view.modalState then begin local childOfRoot := view; while childOfRoot:Parent() <> GetRoot() do childOfRoot := childOfRoot:Parent(); childOfRoot.modalState := view.modalState; end;
This only needs to be done if the view that you send the FilterDialog message to is not an immediate child of the root. You can probably improve the efficiency in your applications, since the root child is ususally your application's base view, which is a "well known" view. That is, you may be able to re-write the code as follows:view:FilterDialog();if view.modalState then base.modalState := view.modalState;
{left: -30, top: <top>, right: 0, bottom: <bottom>}
vjParentRightH + vjLeftRatio
DragAndDrop message to a view, the bitmap for the pre-drag state is cached. Once the drag loop starts, you can not update that cached bitmap. When you "scroll" the view (probably using RefreshViews), you update the screen, but the cached bitmap is still there and is used by the DragAndDrop routine to update the screen as the dragged item is moved.ModalConfirm and AsyncConfirm, the 2.0 Newton Programmer's Reference says you may pass three types of things as the buttonList argument: a symbol ('okCancel or 'yesNo), and array of strings, or an array of frames with 'value and 'text slots.'okCancelDefaultOk, 'okCancelDefaultCancel, 'yesNoDefaultYes, and 'yesNoDefaultNo. They do the obvious thing, setting the default key as specified and the close key to Cancel or No if those aren't the default. However, using these symbols on a Newton 2.0 OS device will result in the "OK" and "Cancel" buttons always being displayed, even if you specify 'yesNoDefaultYes or 'yesNoDefaultNo. buttonList argument allows an additional slot, called 'keyValue. Supported values for this slot are the symbols 'default and 'close, or NIL/not present. 'default makes the button the default key, and 'close makes the button activate with the close key. Any other value will cause a problem in the current Newton 2.1 implementation. The keyValue slot is ignored on the Newton 2.0 OS.'yesNoDefaultYes and 'yesNoDefaultNo symbols if you intend to run on both Newton 2.0 and 2.1 devices. Instead, use one of these specifiers: '[{text: "Yes", value: TRUE, keyValue: default}, {text: "No", value: NIL, keyValue: close}]
'[{text: "Yes", value: TRUE}, {text: "No", value: NIL, keyValue: default}]ROM_DefRotateFunc. When I rotate the screen the base view rotates properly, but the linked view closes. Do I need to add a ReorientToScreen slot to the linked view?ReorientToScreen slot in the view tells the OS that this view is OK, so the slot is used first as a token ("magic cookie") to tell the OS that this view knows about rotation. Later during the rotation operation, the ReorientToScreen message is sent to your application's base view and to other views that are immediate children of the root view. That method then performs its second function, which is to completely handle resizing the view and its children for the new screen size. (Even views which are small enough so that no resizing is necessary need a ReorientToScreen method. That method may need to move the base view to ensure that it remains on-screen after rotation.)ROM_DefRotateFunc for this script, since it fills the magic cookie requirement and handles resizing for most views. ROM_DefRotateFunc is very simple: it send a close and then an open message to the view. Since well-written applications take screen size into account when they open, this works fine in most cases. However, applications that keep track of internal state that isn't preserved when the app is closed can't use ROM_DefRotateFunc, because when the app reopens on the rotated screen, it will look different. Opening a linked subview is one example of this; it doesn't usually make sense to remember that a slip is open, since it's usually closed when your application is closed.ReorientToScreen method to your linked views wouldn't help; since they are descendents of your base view and not children of the root view, the OS wouldn't handle these views. (It's up to your application to keep its kids under control.) You could change your application so that it kept track of whether the linked views were open or closed, and restored them to the same state when it was reopened. However, this might be confusing to users who closed your app and then opened it again much later.ReorientToScreen method, which either resizes the views so they fit on the new screen, or which closes and reopens the views such that the floaters also re-open. By using the ReorientToScreen message to handle the special case, you get to do something different during rotation versus during opening at the user request (for example, after tapping on the Extras icon.)BuildContext also must be handled carefully during rotation. Because they are themselves children of the root view, they'll each need their own ReorientToScreen method or the screen may not be rotatable when they are open or they won't reopen after rotation. If you use ROM_DefRotateFunc, the slip itself will be closed and reopened, and care may need to be taken to ensure the slip properly handles being reopened, and that its connection to its controlling application is not lost.protoTXView text engine in Newton 2.1 OS. How can I get text, styles, pictures, etc. out of the object returned by protoTXView's Externalize method without either a) instantiating a protoTXView or b) digging in the data structure?protoTXView produces. The data structures in that object are not documented or supported. You may be tempted to do this anyway, since it looks as though the data structure is obvious. Don't, it isn't. ProtoTXView actually uses several different data formats depending on the complexity and storage destination for the data.protoTXView to get at the data. Here's one way: local textView := BuildContext( { _proto: protoTXView, viewBounds: SetBounds(0, 0, 0, 0), viewFlags: 0, ReorientToScreen: ROM_DefRotateFunc, }); textView:Open(); textView:Internalize(myExternalizedData);
You can now use all the protoTXView APIs to get the data from the textView object. Don't forget to clean up with textView:Close() when you're done.protoTXView data stored in a soup entry, for example to get the text for sending in email?protoTXView method GetRangeData always allocates its storage from the NewtonScript heap, so you will need to copy the data into a destination VBO in chunks. Here's some code to do that. (This code uses a 4K block size, you may wish to adjust that as necessary, add error checking, etc.) StringFilter is used to remove the protoTXView graphic indicator. constant kChunkSize := 0x1000; // 4K chunks local start := 0; local theText := GetDefaultStore():NewVBO('string, length("")); // make VBO into a proper string BinaryMunger(theText,0,nil, "", 0, nil); while numChars-start > kChunkSize do // strip out graphics characters StrMunger(theText,start, nil, StringFilter( textView:GetRangeData( { first: start, last: start := start + kChunkSize }, 'text), "\u2206\u", 'rejectAll), 0, nil); // copy remainder if start < numChars then StrMunger(theText,start,nil, StringFilter( textView:GetRangeData( {first: start, last: numChars}, 'text), "\u2206\u", 'rejectAll), 0, nil); // theText now holds plain text from the protoTXView
For clarity, the code above does not use ClearVBOCache as mentioned in the Q&A, "How to Avoid Resets When Using VBOs". If you are having problems with large VBOs during code like that mentioned above, see that Q&A for more information.clParagraphView and would like to find the current position of the caret within that view so that I can scroll to it. Is there a way to do this?clParagraphView method called caretRelativeToVisibleRect that you can use.'inbox, 'top, 'left, 'bottom, 'right, or nil. Below is a list of what each return value signifies.paragraphView:CaretRelativeToVisibleRect( visibleBox )'inbox The caret is positioned inside the visible region.'top The caret is above the visible region.'bottom The caret is below the visible region. 'left The caret is to the left of the visible region.'right The caret is to the right of the visible region. nil The view has no caret.protoUpDownScroller on an Apple MessagePad 2000 , tapping on the scroller once calls the viewScroll2DScript two or three times. Shouldn't the scroller call the script only once per tap? viewScroll2DScript once per tap, but rather calls it repeatedly while the pen is held down over the scroll arrow. This is normal scroller behavior, and has in fact been there all along. with the MP2000, the processor is so much faster that it can chug through many scroll operations before the pen is released.while not StrokeDone(unit) do targetView:viewScroll2dscript(....)". If it takes even 1 tick for the StrokeDone function to report true, it's possible that the viewScroll2DScript might have been called more than once.viewScroll2DScript. Use the global function Sleep for this, as that call will yeild the NewtonScript task and let other parts of the OS work (or sleep the processor, saving battery power.) constant kMaxScrollSpeed := 60; // ticks viewScroll2DScript: func(...) begin local t := ticks(); ... // do scrolling stuff RefreshViews(); // show scrolled result Sleep(MAX(kMaxScrollSpeed - (ticks() - t), 0)); end;