Building NEW 'Classic' Controls

Organizing tasks to work on, New Features Ideas, Building LCS & LCB Libraries & Widgets, Redecorating and Modifying the IDE, Hacking / Editing Tools, Compiling the Engine from Source, etc.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

FourthWorld wrote: Wed Aug 14, 2024 6:46 pm With HyperCard, SuperCard, OMO, Gain Momentum, Toolbook, Director, Spinnaker Plus, MetaCard, Revolution, and LiveCode, what you describe is the Externals interface.

Indeed nearly all of the key bullet points for the v8 product were externals. They continue to be relied on to this day.
Those externals weren't the bullet points for LC CE v8 that excited me, for me it was primarily about the addition of Extension Builder & the Widgets and Mac 64bit Intel (which also saw the removal of using CEF Framework from Browser Widget on macOS in favor of WebKit/Safari in the OS). Browser Widget is sort of a hybrid thing, the 'Browser Factory' is in the Engine, it was previously used only via an External before the introduction of Widgets.

From the (now historical) posts that I've read from people who know, 'Extension' modules do indeed use the same lcdi interface as Externals do under the hood to establish the connection between them and the engine, it's the xB language that is wrapping it with xTalk-like syntax modules that makes it easier to read and use (once you get the hang of it / over the learning curve).
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

FourthWorld wrote: Wed Aug 14, 2024 6:50 pm My assessment of performance is not mine, merely passed on from the company who made Builder.

If you have rendering metrics that favor Builder replacements for machine code, that would be useful for everyone.
The intermediation / extra syntax look-up might take a thread CPU clock cycle or two, so sure it's not as fast as machine code , but it's fine. Some render slowdowns can be avoided or mitigated with strategic programming of refresh timing, the coding plays a part in speed.

