PDA

View Full Version : Draw transparent glyph, ctlimage or Interface background color?



sami
12-07-2012, 08:08 AM
This is probably an old unsolved question, and I'm sure I've asked it before, but I had another look and couldn't find anything definitive, but is there any way to get nicely alpha'ed transparent PNGs or TGAs drawn onto a LScript window? Ctlimage was buggy so I started drawing Glyphs instead and that works nicely, but I can't seem to figure out how to get the alpha to work?

Is it even possible? I'm using Bob Hood's old gendata.ls script to generate my images into text arrays which are drawable by Glyph.

If transparency still isn't possible in LScript, is it possible to get the shade of grey (it changes from install to install & some people have it custom) of the background color and manually tweak the gendata array to have it seem transparent over the window surface. That still doesn't allow you to stack images but it might be better than nothing.

any ideas? thx!

Blochi
12-07-2012, 10:04 AM
Haven't found a way to use transparency either. It works when the Glyph is stamped into an image buffer (in an Image Filter script), but not in the interface. My workaround for the changing background colors is simple: Decide for one of the BG colors and fill the whole ctlviewport with it first. :)

sami
12-07-2012, 04:37 PM
Bummer, thanks, I'll try messing with the ctlviewport then.

Btw, do you know if Python offers us more choices with UI elements and interface stuff than LScript?

Blochi
12-07-2012, 04:47 PM
I don't know. From what I could gather in this thread (http://forums.newtek.com/showthread.php?131397-Is-it-worth-learning-Python-yet) Python doesn't really cut the cheese yet.
Frankly, I have found ctlinfo and ctlviewport, in combination with drawing callback routines and direct mouse position access in a reqmousedown/reqmousemove is giving me total freedom of interface design.

sami
12-08-2012, 04:05 AM
cool. But obviously (I assume) all UI stuff is entirely only within the requestors - right? It's not like I can create even a tooltip or anything outside of a requestor on the main interface with LScript (or Python) can I? Your technique only works in the dialogs right?

thx!

Blochi
12-08-2012, 04:12 AM
Well yeah, but within your requester you're king. That's already more than what I have seen in Maya or MAX, because there you don't even have this freeform canvas type of requester.

You could also do a lot of cool stuff in a viewport with a custom object script. But I don't think direct glyphs are supported, you would have to pixel-punch them in yourself with a looped drawpixel command.

sami
12-08-2012, 07:00 AM
Thanks Blochi! While I'm at it, can I ask you (or anyone else) another question? I have a good idea for a plugin I'd like to make and share so - Do you (or anyone) have any code or could tell me how to use the ctlviewport in a requester, to create a scrollable, drawable canvas/subpanel/2Dviewport? I need to create a drawable canvas that is like 402px high x thousands of pixels wide. And I want to use drawpixels on it and also have it scrollable width-wise. How hard is this and is this possible or are there memory limitations to drawing pixels like that?

Also, how responsive mouse scrolling-wise would that kind of a drawing canvas be? Would it scroll smoothly by the user or by Lscript programmatically?

thanks again!

sami
12-09-2012, 04:33 PM
Never mind, ctlviewport wasn't as hard to figure out as I thought it would be. though do you know the maximum off screen size in pixels that the viewport canvas (not the area onscreen) can be? I mean can I have 10s of thousands of pixels?

Blochi
12-17-2012, 03:42 PM
Yes I believe you can. My sIBL-Loader uses it for procedurally building the scrollable thumbnail page, and so far I haven't found a max size.
I recommend making good use of Glyph images. Drawpixel is all great and well, but if you have repetitive things you may get faster by manipulating the pixels in a glyph, because then they get stamped into the viewport as block on a ctlrefresh. And you can move them around as well...

sami
12-17-2012, 05:06 PM
Ok cool. thanks Blochi!

But one more question: is there a getpixel or something that lets me get what has been drawn into the ctlviewport in a given region so I can save it and then draw something over it and then essentially just erase the last thing I drew by stamping that gotten region back over the latest drawing? Is this possible? I can't figure out how to do this other than just erasing the whole viewport completely and redrawing everything in there. I really need to have overlays that are "moveable" on a ctlviewport. Any ideas?

Blochi
12-17-2012, 05:23 PM
That's where Glyphs come in.
You can read & write pixels in a glyph, so that's where you would do your per-pixel processing. Then you stamp the whole thing into the viewport at once. These glyphs act as sort of sprites... you can even access the pixels inside a glyph that is already drawn in the viewport, and it will properly update.

sami
12-17-2012, 09:45 PM
cool. Didn't know you could write to Glyphs in color like that? So if I understand you right, instead of using draw commands directly on the ctlviewport, I can draw into a glyph 10s of thousands of pixels wide, and then stamp it in one go into the viewport? and then by keeping mutliple versions of that Glyph in different variables, I can erase part of a drawing overlayed on another drawing? I'll read up more on Glyph, but can I use drawline etc commands into a Glyph?? thanks for the tip!

Blochi
12-17-2012, 10:58 PM
err .... no, that's not what I meant.
Don't think the glyph can be that big. And you only have simple pixel-draw inside the glyph.
Why don't you tell me what you're really trying to achieve?

sami
12-17-2012, 11:09 PM
oh sorry for not being clear. I have this big canvas of a ctlviewport and so far I am drawing various shapes and graphics in this big panel on my requester based on objects and other stuff. It's custom drawing using drawline, drawbox etc etc. the drawing can be 10s of thousands of pixels wide (I've just tried drawing 9,000+ wide and it worked so far with the ctlviewport's scrollbars letting you see the whole drawn image as you scroll).

I'd like to draw moveable floating popup boxes in non square shapes (controlled by mouse movement) over top of this drawing. Obviously to move them to where your mouse hovers or clicks, I'd need to either erase the square portion under the my custom popup graphic and redraw that portion that was underneath the popup before I drew it (which is kind of impossible because the whole 9,000+pixel image is drawn in several steps with many commands crossing over this area) -- or I'd need to get the pixels underneath the popup that have been previously drawn in order to save it and redraw that portion for when I "move" my floating popup.

This drawing is big enough and somewhat complex enough that I'd rather not reassemble and redraw it all from scratch every time I move an overlay popup I want to display on it. What do you suggest? If this is not possible with Glyphs or without redrawing everything, then can I just simply draw my popup overlay into a separate ctlimage and move that over the ctlviewport? last time I tried using ctlimage it was very buggy with refresh.

thanks for any ideas or pointers! :)

Blochi
12-18-2012, 12:55 AM
Hmm... I've never done something like this. I'm always redrawing the whole thing from scratch, and rather concentrated on keeping the number of refreshs to the bare minimum.

ctlimage is rather spotty, I agree. And a pain to handle because the image must be loaded from disk.

Is there a way to construct your popup from a regular control type? Maybe a ctlchoice in a vertical configuration? Because there is one odd behavior with ctlinfo and ctlviewport that I have found... I guess it is technically a bug, but one that you can make work for you: They both bully other controls into the background. When you position a control underneath the viewport, then it will be invisible UNTIL the user actually rolls over them. Then they get focus, and pop into the foreground. But as soon as the user leaves the area with his mouse, they become invisible again. So that's your popup behavior right there. I'm using it a lot to make text that I have written into the ctlinfo editable: As soon as the user double-clicks in a custom drawn table, I move a ctltext there. Doing that right inside the function that watches the mouse movement. Then, when he leaves, I grab the value and recycle the same ctltext for the next double-click.
So this way you're not actually touching the content of the ctlviewport. But you would have to find a way to construct your popup out of normal controls. Your ctlimage idea may work, but I imagine it brings up other problems...

sami
12-18-2012, 04:48 AM
Thanks.... .hmmm....bummer... yeah, I was hoping to make the popup out of draw commands so that I can utilize color and make non-square shapes - like callouts. I might resort to the trick you mentioned if I can't get anything else to work - but when I've tried the overlapping controls in the past, I never got them to go back to invisible once the mouse brought them up on rollover. Roll off did not make them invisible again.... maybe it is different with a ctlviewport? Neat trick to make them editable though. I may be trying to push LScript a little too graphically. I'll have another play and let you know if I work anything out.

Bummer there is no getPixel or cache for images...

oh hey, something just occured to me. I could have 2 ctlviewports and draw the massive graphics into both of them and only have one visible. Then draw the poopup into the first and when moving the popup, switch to the 2nd? hmm seems like a ton of memory usage... but that may work...?? Only if I can assign the value of the one to the other?? What do you think? Is that possible / too goofy/inelegant?

sami
12-27-2012, 09:09 PM
Hey Blochi,

