Changing the colour of a graphics object dynamically by RGB at runtime

This sounds like a simple objective but hard to achieve in practise unless I'm missing something.

I can easily place a graphics object on a page, and set its colour to any RGB value, at design time. I can even pre-configure several colour options and use an expression to pick one of them at runtime,

But how can I set an arbitrary colour at runtime?

The use case is simple: I need to show the colour of some lighting. The colour can change at runtime to any RGB combination (with R,G,B each being 8-bit UINTs). How can I show that colour on a graphics page? (Consider a slider each for R, G & B, and a box that shows the colour as the sliders are moved.)

The best I have come up with so far is to create my own ActiveX object to do it, although I'd really prefer not to do it outside Citect and especially not with something like ActiveX (it's 2022!). 

I'm having a discussion with support about it and figured it might be useful to see if anyone else has any clever ideas I haven't thought of!

In case it's relevant I need to show anything up to about 50 different colours on the same page simultaneously, and I need the resulting object to behave like other graphics objects (I need to be able to hide it, or to click on it to trigger a Cicode function, etc).

Parents
  • Hi Mark,

    Could you provide a little more detail as to what you are trying to change the colour of?

    • Fill colour of a vector object - e.g. rectangle?
    • Line colour
    • Gradient 'To' colour
    • Colour in a Fill animation set?
    • Background colour of a Fill Level?
    • Roughly how many objects on a page you would likely be wanting to change the colour properties of

    Unfortunately, there is no native functionality at the moment that allows full control of dynamically changing the colour of any colour property of any object at runtime via cicode.

    If you need to show a simple block of colour, then you could:

    • Write your own DLL that generates a BMP of the right colour, call from cicode, and DspBmp that on the screen...
    • Try your luck with an enhancement request. The team would need to understand exactly what and how much you plan to colour.. Depending upon scope, and alignment, an enhancement would most likely be associated to a new release only.

    bradley

  • Hi Bradley

    To answer your question: In an ideal world, just setting the fill colour of an object (rectangle or other shape) would be perfect. But I'll work with whatever works!

    In many cases the user will be selecting a colour using sliders so it needs to pretty responsive to the slider movement. And I need to be able to show about 50 distinct colours on the screen (ie 50 of these objects with distinct parameters) on screen at once.

    Unfortunately, there is no native functionality at the moment that allows full control of dynamically changing the colour of any colour property of any object at runtime via cicode.

    Not strictly true. I have some "working" code using a piece of text on a graphics page, using DspFont to create a font of the desired colour, and DspText to show some text in that font (setting both foreground and background to the same colour to create a filled box shape)

    However, (a) DspFont (and similar functions) are supposed to be obsolete v3/4 tools and I don't want to hitch my wagon to a solution that won't work in a couple of years, but more importantly (b) DspFont creates a new font handle for each unique font/colour/size combination and is limited to a maximum number of handles (its not documented but experimental evidence suggests 256). Since there's no way to delete (or change the colour of) old handles it makes for a great demo but falls down in actual use.

    It was getting that close that prompted me to ask here, as there may well be some other workaround I hadn't thought of. Such as:

    Write your own DLL that generates a BMP of the right colour, call from cicode, and DspBmp that on the screen

    Interesting idea, thanks. Not sure how quickly it would respond but I can look at it. (Support suggested using a .net component instead of ActiveX but I've not found any documentation on how that might work.)

    For now ActiveX is looking like my best option though.

    Try your luck with an enhancement request. The team would need to understand exactly what and how much you plan to colour.. Depending upon scope, and alignment, an enhancement would most likely be associated to a new release only.

    I should probably try this, if only because it seems crazy that this isn't trivial and I'm surprised that it isn't an issue for other people - but at the same time if it was I'm sure there'd already be a solution!

  • Perhaps a compromise?  4096 pre defined BMP's so 4 bits/colour resolution would perform well, and only require a folder to store them in?  The problem would be that it would only really support whatever shape you had them in.  A problem I see overall with this approach is that when you display the page, you need to refresh all of the animations manually with dspbmp.  Also, if someone else is changing the values, you'll need to have something monitoring them and updating the page near real time(?)
    Anyway, 4096 is quite a few colours:

Reply
  • Perhaps a compromise?  4096 pre defined BMP's so 4 bits/colour resolution would perform well, and only require a folder to store them in?  The problem would be that it would only really support whatever shape you had them in.  A problem I see overall with this approach is that when you display the page, you need to refresh all of the animations manually with dspbmp.  Also, if someone else is changing the values, you'll need to have something monitoring them and updating the page near real time(?)
    Anyway, 4096 is quite a few colours:

Children
  • Interesting idea, thanks.

    With the font handle limits I'd already considered reducing the bit depth (Side note: MakeCitectColour(R BITAND 192, G BITAND 192, B BITAND 192) does NOT do what you expect since MakeCitectColour() is a label not a function, and the way it's defined doesn't expand properly; it also breaks if any of R,G,B aren't integers!)

    Edited to add: I think the realistic limit for font colours would be 2 bits per colour which isn't enough anyway.

    4096 is plenty of colours for our purposes, it's the responsiveness of dragging a slider and loading the appropriate bitmap that would concern me.

  • I couldn't help myself - So the plot functions don't seem to have the same limitation - here are 32768 generated colours.  Fair to say I almost lost the plot getting this working.

    FUNCTION lotsacolours()
    INT r,g,b, hAn, hPlot, hCol, nRet
    FOR r = 0 TO 31 DO
    FOR g = 0 TO 31 DO
    FOR b = 0 TO 31 DO
    hAn = DspAnNew(r*3+g*3*31, b*32)
    hCol = MakeCitectColour(r*8,g*8,b*8)
    TraceMsg("r: " + R:# + " g: " +G:# + " B: " + B:# + " = " + HexToStr(HcOL,8))
    hPlot = PlotOpen(hAn, "Display",1)
    //nRet = PlotMarker(hPlot, 7, hCol, 0, 1, 0, 0) //this works too but the markers are too big
    nRet = PlotDraw(hPlot, 3, 0, hCol, 3, hCol, 0, 0, 20, 20)
    PlotClose(hPlot)
    END
    END
    END
    END

  • I couldn't help myself - So the plot functions don't seem to have the same limitation - here are 32768 generated colours.  Fair to say I almost lost the plot getting this working.

    Wow, thanks!

    It does have the feel of a nice little Citect challenge - I've spent way more time on this than is probably justified (and I've had a similar effort from our local support) but neither of us came up with your solution.

    I'll go and experiment!

    I feel bad that you won't have any excuse for more plot puns though! Or maybe you're just happy to draw a line under it...

  • Hmm this whole thing has turned into a bit of a kudzu plot.