Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Toolkit Pro
  New Posts New Posts RSS Feed - Disabling Vector
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Disabling Vector

 Post Reply Post Reply
Author
Message
navap View Drop Down
Groupie
Groupie
Avatar

Joined: 11 June 2019
Location: India
Status: Offline
Points: 12
Post Options Post Options   Thanks (0) Thanks(0)   Quote navap Quote  Post ReplyReply Direct Link To This Post Topic: Disabling Vector
    Posted: 17 September 2021 at 9:01am

I am trying to use xaml icons in command bar for my application.Previously I have used bitmap images for my ribbon bar , now I am trying to replace them with xaml icons. I have followed the codejock sample "CommandBarIcons" . I have following queries 

1. How do I disable this vector icon ? I have tried using below method , but I am not able to disable the icon. Is there any other call which I am missing ?
XTPImageManager()->SetVectorIcon(_T("RT_XAML"), IDR_XAML_ICON_DISABLED_SAVEALL, ID_FILE_SAVEALL, XTP_DPI_X(16), xtpImageDisabled);
2. Also is there any method which automatically disables the icon , like in bitmap image (which doesn't require any gray-image). 

Thanks,
Navap
Back to Top
astoyan View Drop Down
Admin Group
Admin Group
Avatar

Joined: 24 August 2013
Status: Offline
Points: 250
Post Options Post Options   Thanks (1) Thanks(1)   Quote astoyan Quote  Post ReplyReply Direct Link To This Post Posted: 18 September 2021 at 9:43pm
Setting an icon with xtpImageDisabled only adds that image into the image collection and tells it that it's associated with a disabled state of a control where it will be used in, but it does not make it to use the disabled icon right away. Whenever a command bar button is in disabled state its paint manager will try to obtain and draw an xtpImageDisabled icon.

And there is no method to make a disabled icon automatically.
Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 435
Post Options Post Options   Thanks (1) Thanks(1)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 19 September 2021 at 12:12am
My approach to solving this was to hack together some code that loads the XAML icon from resources and replaces any colors it uses with a light shade of gray. It is then stored in the image list for use by the "disabled" state.

Yeah, it's ugly - but preferable to creating and storing all the disabled vector variants separately.
Back to Top
navap View Drop Down
Groupie
Groupie
Avatar

Joined: 11 June 2019
Location: India
Status: Offline
Points: 12
Post Options Post Options   Thanks (0) Thanks(0)   Quote navap Quote  Post ReplyReply Direct Link To This Post Posted: 20 September 2021 at 8:54am
Thanks for the response . I am able to enable/disable the icon when command bar button state is changed . However my concern is that I have to maintain 4 sets of icons (normal-large, normal-small, disabled-large, disabled-small) if I have to go with vector icons, previously i.e. while using bmp icons it was only 2 sets of icons (large and small). 

I am trying to understand if there any better way to handle this. Loading file and changing its attributes programmatically is the best logic I could come across. 
Thanks,
Navap
Back to Top
dbrookes View Drop Down
Groupie
Groupie


Joined: 30 August 2019
Location: Australia
Status: Offline
Points: 64
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbrookes Quote  Post ReplyReply Direct Link To This Post Posted: 20 September 2021 at 9:15pm
I do a similar thing to markr, except at pre-compile time. I have a powershell script that runs over the XAML XML and grayscales any colours to create disabled variants of icons.

All my icons are stored in a tar gz archive that I load and create vector icon handles at runtime. I don't store icons in a resource DLL.

I guess it depends how many icons your dealing with whats worth it for you. If you haven't got a large number of icons its probably fine to grab the XAML from your resource DLL and to generate disabled variants at runtime. 
Product: ToolkitPro v19.1.0
OS: Windows 10
Language: C++ (VS2019)
Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 435
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 24 September 2021 at 6:35pm
> If you haven't got a large number of icons its probably fine to grab the XAML...

More icons = better software Shocked
Back to Top
Pesci7 View Drop Down
Newbie
Newbie
Avatar

Joined: 27 January 2021
Location: Italy
Status: Offline
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote Pesci7 Quote  Post ReplyReply Direct Link To This Post Posted: 29 September 2021 at 6:20am
Is it better lo load icons from an external file instead of from resources?

Actually I had to add a splash screen on startup because of initial icons loading.

Any advice?
Thanks
Product: Xtreme ToolkitPro (20.1.0)
Platform: Windows 10 (x64)
Language: Visual Studio 2019 (C++)
Back to Top
dbrookes View Drop Down
Groupie
Groupie


Joined: 30 August 2019
Location: Australia
Status: Offline
Points: 64
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbrookes Quote  Post ReplyReply Direct Link To This Post Posted: 06 October 2021 at 6:10am
There are benefits but also downsides. A benefit being avoiding have to add resource ids and so on for each icon, icon size and icon state. It is more work to setup loading from an external source. You have to map those to command ids at some point. We do have a resource DLL of course full of all the usual stuff, just not our icons. I doubt there is a big performance difference one way or the other. If I had to guess resources would be faster. Recently I found for this use case that .tar.gz is a fair bit faster than .zip with similar compression so switched to that.

As for vector icon loading it self. I too found that the performance of that can be a problem. We added around 4 seconds to our loading time when we moved to using vector icons. Not to mention around ~400mb more initial memory usage. We do have quite a lot of icons so are probably an outlier. Around 1200 icons total, each with a small and large, and with a normal and disabled state. So that makes around 5000 icon handles to load. Loading all that markup takes a lot of time.

You can save a little bit of time by minifying your XAML at pre-compile time but that'll only get you so far.

One thing I tested out was loading these on a worker thread but this stuff is just generally not thread safe. This is a bad idea.

Here is a patch someone might find interesting...

CXTPImageManagerVectorImageHandles actually already keep a copy of the XAML in their serialization data buffer. Piggy backing off of this we can delay building the markup UI element until we first try and draw the vector icon rather than immediately. If you have a ribbon like we do this means icons are built as they become visible when switching tabs. Building a tab worth of icons is quick enough its not noticeable. Similarly the disabled icon for things won't be built until they are needed. This took our loading time from 4 seconds to around 27ms and took our initial memory usage way down. That memory usage grows over time as icons are built on demand.

This delayed markup building idea can be used for markup list boxes as well by the way if you have a very large number of items to deal with. This only works for fixed height owner draw though since we can't measure the markup if it isn't built for variable height owner draw. The former is better for performance usually anyway.
Product: ToolkitPro v19.1.0
OS: Windows 10
Language: C++ (VS2019)
Back to Top
Pesci7 View Drop Down
Newbie
Newbie
Avatar

Joined: 27 January 2021
Location: Italy
Status: Offline
Points: 9
Post Options Post Options   Thanks (0) Thanks(0)   Quote Pesci7 Quote  Post ReplyReply Direct Link To This Post Posted: 06 October 2021 at 12:39pm
Should I change SetVectorIcon, SetVectorDisabledIcon, ... methods to call CreateDelayedMarkupHandle instead of CreateMarkupHandle to use this patch?


Product: Xtreme ToolkitPro (20.1.0)
Platform: Windows 10 (x64)
Language: Visual Studio 2019 (C++)
Back to Top
dbrookes View Drop Down
Groupie
Groupie


Joined: 30 August 2019
Location: Australia
Status: Offline
Points: 64
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbrookes Quote  Post ReplyReply Direct Link To This Post Posted: 20 December 2021 at 12:47am
I think so... haven't tried that to be honest since I don't load from resources. I call CreateDelayedMarkupHandle myself and then call the image manager SetVectorIcon with that handle.
Product: ToolkitPro v19.1.0
OS: Windows 10
Language: C++ (VS2019)
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 786
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 20 January 2022 at 4:26pm
Hi dbrookes,

I'm looking into XAML icons. I have code that loads icons on demand from either individual files on disk or via resource DLLs. I use the LoadBitmapFromFile method. All I found in CJ was SetVectorIcon APIs that just load via a resource.

You mentioned loading XAML icons yourself. Did you find an API to use to load XAML from files?

Oh, and I liked your comment about delayed loading. We have our own ribbon class so it might be handy to load icons when a tab is activated and not just load all them when we start up. Though we build ribbons for other reasons than for being displayed such as for some customization code and for a 3D controller that likes to obtain our command images as it can add commands to its own UI (some of them have fancy screens). But, I can "force load" images if need be. I'll keep your comment in mind if I start to see a slowdown.
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 786
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 20 January 2022 at 4:29pm
Hi dbrookes,

Regarding my last question: XTPCreateReadOnlyFileStream perhaps? Looks promising.
Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 435
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 20 January 2022 at 6:40pm
Hi rdhd,

I load XAML icons "on demand" (during containing window construction) from program resources and haven't observed much of a delay at all.

My approach is to parse the icon XAML and replace all instances of "fill" and "stroke" attributes with dimmed versions of the target colors. For the dimming, I first convert the color to grayscale and then "lighten" it by 50%. The resulting disabled XAML images are then cached in an XTP image manager instance.

Just wanted to share what's been working well for me in case it helps.

- Mark
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 786
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 21 January 2022 at 9:24am
Hi markr,

I was thinking that if we add support for xaml icons, I would want to load from files or resources. Not because of a performance issue but because it can be more dynamic. Image creation people can just drop a file on disk and cause a load or reload to occur in our app and they can view the results right away. No coding needed, no build or waiting for a build to deploy. I do this for BMP and PNG now and the image creator just has to go to our options dialog and change color theme (I support images on a per color theme basis too). I discover the ID of the resource by using a naming convention that has the ID included in the name. Filenames have the ID and when adding a resource using Visual Studio, one just goes to the properties window and selects the auto-generated ID and types something like (quotes included) "image12345_16". The "16" is irrelevant to my code as I just care what is between "image" and "_". Filenames follow the same pattern - image12345_16.png, image12345_32.png ...

I also auto-scale images using WIC for cases where a user is running at a high DPI like 200% on a 4k monitor. If any scaled image looks bad, our team just creates, say a 64x64 version of an image and drops it on disk (image12345_64.png), or adds it to the resource DLL and forces the reload.

I haven't tried using XTPCreateReadOnlyFileStream yet to see if that's the way to load a XAML icon from disk but it appears that it should work.

As for dimming, I don't supposed you tried setting an opacity to some low value like 0.3? I've been playing around with that and it shows promise. Images "fade" out quite well - so far. Ok, so I only have one simple image taken from the CommandBarIcons sample so its very simple ...
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 786
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 21 January 2022 at 1:04pm
I have it - CXTPImageManager::OleLoadVectorIcon. The "Ole" threw me when I was searching their files. Looks like this is the highest level call I can make analogous to the API I use to load an image from file and give it to the image manager.
Back to Top
dbrookes View Drop Down
Groupie
Groupie


Joined: 30 August 2019
Location: Australia
Status: Offline
Points: 64
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbrookes Quote  Post ReplyReply Direct Link To This Post Posted: 23 January 2022 at 10:09pm
Hi rdhd.

The way I do it is have an archive of all of the .xaml files. I used to use .zip but found .tar.gz with libarchive to be much faster for this. I open this archive once on startup and read all of the .xaml out of it into strings. I then use CXTPImageManagerVectorImageHandle CreateMarkupHandle, actually I use my patched CreateDelayedMarkupHandle function I mentioned above. By the way that likely only helps if you have a very large number of icons to load. I'm loading around 1200, but each have small and large, normal and disabled. So its actually around 5000 icons being loaded.

I think using the IStream version of these should work fine if you want to read directly from a file stream. If you want to pre-process the .xaml though to do something like creating disabled variants it may be better to read the file into memory first, do what you want and then pass the string to CreateMarkupHandle.

I mentioned above I think, but I generate disabled icons at pre-compile time with a powershell script. For grayscaling I use the following function.
function Grayscale($brightnessFactor, [ref]$colour) {
    # Convert input colour to grayscale.
    $gray = $colour.Value.R * 0.299 + $colour.Value.G * 0.587 + $colour.Value.B * 0.114
    # Scale by brightness factor.
    $gray = [System.Math]::Pow(($gray / 255), $brightnessFactor) * 255
    $gray = [System.Convert]::ToInt32($gray) # Floor
    $colour.Value = [System.Drawing.Color]::FromArgb($colour.Value.A, $gray, $gray, $gray)
}

Shouldn't be too hard to do the same thing in C++. For light themes I use a brightness factor of 0.5, for dark themes I use a brightness factor of 1.25.

By the way. The names of my icons are actually the id names of the command. e.g. ID_FILE_NEW.xaml. I have a pre-compile awk script that parses CommandsRes.h into a header file that contains the id name strings and id number paired together. That way we can map the file name to the id of the command at runtime.

Regards,
Daniel.
Product: ToolkitPro v19.1.0
OS: Windows 10
Language: C++ (VS2019)
Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 435
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 24 January 2022 at 3:31am
> I don't supposed you tried setting an opacity to some low value like 0.3.

I did, and found the results unsatisfactory. I use a grayscale conversion function very similar to what Daniel shared in this thread, then also adjust the brightness a bit.

Opacity doesn't alter the colors, so it never actually looks "disabled" to me.
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 786
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 24 January 2022 at 11:40am
Yep. Opacity will fade them out but the hue remains. Just wondered if that was enough to indicate disabled. Of course some images can be grayscale themselves too.

If we end up supporting XAML, I'll be tempted to just change the CJ markup code if possible. I usually use the NTSC color to grayscale conversion method so its quite easy and fast. Better than SECAM which we always joked meant "Something essentially contradictory to the American method).
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.063 seconds.