Thanks! I tried your advice - I am now successfully using a ctlinfo as a hovering/ floating popup over top of a larger ctlviewport and it works nicely and no problems as long as I do requpdates and make the ctlinfo invisiable by calling ctlinfo.visible(false); whenever I don't need it. :)

However, I was hoping the ctlinfo would have a transparent background - but it's just grey. So that means I cannot have non-rectangluar popups using a ctlinfo work - like say I drew a circle in the ctlinfo, the ctlinfo as a popup will display the circle in a grey box - even though nothing was drawn in the corners of that control. I wanted it to be transparent in the corners so I could have different shapes masked on top of my ctlviewport. So provided I size the ctlinfo to the size of my overlay rectangle that is okay for rectangular shapes, but everything else just shows grey - I can't draw triangles, or callout bubbles or anything and have them be masked on top of another control.

Any ideas? There has to be a way to do this... (crossing my fingers) ... Also do you know anything about either drawing Icon()s in color? They always appear light grey no matter what color I send them with drawtext(). And Is there any way to draw RGBA boxes or lines, like can I draw full black at 50% opacity on top of whatever was already beneath it? Thank you for your expertise!

It's been very quiet in here and either no one knows or are sick of all my GUI related questions ;-)

Blochi
12-28-2012, 01:46 AM
Ahhh ... ctlinfo on top, now that's clever.

I'm afraid the rectangular shape is a hard limitation. Nothing is really transparent, let alone semi-transparent in Lightwave's UI, so I have to say you are hitting a wall there. The only way to get your custom shapes is by drawing them right into the viewport, and that's when you have to reconstruct that area yourself when you clear it.

Colored Icons:

I don't use the Icon object, ever. It was causing mysterious crashes and general instability, at least in the first few LW version where Icons() was implemented. Guess this is fixed now, but in the meantime I have come up with my hack workaround, and that is way better anyway. Because it has color.

Because I was looking at the data fields that are used to draw these icons. And I noticed that they are just simple arrays. So I adopted that and extended it.

This would be an example of an icon with color:



[email protected]
"................",
"....*********...",
"...*OOOOOOO**...",
"..*********O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO***....",
"..*********.....",
"................",
"................"@;



Designing them is a bit like ASCII art. You just make up a convention of symbols. The dot is empty, star is black outline, and O is a color.
I keep this and many other icons in a separate file and include it in the head of my script.

Then in the script I have this function:



drawicon: col1, col2, x, y, v
{
u = sizeof(v);
for(m = 1; m <= u; m++)
{
for(n = 1; n <= 16; n++)
{
if(v[m][n] == "*") drawpixel(col1,x + n,y + m);
else if(v[m][n] != ".") drawpixel(col2,x + n,y + m);
}
}
}



Yes, it's very silly and simple. Just loops through the strings, checks the value of each letter, and then draws a pixel. As you see here you could implement more symbols with more colors. And my icons all have to be exactly 16 pixels wide.

Now with this in place, I can just call this function when I construct my ctlinfo or ctlviewport.

For example, somewhere in the script I fill a table with a red filled box with this line:



drawicon(<0,0,0>,<255,0,0>,tableCol[j],tableRow[i],icon_3dbox_bbo);




Even through the function does a lot of pixel punching, it all seems to happen instantaneously. I still don't really know what the big image in your vctlviewport is, but I recommend giving it a try to modularize your code and pack it all into repeatable routines so you can redraw it from scratch. You'll be surprised at what you can get away with... In one script I'm actually having a floating tooltip window with rounded corners that moves with your mouse. Means, whenever the mouse moves I clear the whole canvas, draw a table with data from the scene, completely filled with colored icons, and then draw the tooltip on top. With the requpdates kept in check (no double-calling, ever!!!) that whole thing does not even visually flicker when you move the mouse!

Blochi

- - - Updated - - -

Ahhh ... ctlinfo on top, now that's clever.

I'm afraid the rectangular shape is a hard limitation. Nothing is really transparent, let alone semi-transparent in Lightwave's UI, so I have to say you are hitting a wall there. The only way to get your custom shapes is by drawing them right into the viewport, and that's when you have to reconstruct that area yourself when you clear it.

Colored Icons:

I don't use the Icon object, ever. It was causing mysterious crashes and general instability, at least in the first few LW version where Icons() was implemented. Guess this is fixed now, but in the meantime I have come up with my hack workaround, and that is way better anyway. Because it has color.