That's not to say I haven't noticed some degradation in the Engine's rendering speed over the years (try 9.6.1 vs 9.6.3 with Animated GIFs!), and I also certainly wouldn't mind using a rendering library that can do all sorts of GPU acceleration 3D models spinning around all over the place
Like I said I DO understand, it may be some 100s of milliseconds (what's 50-100 milliseconds in human time?) slower to use intermediate bytecode to mediate between the Widget and libSkia in the Engine than it is to use straight compiled machine code to more directly use libSkia to make some buttons appear on a card. However as noted changing anything about the Engine code, like tweaking some appearance of the standard buttons, requires C++ (and maybe ObjC on Mac/iOS) edits and then rebuilding the engine(s, times 6 or 7 versions), versus making widgets which can be unloaded from memory, changed, recompile, and reloaded in under a minute without even quitting out of the Engine! (aka 'Live Reloading') That's a HUGE win for iterative development!

Can you cite me a link to these benchmark tests so I can read them myself?
Still I stand by my 128x128 button Grid Example, that may have more to do with engine memory allocation or handling a ton of scriptObjects in memory, but the engine comes to crawl trying to generate such a grid with many cells using classic controls Buttons, vs my Widget version that renders instantly. The Widget I guess is much quicker because it's only a single object for the Engine to allocate, render, track, instead of 16384 button objects. So there's a huge speed advantage for that use-case right there.

Anyway I'll use all of the cards in the hand we've been dealt if it makes sense, holistic approach ya, know.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

tperry2x wrote: Wed Aug 14, 2024 7:07 pm I noticed it made all manner of other files:
piles-of-files.png
OK, this is probably stuff that should go in a 'How-To-Build-Widget Extensions' and/or a 'What Are Widgets anyway' section, but I'll try to go through this here.

The 'All manner of other files' are files that Extension Builder created from data extracted from the .LCB file, they are used by the IDE, Dictionary (API.lcdoc) and Extension Management (manifest and 'interface' file). Some of these can also be created manually/separately like if you didn't want to use the inline documentation system in your code you can make that markdown file from scratch. Extension Project can also have additional folders with things like foreign code libraries, LoDPI/HiDPI icon images, or any other resource your Extension may need to include. The most important file that gets generated is actual compiled module bytecode which ends in ".lcm" (LC Module), there is syntax that can load that module from disk file. When you 'Package Extension" all of these files get zipped up into a file that ends with ".lce" (LC Extension). That's the package system used to deliver new Extensions to IDE users.
At first I thought it hadn't worked, but it is there:
fool-1.png

Note: the label text font was "" and the label text size was 0.
As soon as I set that to a font (Liberation Sans) and 12 under the label text size, it worked and I could change the other properties through the inspector, just as you would a 'classic control'.
fool-2.png

So, all good.
Well not so much 'good' as it is a work-in-progress. It's odd that setting the 'label property did anything for you, it should've only worked with 'set the text of Widget ..." to whatever, 'the label' shouldn't be stored the same as or used as an synonym for 'the text' prop, in the same way a button menu can have a 'the text' list property AND separately a button 'label' prop ). Anyway it should have had the default text filled in by the OnCreate handler so I'll have to look at that.
But, here's where I come back to my question a little further up. When trying to save the stack, I can't. It goes through the motions of saving a stack - but the stack file never appears. I don't get an error or anything either, which means I lose any changes to this new stack, and have to repeat the entire process through 'Extensions Builder' again.

I had hoped it would be a simple oxtstack file that you could copy & paste the 'LabelBox' out of and into a stack of your choice, but it doesn't work like that :?:

Also, I wondered - do these files then need to all live in a subfolder together somewhere? Sorry for all the foolish questions.
What gets stored in the stack file is only reference to the extension module used, and the properties array that was used with it. So if the Extension is not loaded by the Engine FIRST, you won't see any widget when you open that stack. If the Extension is installed (instead of temporarily loaded) either in the User Folder or included in the IDE folders, then it gets automatically loaded when the Engine starts up. If you're only TESTING the Extension but did not install it, then the module gets auto-unloaded when you close that temporary test stack it that it created, so if you then open a saved stack again that had it place on to the card, then the Widget module won't be loaded and you'll get no Widget on screen. The temporary testing stack that it creates should not (cannot?) be saved, don't do that, instead install the widget, then place it on a card in a new stack, save that stack, then reopen the widget should be there as long as the module is still loaded.

If you change widget identifier, or the editable properties of, or version number, and then load this newer version of the same widget, and the properties array in a stored in a previously mad stack may not 'match-up' and you may again get no widget displayed when you open that stack where the widget reference to the old version of it was placed. You may get some message about an 'Array Element' is missing or something like that, which is the array that widgets properties are stored in.

Now, that is sort of an issue with Widgets, they need to be loaded into memory before they can be used, they are not normally stored embedded in their entirety into the stack file, but an interesting trick is that they can be loaded from binarydata of that module.lcm file, so you can store that data, in a variable or perhaps in a custom property embedded into a stack file, and then you load the module from that data 'on preOpenStack' before the Widget is needed in order to render anything. I've even done this in 'script only ' stack by base64 encoding the binary module and storing it as plain ASCII text in a variable, easy/fast decode+load.

If we all had the same base set of Widgets (which we should already have the same very basic set of including the IDE Widgets and the SVGPath Icon widget) then it's not a problem to use any of those widgets without needing to also include the Widget along with the stack (although I would still prefer be able to optionally encapsulate it all together), but not the case if it's a brand new custom widget that you want to share a demo stack of. This was the spark for the idea I've mentioned a few times for having something like the old HC 'Resource Movers' and a pseudo 'Resource Fork' that can be used to embed Extensions into a stack and inject a small preOpenStack Script script to load them.

Hope that helps make some sense of it.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

FourthWorld wrote: Wed Aug 14, 2024 4:13 pm In actionable terms, this philosophical shift, and the prospect of shifting back, invites us to consider two things:

1. IDE messaging can be designed in a way that doesn't need to prohibit devs from using key language feature like tool modes in their own apps, leaving the door open for a wide range of apoa that are free more cumbersome to build if key language feature must be rewritten in script.

2. If prompts IDE maintainers to consider control rendering methods that work equally well regardless of the current tool for a smoother overall user experience.

Thank you for considering this.
OK, I will take these thoughts into consideration.
I think I know what you mean abut Tool modes becoming more the domain of the IDE, in fact they were sort of 'painted over' and some wreckage left behind (I found some while working on redesigning 'Tools' Palette).

I have a few Extensions that already have their own edit modes built-in, encapsulating functionality and properties in a Widget module (OOP, this is the way!) means Stack authors can easily write stacks that can allow end users of stacks/standalones to use the editing features. Is that the sort of thing you mean?

I think Widgets could be a bit like the idea with Apple's defunct 'OpenDoc' Editors back in the day, that idea being that instead of 'apps' you can have 'software components' data editors that users can mix and match, along with stored data in interactive, editable documents. I quite like the idea, too bad it failed to catch on. Much like that old 'interactive Hyper Text demo' from the 1960s has yet to be realized ( longest running vaporware ever)...sigh.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

Here's an old Widget idea that I was playing with a few years back,
https://github.com/PaulMcClernan/org.op ... agetwister

Watch demo Image Trister Preview Video (was supposed to be 'Twister') in this file:
https://github.com/PaulMcClernan/org.op ... wVideo.mp4
To see what that was about.
However, that video does not really do it justice as far as showing rendering speed/quality because I purposely reduced the frame rate the video to try to make the .mp4 file tiny (it's only 0.5mb).

Basically it's an Image rendering box with the image painted inside an adjustable Round Rect (path) that you can 3D(ish) transform by setting bits of a transform matrix. Renders pretty quickly, fast enough for a basic 20-30fps-ish frame-rate animation at least (probably depends on bit on the CPU/GPU).
User avatar
tperry2x
Posts: 3209
Joined: Tue Dec 21, 2021 9:10 pm
Location: Somewhere in deepest darkest Norfolk, England
Contact:

Re: Building NEW 'Classic' Controls

Post by tperry2x »

OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm When you 'Package Extension" all of these files get zipped up into a file that ends with ".lce" (LC Extension). That's the package system used to deliver new Extensions to IDE users.
Ah, got it - so I'd only part-generated everything. It kind of wasn't finalised, which makes sense as to why I couldn't save the stack I suppose - as it wasn't really ready?
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm It's odd that setting the 'label property did anything for you, it should've only worked with 'set the text of Widget ..." to whatever, 'the label' shouldn't be stored the same as or used as an synonym for 'the text' prop, in the same way a button menu can have a 'the text' list property AND separately a button 'label' prop ). Anyway it should have had the default text filled in by the OnCreate handler so I'll have to look at that.
Sorry, I should clarify: The default text was there, just not at all visible as the text size was set to 0 and the font was "".
Once I sorted the font and chose a text size, then the text rendered. It might have been there before, but as the size was 0 it didn't show anything. To be clear, I didn't type any of that text in at any point.
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm The temporary testing stack that it creates should not (cannot?) be saved, don't do that, instead install the widget, then place it on a card in a new stack, save that stack, then reopen the widget should be there as long as the module is still loaded.
Understood. I now get why it wouldn't work - user error by me :D
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm an interesting trick is that they can be loaded from binarydata of that module.lcm file, so you can store that data, in a variable or perhaps in a custom property embedded into a stack file, and then you load the module from that data 'on preOpenStack' before the Widget is needed in order to render anything. I've even done this in 'script only ' stack by base64 encoding the binary module and storing it as plain ASCII text in a variable, easy/fast decode+load.
Yes, if we can make this all as automatic as possible, without having to juggle files around everywhere by the end user, that will demystify (for want of a better word), this whole process of using LCB extensions. This partly explains why perhaps people don't use them more, as there's quite a lot of steps required to start using them. (in my opinion)
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm If we all had the same base set of Widgets (which we should already have the same very basic set of including the IDE Widgets and the SVGPath Icon widget) then it's not a problem to use any of those widgets without needing to also include the Widget along with the stack (although I would still prefer be able to optionally encapsulate it all together),
Yes - I agree on this. If we could have a load of widgets that we can all use - perhaps an "OXT Base Widgets Pack" - which is included in OXT Lite & OXT DPE, then at least it'll give a consistent approach in both IDEs, so people can write stacks that work in both.
I have a question regarding that though: Do these widgets play nicely when a standalone is being made? I haven't tested yet, but are they packaged up by the standalone builder on all platforms, and do they then work reliably?
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm ...but not the case if it's a brand new custom widget that you want to share a demo stack of. This was the spark for the idea I've mentioned a few times for having something like the old HC 'Resource Movers' and a pseudo 'Resource Fork' that can be used to embed Extensions into a stack and inject a small preOpenStack Script script to load them.
I remember that. I also used to use ResEdit back in the day, to copy XCMDs and XFCNs into a stack file manually. Supercard used to have a section which did that too, but into the data fork of the stack - since Resource forks get 'hosed' by copying to Windows and Linux (and by MacOS now) that does not keep old style resource fork.

If we can keep this all in a variable, or an array - ('in stack'), this will be a lot better in my opinion.
User avatar
tperry2x
Posts: 3209
Joined: Tue Dec 21, 2021 9:10 pm
Location: Somewhere in deepest darkest Norfolk, England
Contact:

Re: Building NEW 'Classic' Controls

Post by tperry2x »

OpenXTalkPaul wrote: Thu Aug 15, 2024 3:00 am Here's an old Widget idea that I was playing with a few years back, [...]Basically it's an Image rendering box with the image painted inside an adjustable Round Rect (path) that you can 3D(ish) transform by setting bits of a transform matrix. Renders pretty quickly, fast enough for a basic 20-30fps-ish frame-rate animation at least (probably depends on bit on the CPU/GPU).
ImageTwisterPreviewVideo.gif
ImageTwisterPreviewVideo.gif (176.87 KiB) Viewed 5070 times
I like this, in actual fact - I think it's brilliant, and it has me thinking about being able to do some pretty cool effects. For example, In theory you could have an example page-turn effect in a stack.
Have a script that exports a rect of the screen to an image container: then use the data of that temporary image to render a visual transform that looks like the page is being curled and turned over. Could this [replace some of / mimic some of] the old QuickTime visual effects?
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

tperry2x wrote: Thu Aug 15, 2024 5:52 am I like this, in actual fact - I think it's brilliant, and it has me thinking about being able to do some pretty cool effects. For example, In theory you could have an example page-turn effect in a stack.
Have a script that exports a rect of the screen to an image container: then use the data of that temporary image to render a visual transform that looks like the page is being curled and turned over. Could this [replace some of / mimic some of] the old QuickTime visual effects?
Thanks.
Yes I suppose you could do stuff like that, although I'm not sure about a 'curl' effect so much as a 'stiff' looking page that's 'turn' is a skewed rectangle made to look 3D-ish, at least not without using some external image manipulating library.
On macOS, some of those transition effects that use 'CoreImage' effects (not QuickTime) do indeed still work, but since they'll only work on macOS (and some of those effects no longer come with macOS), I haven't bothered using them so much, but IIRC I did update the demo stack for that that came with the IDE. It would be great if we had a cohesive set of transitions that worked on every platform that was a larger selection then: Dissolve in/out, Push left/right up/down. This Widget could probably handle doing some scale-up/down, 3d-collapse, stretch, shrink, those sort of transitions, but it would be in cross platform way, no external libraries or OS APIs needed.

One of the motivations for this image Twister Widget idea was to emulated the old macOS CoverFlow. There's lots of JS/CSS libraries for the web that can do those sort of image galleries, a Widget certainly could be designed that does that sort of sliding image list display. In fact this Widget pretty much can do that but it could be made to be so much much better. It could cache image data for a few images so they're ready to render. It could have it's own timer or timeline-property that would posts script messages at various specified time offsets from start (a queue sort of mechanism. Some fake inertia could be added for carousel spin sort of motion. Another thing I worked on a bit was to be able to pass an SVGPath string (like a 'Star' shape or whatever) to use to render the image inside of ( a clippingPath), instead of the rounded rectangle path it currently uses.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

tperry2x wrote: Thu Aug 15, 2024 5:40 am
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm When you 'Package Extension" all of these files get zipped up into a file that ends with ".lce" (LC Extension). That's the package system used to deliver new Extensions to IDE users.
Ah, got it - so I'd only part-generated everything. It kind of wasn't finalised, which makes sense as to why I couldn't save the stack I suppose - as it wasn't really ready?
No that's not it, I'm not really sure why you can't save that auto-created temporary demo stack that the Extension Builder creates. There has been a few times when I've edited its script and then did actually want to save the transient stack, but as you've noted you can't, it doesn't save properly. Now that I think about it, that might be a bug in the Extension Builder scripts.

I'll try to answer the rest later today, busy atm
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

Yes, if we can make this all as automatic as possible, without having to juggle files around everywhere by the end user, that will demystify (for want of a better word), this whole process of using LCB extensions. This partly explains why perhaps people don't use them more, as there's quite a lot of steps required to start using them. (in my opinion)
Well for widgets apparently installing them can be as easy as drag-dropping the module file into the tools palette window (undocumented feature found while working on 'Tools redo')...but I know what you mean, the facts that: there's no built-in editor for XB code let alone for designing Widgets graphically, the documentation for XB is not very good, that there's slightly lower level concepts such as explicit variable declarations that may be required, and the whole compile-test-recompile workflow is an alien concept to xTalk, are all barriers for entry.

As far as 'Automatic' what I had in mind was a 'Resource Mover', that users can choose what resources should be embedded (or copied, or removed), such as Widgets/Extension Modules, but and also things like ImageData, SVG 'font' families (as .TSV), Sounds (embedding sounds/video with the built-in engine method is very old and limited), etc. Into a stack file in some way that's consistent so that they can be loaded by a standard loader script later.

I was just looking at MadPinks super-elaborate multi-control-type set that's a single widget with a TON of properties to set:
https://github.com/madpink/mp-livecode-controls
In the demo stack I see they have some sort of script like the one I used that generates a variable string with base64 encoded data probably containing a modified Widget ?
Screen Shot 2024-08-14 at 11.59.09 PM.png
Screen Shot 2024-08-14 at 11.59.09 PM.png (655.55 KiB) Viewed 4977 times
FourthWorld
Posts: 442
Joined: Sat Sep 11, 2021 4:37 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by FourthWorld »

OpenXTalkPaul wrote: Wed Aug 14, 2024 10:00 pm Like I said I DO understand, it may be some 100s of milliseconds (what's 50-100 milliseconds in human time?)
Stuff adds up.
Can you cite me a link to these benchmark tests so I can read them myself?
I haven't come across a formal benchmarking suite. Thought about making one myself back in the early days of Builder, but a good test would require more work than I can justify spending.

Their CTO has acknowledged in a forum post within the last couple years that for many operations Builder is slower than Script. This is part of why the company is returning to Script Widgets. The CTO's assessment was enough for me.

Performance of the main scripting language is discussed often enough that I hadn't considered that it might be a question.

I've seen a few examples over the years comparing Script to other scripting languages, but that was before PHP7 altered the performance landscape. It would be useful to see a comparison when Python, but tho I've asked a few times I haven't seen anyone write such a test. I may get around to writing a test for JS, but probably not anytime soon. The results I see in web apps is an imprecise assessment but enough for me for now.

The difference between any scripting language and machine code is not something I had considered needing benchmarking.

Still I stand by my 128x128 button Grid Example, that may have more to do with engine memory allocation or handling a ton of scriptObjects in memory, but the engine comes to crawl trying to generate such a grid with many cells using classic controls Buttons, vs my Widget version that renders instantly. The Widget I guess is much quicker because it's only a single object for the Engine to allocate, render, track, instead of 16384 button objects. So there's a huge speed advantage for that use-case right there.
For things like that I would also use a single object where practical, just as I'd use a single field for a table rather than make a grid of separate fields.

A non-uniform set of buttons poses a different challenge, and I've explored around the edges of that for a game system back in the day. Terrain tiles, for example, would be non-uniform.

But there we can also learn from others. How do game makers do things like that? For starters, just like the DataGrid, they don't bother rendering anything that isn't within the clip bounds of the content region. So if a game map might logically run the full extent what group size (about 30 feet in each direction), tiling with subgroups would keep the number of objects needing rendering down to a fraction of the total.

There are no doubt all sorts of edge cases where one can find advantage with Builder. And today, since the considerable funds needed to design, test, iterate, and document and entirely new language have already been spent, if you like it use it.

My suggestion was mostly to proceed with caution if the goal includes replacing engine-native objects when Builder scripted objects. That was one of the stated goals when Builder was first imagined.

But today we have two separate widgets standard buttons on mobile, a different widget for each OS. The challenge of writing one widget that works on both OSes in a newly invented language was understandable, and obviously no one's first choice given the cumbersome requirement a user of replicating OS-limited controls in a product whose primary advantage is multiplatform deployment. The original desktop workflow set the standard of expectation, where one control adapts to OS appearance as needed. But all these years later, that multi-object encumbrance remains. If it were at easy as originally imagined to replace formerly engine-based things with Builder, we'd see it.
Anyway I'll use all of the cards in the hand we've been dealt if it makes sense, holistic approach ya, know.
That's a healthy approach. This is not a funding question for OXT, and with the considerable expense already absorbed years ago, it's here to be used where useful.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

FourthWorld wrote: Thu Aug 15, 2024 4:34 pm
OpenXTalkPaul wrote: Wed Aug 14, 2024 10:00 pm Like I said I DO understand, it may be some 100s of milliseconds (what's 50-100 milliseconds in human time?)
Stuff adds up.
Their CTO has acknowledged in a forum post within the last couple years that for many operations Builder is slower than Script. This is part of why the company is returning to Script Widgets. The CTO's assessment was enough for me.
I wonder what operations those were. For widgets, I'm mostly interested in the rendering speed, not so much the script execution time, which I would think would be faster too for most things. I've never seen detailed benchmarks for LCB vs Script or for rendering classic controls vs. rendering an equivalent Widget control.
I've seen a few examples over the years comparing Script to other scripting languages
What I think would need to be compared here would be the rendering speed of a dynamic classic control while a script is running vs rendering speed of a widget that visually matches that classic control while a script is running. Widgets run in the UI thread, so that there is no blocking of script execution. That can be a big advantage.
The difference between any scripting language and machine code is not something I had considered needing benchmarking.
Agreed, that's not even a question. I think you're mixing things up here.

What I'm saying is the difference in this particular context comes only from any overhead of interpreting the script (symbol look up) and going through the intermediary bytecode. With widget drawing we are calling on libSkia which is linked internally in the Engine, versus the engine calling lib attached to the engine, directly from the engine. The clock cycles used is not nothing, it's not going to be super-framerate game engine on it's own, but the benefits certainly make it acceptable to me for rendering some buttons, SVG, and text.

I know the milliseconds can add up, anything more than about 10-15 milliseconds with real-time music can be enough latency to make it difficult to say on the beat. In scripted loops where timing is critical, you need to subtract the time to execute from the time to send the next beat trigger otherwise you get lag instead of a constant tempo.

The difference between script and extension builder when using foreign code (some C++ dynamic library) via FFI to do something like manipulating pixels of an image is certainly going to be much faster than a script to try to do that, because Core Image, ImageMagick, etc. are compiled machine code, have been optimized for years to do those tasks, they may be running tasks in separate threads, and using GPU acceleration to do the work. No question about that.
Still I stand by my 128x128 button Grid Example
For things like that I would also use a single object where practical, just as I'd use a single field for a table rather than make a grid of separate fields.
There's no single object like the grid I wanted that is included with the engine that can be used like that. That's why I had to make my own.
just like the DataGrid, they don't bother rendering anything that isn't within the clip bounds of the content region
Widgets do not render image that's outside of their bounding box either.
But today we have two separate widgets standard buttons on mobile, a different widget for each OS.
Yes, but if we simply used Canvas drawn widgets for everything (not even talking about 'Native' widgets here) we wouldn't need those MobileControl* or 'Android Native Field", and something like button-widget could look identical on every platforms (all font resources being equal).
one control adapts to OS appearance as needed. But all these years later, that multi-object encumbrance remains. If it were at easy as originally imagined to replace formerly engine-based things with Builder, we'd see it.
But that IS what we are seeing in LiveCode Create, is it not? It sure looks like all-widgets from what I've seen of it. That makes sense when you want your UI to look the same on any platform when running inside a web-app engine on all sorts of different platforms in an HTML5 browser.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

tperry2x wrote: Thu Aug 15, 2024 5:40 am If we could have a load of widgets that we can all use - perhaps an "OXT Base Widgets Pack" - which is included in OXT Lite & OXT DPE, then at least it'll give a consistent approach in both IDEs, so people can write stacks that work in both.
I have a question regarding that though: Do these widgets play nicely when a standalone is being made? I haven't tested yet, but are they packaged up by the standalone builder on all platforms, and do they then work reliably?
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm ...but not the case if it's a brand new custom widget that you want to share a demo stack of. This was the spark for the idea I've mentioned a few times for having something like the old HC 'Resource Movers' and a pseudo 'Resource Fork' that can be used to embed Extensions into a stack and inject a small preOpenStack Script script to load them.
I remember that. I also used to use ResEdit back in the day, to copy XCMDs and XFCNs into a stack file manually. Supercard used to have a section which did that too, but into the data fork of the stack - since Resource forks get 'hosed' by copying to Windows and Linux (and by MacOS now) that does not keep old style resource fork.

If we can keep this all in a variable, or an array - ('in stack'), this will be a lot better in my opinion.
Yes, that's what I'd like to do, targeting equivalent functionality partity to classic controls. If we could at least get a nice button, tabs-button, slider control, scrollbar, progress bar, label-field, list field, and maybe image box (which I have already some starting-point widgets that cover most of that list), that would be good start. Stuff like a field that can do RTFText, HTMText, and has an edit mode, new movieplayer, datagrid, etc. would be a bit more time consuming to create.
There's couple of others (not by me) that I think could be useful to a general audience, that is the Calendar / Date-picker, the Pie Graph, and a maybe couple of others. Maybe we can do poll to vote on which ones to include.

Yes, Widgets/Extensions do play nicely in that they should be auto checked in the Standalone Builder if they're used in the stack (finds by widget kind 'identifier') but you can also double check the include check list in the Standalone Settings stack. When they're checked they're bundled along with the stack into the standalone, I've made .apps for myself that use my CoreMIDI Library to send MIDI signals to Digital Audio Workstation App (Logic, Garageband, Live, etc.) along with custom Widget controls.

Canvas drawn widgets should work fine on all the platforms, even with the Emscripten HTML5 Engine. The OXT web Playground stack has my Piano Widget and a couple of other widgets on that. Obviously any Extension labeled 'Native' is going to be platform specific and not work on other platforms, but even some Extensions that us FFI that wrap a external library can be cross-platform provided there's builds of the foreign library for the target platforms present in the 'code' sub-folder of the Extension's build project folder.
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

tperry2x wrote: Thu Aug 15, 2024 5:40 am If we could have a load of widgets that we can all use - perhaps an "OXT Base Widgets Pack" - which is included in OXT Lite & OXT DPE, then at least it'll give a consistent approach in both IDEs, so people can write stacks that work in both.
I have a question regarding that though: Do these widgets play nicely when a standalone is being made? I haven't tested yet, but are they packaged up by the standalone builder on all platforms, and do they then work reliably?
OpenXTalkPaul wrote: Wed Aug 14, 2024 11:00 pm ...but not the case if it's a brand new custom widget that you want to share a demo stack of. This was the spark for the idea I've mentioned a few times for having something like the old HC 'Resource Movers' and a pseudo 'Resource Fork' that can be used to embed Extensions into a stack and inject a small preOpenStack Script script to load them.
I remember that. I also used to use ResEdit back in the day, to copy XCMDs and XFCNs into a stack file manually. Supercard used to have a section which did that too, but into the data fork of the stack - since Resource forks get 'hosed' by copying to Windows and Linux (and by MacOS now) that does not keep old style resource fork.

If we can keep this all in a variable, or an array - ('in stack'), this will be a lot better in my opinion.
Yes, that's what I'd like to do, targeting equivalent functionality partity to classic controls. If we could at least get a nice button, tabs-button, slider control, scrollbar, progress bar, label-field, list field, and maybe image box (which I have already some starting-point widgets that cover most of that list), that would be good start. Stuff like a field that can do RTFText, HTMText, and has an edit mode, new movieplayer, datagrid, etc. would be a bit more time consuming to create.
There's couple of others (not by me) that I think could be useful to a general audience, that is the Calendar / Date-picker, the Pie Graph, and a maybe couple of others. Maybe we can do poll to vote on which ones to include.

Yes, Widgets/Extensions do play nicely in that they should be auto checked in the Standalone Builder if they're used in the stack (finds by widget kind 'identifier') but you can also double check the include check list in the Standalone Settings stack. When they're checked they're bundled along with the stack into the standalone, I've made .apps for myself that use my CoreMIDI Library to send MIDI signals to Digital Audio Workstation App (Logic, Garageband, Live, etc.) along with custom Widget controls.

Canvas drawn widgets should work fine on all the platforms, even with the Emscripten HTML5 Engine. The OXT web Playground stack ( https://openxtalk-org.github.io/OpenXTalk-Playground/ ) has my Piano Widget and a couple of other widgets on that. Obviously any Extension labeled 'Native' is going to be platform specific and not work on other platforms, but even some Extensions that us FFI that wrap a external library can be cross-platform provided there's builds of the foreign library for the target platforms present in the 'code' sub-folder of the Extension's build project folder.
FourthWorld
Posts: 442
Joined: Sat Sep 11, 2021 4:37 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by FourthWorld »

OpenXTalkPaul wrote: Thu Aug 15, 2024 9:33 pm ...That makes sense when you want your UI to look the same on any platform...
Depends what you want to be consistent with.

For heavily stylized works like games and interactive art, having the app's UI appear consistent to itself across platforms can be useful.

Most of my work is making business systems. Windows users are accustomed to Windows UI conventions, Mac users to theirs, etc. For business apps I strive to be consistent with the context of use.

https://forums.livecode.com/viewtopic.p ... 46#p166546
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

FourthWorld wrote: Fri Aug 16, 2024 1:30 am Windows users are accustomed to Windows UI conventions, Mac users to theirs, etc. For business apps I strive to be consistent with the context of use.
Right but it's not hard to create at least passable knock-offs, specially when everything UI is 'flat' and boring for the past 10 years!

Damn Flatheads!
kids-in-the-hall-crushing-your-head.gif
kids-in-the-hall-crushing-your-head.gif (1.97 MiB) Viewed 4909 times
User avatar
tperry2x
Posts: 3209
Joined: Tue Dec 21, 2021 9:10 pm
Location: Somewhere in deepest darkest Norfolk, England
Contact:

Re: Building NEW 'Classic' Controls

Post by tperry2x »

Getting back to this labelbox widget testing, I found how I could save a stack with it in:

First, open Tools Menu > Extensions Manager
Click the + and select the LCE file I made earlier (further up these posts).
a.png
a.png (150.15 KiB) Viewed 4875 times
It then appears in the extensions manager.
b.png
b.png (147.06 KiB) Viewed 4875 times
I then had to restart the IDE for it to load properly (even though it's in the widgets section in the tools palette, it's not yet available).

Then, I made a new stack and added the new widget to it.
Object menu > New Widget > LabelBox
c.png
c.png (179.48 KiB) Viewed 4875 times
I could then save the stack, after styling the labelbox how I wanted.
d.png
d.png (341.47 KiB) Viewed 4875 times
Strangely, every time I open the stack, the widget forgets if it's set to "Opaque" (I have to turn that back on manually) and it forgets the Radius.
I wondered if the radius is anything to do with 'Raidus' being spelt incorrectly? (not sure, speculation)
Attachments
labelbox.zip
(8.96 KiB) Downloaded 64 times
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

tperry2x wrote: Fri Aug 16, 2024 11:22 am I then had to restart the IDE for it to load properly (even though it's in the widgets section in the tools palette, it's not yet available).
You should not have had to restart the IDE. Just make sure you close any stacks with the widget placed on them and then unload the widget module from memory before you recompile and load it again otherwise Extension Builder gets stuck in a cycle where it can't unload it from memory to load the new version. There can be only once module with a given Identifier loaded into memory at a time.
I could then save the stack, after styling the labelbox how I wanted.
d.png

Strangely, every time I open the stack, the widget forgets if it's set to "Opaque" (I have to turn that back on manually) and it forgets the Radius.
I wondered if the radius is anything to do with 'Raidus' being spelt incorrectly? (not sure, speculation)
That's because it's an unfinished work I progress. Without looking at the source , those two properties need to be added to the handler OnSave() which writes the widgets properties to the array that gets stored as a reference in a stack that it's placed on. Fixing this is just a matter of adding a couple more lines to the handler to save these properties to the array. The properties array gets loaded into the widget with the event handler 'OnLoad()' which is triggered whenever a card with the widget is opened. The handler 'OnCreate()' gets triggered when a new instance of a widget is created / placed onto a stack.

This widget reference / properties array is why I've mentioned that if you change the name of, or remove a property of a widget (like while you're still developing it), then it may not match up with a placed instance reference in stacks which used a previous version of the widget, to the new version of it, and then the Widget is not rendered. The IDE may throw an error saying something about 'an array key is missing', unfortunately the only way to fix it when that happens is delete the old widget and replace it with the new version of the widget (and then have to manually copy the properties and the widgets script over to the new version).
User avatar
OpenXTalkPaul
Posts: 2633
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Building NEW 'Classic' Controls

Post by OpenXTalkPaul »

I'm also updating this early demo widget 'basic button'.
Screen Shot 2024-08-21 at 12.06.32 AM.png
Screen Shot 2024-08-21 at 12.06.32 AM.png (42.64 KiB) Viewed 4467 times
It has a timer scaling effect that can be enabled that gives the button a little a pulsing throbbing effect, pretty cool, it also rotates the canvas which makes whatever icon image you may assign spin.

To test it I used a rather large image (1024x1024 at full scale size) and made a full screen size 'button'. It struggled for smooth animation at that size (it's transforming a roundRect path, a formatted line of text, and large image data in between each frame).
Screen Shot 2024-08-20 at 11.57.14 PM.png
Screen Shot 2024-08-20 at 11.57.14 PM.png (680.86 KiB) Viewed 4467 times
The code is not at all optimized for speed, for example the large image transformations could be done ahead of time and cached in memory. Making its rectangle smaller (cropping the image) resulted in a more smooth frame rate.

It's hard to make a GIF that captures this sort of thing accurately enough but this 3.8mb animate GIF may give you some idea:
basic button_ani.gif
basic button_ani.gif (3.66 MiB) Viewed 4462 times
I guess the point is it's all there to do a button much like the 'classic' button, but in a widget canvas drawn form.
And we can add tricks to it. I'd like to add that 'nope' side to side button 'shake' effect that Apple has used to indicate bad input (like on a log-in attempt with wrong password).
It still needs lots of basic functionality work done though.
I want to make it so that you can precisely position the label text and image scaling, position, and rotation.

I'm also working on a xBuilder Editor/ miniIDE of sorts, because adding all this metadata and handlers to use all of these properties can get a bit tedious. It's a lot of boiler-plate stuff that should be generated for us.
User avatar
richmond62
Posts: 4831
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: Building NEW 'Classic' Controls

Post by richmond62 »

I would suppose the ONLY real difference between a new 'classic' control and a control that has been assembled from a group of other controls is that the former cannot be ungrouped: I am not convinced that is a good thing.
https://richmondmathewson.owlstown.net/
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest