# Showing/hiding images with plugin



## Plastburk (Jan 13, 2013)

Hello everyone,
I'm trying to create a plugin for my stream, but I'm having some problems with showing and hiding images.

Basically, it's supposed to do two things, the first is to change the text of an element, and the second is to show and hide a few images.
Changing the text was simple:

```
// Update text
ImageSource *textImageSource = API->GetSceneImageSource(TEXT("StatusText"));

XElement* globalSourceElements = API->GetGlobalSourceListElement();
XElement* textElement = globalSourceElements->GetElement(TEXT("StatusText"));
XElement* data = textElement->GetElement(TEXT("data"));
data->SetString(TEXT("text"), messageText);

if (textImageSource)
	textImageSource->SetString(TEXT("text"), messageText);
```
My idea to hide an image was to set it's opacity to 0, unfortunately, doing that wasn't quite as simple, this is what I've got right now:

```
// Update image
ImageSource *imageImageSource = API->GetSceneImageSource(TEXT("StatusImage1"));

XElement* globalSourceElements = API->GetGlobalSourceListElement();
XElement* imageElement = globalSourceElements->GetElement(TEXT("StatusImage1"));
XElement* data = imageElement->GetElement(TEXT("data"));
data->SetInt(TEXT("opacity"), opacityValue);

if (imageImageSource)
	imageImageSource->UpdateSettings();
```
The problem is that it doesn't change the opacity "live", it only changes it in the configuration, so if you restart the stream, it will work, or if you open the properties of the image you'll see that the opacity is changed, but it wont update while the stream is running.

Obviously, I'm doing something wrong, but I'm not quite sure what, anyone has any idea how I could make this work?

Thanks!


----------



## dodgepong (Jan 13, 2013)

I believe the latest test version (467 test 2) has support for monitoring image changes live. If you add an image, there is a checkbox in properties called "Check for changes" and if the image is changed at all, OBS will update right away. I think if the image is deleted/renamed, then the image disappears from OBS until another image of the same name is put back (you can experiment with this).

If you use text sources that pull their text from a .txt file, then I don't think you even need to write an OBS plugin for what it sounds like you are doing...just a standalone program that manages .txt files and images.


----------



## Plastburk (Jan 13, 2013)

dodgepong said:
			
		

> I believe the latest test version (467 test 2) has support for monitoring image changes live. If you add an image, there is a checkbox in properties called "Check for changes" and if the image is changed at all, OBS will update right away. I think if the image is deleted/renamed, then the image disappears from OBS until another image of the same name is put back (you can experiment with this).


Interesting, I'll try that.



			
				dodgepong said:
			
		

> If you use text sources that pull their text from a .txt file, then I don't think you even need to write an OBS plugin for what it sounds like you are doing...just a standalone program that manages .txt files and images.


I know, but since I needed to make a plugin for some other stuffs as well, I figured I'd just add that too.


----------



## dodgepong (Jan 14, 2013)

Out of curiosity, what all will this plugin do?


----------



## Plastburk (Jan 14, 2013)

Basically, it's a personalized plugin for my stream, it will do two things; the first is to check what programs are currently running what they're doing and from that swap to the correct scene to reflect that, this part is already done.
The second thing I want is to show a status message on top of the screen, but just putting a flat text there looks really ugly, so I have a background graphic for it, the problem comes when the message is empty, or multiple lines, when that happens I want to either hide the background completely, or swap it for a bigger one if it's multiple lines, which is where the plugin comes it.


----------



## Jim (Jan 14, 2013)

You want "textOpacity" rather than "opacity".  I apologize about the design, it was kind of a last minute thing and not necessarily exactly the way I would prefer to have implemented it I think.  You don't need to call UpdateSettings either if you use this.

I'm going to create development forum I think.


----------



## Plastburk (Jan 14, 2013)

Are you sure? That doesn't seem to do anything at all. Or maybe I'm doing something else wrong, could you give me a simple example or something?


----------



## Jim (Jan 14, 2013)

ah wait, I'm sorry, I misread the code.

Well UpdateSettings should cause it to trigger an update.  Make sure you're getting the right item.  You can also use ImageSource::Set[Int/Float/String/etc] to set something in real time.  Make sure the name is correct as well


----------



## Plastburk (Jan 14, 2013)

Jim said:
			
		

> You can also use ImageSource::Set[Int/Float/String/etc] to set something in real time.


As you can see from my code, that's what I did to change the text, but it doesn't seem to work on images. Looking at the code, it's not really that strange, TextOutputSource has overrides for the Set[Int/Float/String/etc] methods, but BitmapImageSource does not.



			
				Jim said:
			
		

> Well UpdateSettings should cause it to trigger an update.


Yeah, looking at the code, that's what I expected it should do, but it doesn't seem to actually do anything. The same problem happens with TextOutputSource, if I replace the call that did work to change the text

textImageSource->SetString(TEXT("text"), messageText);

with

textImageSource->UpdateSetting();

i'd assume that would work too, but it doesn't.
Unfortunately, I'm not amazingly good at C++, so I can't for the life of me figure out why the call to UpdateSettings does absolutely nothing, maybe you could help?


----------



## Jim (Jan 14, 2013)

have you run it through a debugger at all?  you could step into the functions and see if they're working okay.  I could look as well if you wish.


----------



## Plastburk (Jan 14, 2013)

Yeah, that's pretty much what I mean with not being that good at C++, I've got no idea how to use a debugger when workings with dlls, I'm obviously using the debugger wrong, but it just never seems to work correctly for me. I'd really appreciate if you could look into it for me.


----------



## Jim (Jan 14, 2013)

Well come on chat some time and I wouldn't mind taking a look.


----------



## Jim (Jan 14, 2013)

hey, I'm back, really sorry about not really responding promptly earlier.

I'm dumb, I should have noticed what you were doing from the source, API->GetGlobalSourceListElement() is for global sources only.

What you want to do is API->GetSceneElement(), and then get the element data from that.  ex:


```
XElement* sceneElement = API->GetSceneElement();
        if(sceneElement)
        {
            XElement *sources = sceneElement->GetElement(TEXT("sources"));
            if(sources)
            {
                XElement* imageElement = sources->GetElement(TEXT("StatusImage1"));
                if(imageElement)
                {
                    XElement* data = imageElement->GetElement(TEXT("data"));
                    if(data)
                    {
                        data->SetInt(TEXT("opacity"), opacityValue);

                        opacityValue = (opacityValue + 5) % 100;

                        ImageSource *imageImageSource = API->GetSceneImageSource(TEXT("StatusImage1"));
                        if (imageImageSource)
                        {
                            imageImageSource->UpdateSettings();
                            //imageImageSource->SetInt(TEXT("opacity"), opacityValue);
                        }
                    }
                }
            }
        }
```

wow I designed this API badly.


----------



## Plastburk (Jan 15, 2013)

Ahh, thank you very much, that worked fine! :)

The reason that I used API->GetGlobalSourceListElement() is because I was actually using global sources, that wasn't really a requirement though, I mostly used it because it was convenient to use, so I simply stopped using it and this worked fine, thought I'm a bit curious as to why it wouldn't work with global sources, shouldn't they be linked somehow?


----------



## Jim (Jan 15, 2013)

well, I don't think I've implemented a method for getting the actual global source ImageSource object yet in the API.  I should put that in.  however, any of the member functions you use on an instance of it in the scene will affect the global source though, so you should be fine that way as well.


----------