Because I was looking at the data fields that are used to draw these icons. And I noticed that they are just simple arrays. So I adopted that and extended it.

This would be an example of an icon with color:



[email protected]
"................",
"....*********...",
"...*OOOOOOO**...",
"..*********O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO*O*...",
"..*OOOOOOO***....",
"..*********.....",
"................",
"................"@;



Designing them is a bit like ASCII art. You just make up a convention of symbols. The dot is empty, star is black outline, and O is a color.
I keep this and many other icons in a separate file and include it in the head of my script.

Then in the script I have this function:



drawicon: col1, col2, x, y, v
{
u = sizeof(v);
for(m = 1; m <= u; m++)
{
for(n = 1; n <= 16; n++)
{
if(v[m][n] == "*") drawpixel(col1,x + n,y + m);
else if(v[m][n] != ".") drawpixel(col2,x + n,y + m);
}
}
}



Yes, it's very silly and simple. Just loops through the strings, checks the value of each letter, and then draws a pixel. As you see here you could implement more symbols with more colors. And my icons all have to be exactly 16 pixels wide.

Now with this in place, I can just call this function when I construct my ctlinfo or ctlviewport.

For example, somewhere in the script I fill a table with a red filled box with this line:



drawicon(<0,0,0>,<255,0,0>,tableCol[j],tableRow[i],icon_3dbox_bbo);




Even through the function does a lot of pixel punching, it all seems to happen instantaneously. I still don't really know what the big image in your vctlviewport is, but I recommend giving it a try to modularize your code and pack it all into repeatable routines so you can redraw it from scratch. You'll be surprised at what you can get away with... In one script I'm actually having a floating tooltip window with rounded corners that moves with your mouse. Means, whenever the mouse moves I clear the whole canvas, draw a table with data from the scene, completely filled with colored icons, and then draw the tooltip on top. With the requpdates kept in check (no double-calling, ever!!!) that whole thing does not even visually flicker when you move the mouse!

Blochi

sami
12-28-2012, 07:36 AM
I'm afraid the rectangular shape is a hard limitation. Nothing is really transparent, let alone semi-transparent in Lightwave's UI, so I have to say you are hitting a wall there. The only way to get your custom shapes is by drawing them right into the viewport, and that's when you have to reconstruct that area yourself when you clear it.

That sucks about no transparency at all in any control. Thanks for that, I have hit a wall there I guess. At some point I will take a look at doing my own GUI in a .p plugin - but that might mean twice the codebase for both PC & Mac platforms if I do something other than LW's GUI system...




I don't use the Icon object, ever. It was causing mysterious crashes and general instability, at least in the first few LW version where Icons() was implemented. Guess this is fixed now, but in the meantime I have come up with my hack workaround, and that is way better anyway. Because it has color.

I ended up refactoring that SuperText script of mine you dug up a while ago. I rewrote it from scratch and only kept the icon data out of it. It is now pretty clean code and quite fast and stable. FYI as far as I know Icon() is pretty stable now in LW 11 (and 9 as I recall). I've hammered that code in Modeler, but only a tested it a bit in Layout so far, and never had a problem with instability or crashes or anything with Icon().








drawicon: col1, col2, x, y, v
{
u = sizeof(v);
for(m = 1; m <= u; m++)
{
for(n = 1; n <= 16; n++)
{
if(v[m][n] == "*") drawpixel(col1,x + n,y + m);
else if(v[m][n] != ".") drawpixel(col2,x + n,y + m);
}
}
}


Yes, it's very silly and simple. Just loops through the strings, checks the value of each letter, and then draws a pixel. As you see here you could implement more symbols with more colors. And my icons all have to be exactly 16 pixels wide.
...
Even through the function does a lot of pixel punching, it all seems to happen instantaneously. I still don't really know what the big image in your vctlviewport is, but I recommend giving it a try to modularize your code and pack it all into repeatable routines so you can redraw it from scratch. You'll be surprised at what you can get away with... In one script I'm actually having a floating tooltip window with rounded corners that moves with your mouse. Means, whenever the mouse moves I clear the whole canvas, draw a table with data from the scene, completely filled with colored icons, and then draw the tooltip on top. With the requpdates kept in check (no double-calling, ever!!!) that whole thing does not even visually flicker when you move the mouse!


Nice trick with the pixel punching for your drawicon function. I just assumed this would be very very slow. I may replace my draw icon routine in SuperText with this sort of approach and see how that goes. It would mean my icons, bold text and vertically drawn text would all be in the correct colors.

Here's an example of what my new SuperText can do:
110100

You call it like this:



paragraph= "Ten years ago a <color=#ffaa5e>crack commando unit</color> was sent to <b>prison</b> by a military court for a crime they didn't commit. These men promptly escaped from a maximum security stockade to the Los Angeles underground.<br><br>Today, still wanted by the government, they survive as soldiers of fortune. If you have a problem and <color=#00aa5e>no one else can help,</color>, and if you can find them, <icon=ICON_SMILE_INVERSE> maybe you can hire the A-team. ";

// SuperText arguments: x, y, maxTextboxWidthInPixels, textString, addToLineLeading, paddingAroundTextBlock, backgroundColor, borderWidth, borderColor
// passing in nil for the last 3 args makes you not have a bgd color or border
result = SuperText(260, 40, 220, paragraph, 2, 5, <128,128,128>, 3, <20,20,20>);

// it returns an array with these 2 constants which give you # of lines drawn and textbox height in pixels
info("lines = " + result[SUP_LINE_COUNT] + " : height = " + result[SUP_TEXTBOX_HEIGHT]);


Also have a Calc version of the function if you want to get the size of a textblock before drawing it. Still to do word breaking & hyphenation. At the moment it only hard breaks on <br> tags in your string or by character when it hits the width limit. This library is now pretty stable - draws the icons, bold text, colored text, and vertical text and I'm using it in my other scripts as a stable library to draw nicer controls. I'm sure you have your own better routines, but I'm glad I got to cleaning it up - I will try and refactor it using the drawpixel idea so I can get colored icons in it as well now.



Also, it's interesting to also hear that you don't even get flickers when you do alot of drawing as you say...? I have to try that. At the moment in the script I'm writing the ctlinfo thing works very fast as a rectangular tooltip on mouse hover or down -no problem dragging it around smoothly. But if you really think I can get away with redrawing EVERYTHING every mouse move then I might try that.

But the viewport thing I'm drawing over now is quite large, so I'm not sure. There are at least 4 layers of drawing 10,000+ pixels wide and although the drawing is fast, I've noticed on the extra large size drawings in my ctlviewport canvas, when I hover the ctlinfo over it, the first time around it takes a 2nd click and then sometimes lags behind the mouse movements a little, in comparison to say a 800 pixel drawing underneath. So it is instantaneous with the ctlinfo, but I can detect a bit of a hit with the ctlinfo poisitioning. I may do as you say and try drawing everything in order to get custom shapes and see how that performs.

Btw how do you get the requester itself to refresh? I get weirdness if I try to call requpdate() with no arguments. and why did you say no double calls to requpdate? is that for performance or does something weird happen?

thanks again for your help and ideas! :-)

BigHache
12-29-2012, 01:31 AM
Btw, do you know if Python offers us more choices with UI elements and interface stuff than LScript?

I thought I'd jump in fashionably late to this discussion. Right now Python looks to offer a bit less because XPanels isn't active (maybe 11.5? :hey:). As far as the actual UI elements go, from what I can tell all of those are the same. You're just limited with the layout of said elements. So you don't get pixel precision placement, you get align horizontal, align vertical. Makes it simple to layout a UI, but difficult to make a good UI.

sami
12-29-2012, 02:27 AM
I thought I'd jump in fashionably late to this discussion. Right now Python looks to offer a bit less because XPanels isn't active (maybe 11.5? :hey:). As far as the actual UI elements go, from what I can tell all of those are the same. You're just limited with the layout of said elements. So you don't get pixel precision placement, you get align horizontal, align vertical. Makes it simple to layout a UI, but difficult to make a good UI.

Thanks, good to know. It's looking more and more like I'll pass on Python until it's mature and stick with LScript and .p plugins for now... While I get that something standard like Python needs to be in LW, its execution so far doesn't sound to be especially worthy of attention. Hopefully this state of affairs will improve.

BigHache
12-29-2012, 03:27 PM
Thanks, good to know. It's looking more and more like I'll pass on Python until it's mature and stick with LScript and .p plugins for now... While I get that something standard like Python needs to be in LW, its execution so far doesn't sound to be especially worthy of attention. Hopefully this state of affairs will improve.

Yeah that makes sense. Since I didn't get going with LScript or compiled plug-ins I figured I'd spend the time now getting up to speed with what is available in Python.