Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to make a semi-transparent window?  (Read 10328 times)

0 Members and 2 Guests are viewing this topic.

Temp

  • Newbie
  • *
  • Posts: 3
    • View Profile
How to make a semi-transparent window?
« on: November 14, 2014, 08:16:14 am »
Hi!

I've was trying to find a solution for this problem all around but still couldn't find it. Tried a bunch of stuff but they all result in the same window with opaque colors(Might be because I'm still a noob  :'().

So what I want to do it have a borderless window without any title bar and stuff and have the window itself also be  semi-transparent or may be have a repeating semi-transparent image. Something similar to rainmeter skins.. I have my base code below. Let me know if you want to clear something out. Thanks!

#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600), "", sf::Style::None);
        sf::Vector2i grabbedOffset;
        sf::Texture texture;
        if (!texture.loadFromFile("BlackBG.png", sf::IntRect(10, 10, 32, 32)))
        {
                std::cout << "count not load image" << std::endl;
        }
        sf::Sprite sprite;
        sprite.setTexture(texture);


        bool grabbedWindow = false;
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                        else if (event.type == sf::Event::KeyPressed)
                        {
                                if (event.key.code == sf::Keyboard::Escape)
                                        window.close();
                        }
                        else if (event.type == sf::Event::MouseButtonPressed)
                        {
                                if (event.mouseButton.button == sf::Mouse::Left)
                                        grabbedOffset = window.getPosition() - sf::Mouse::getPosition();
                        }
                }
               
                sprite.setColor(sf::Color(255, 255, 255, 128)); // half transparent

                window.clear(sf::Color(0, 200, 0, 10));

                grabbedWindow = sf::Mouse::isButtonPressed(sf::Mouse::Left);
                if (grabbedWindow)
                        window.setPosition(sf::Mouse::getPosition() + grabbedOffset);

                window.display();
        }
}
 

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: How to make a semi-transparent window?
« Reply #1 on: November 14, 2014, 09:32:59 am »
For starters you are never drawing the sprite you create. Secondly, you are setting the color the the same thing every frame which is unnecessary.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: How to make a semi-transparent window?
« Reply #2 on: November 14, 2014, 07:07:58 pm »
I'm sure this has come up before and I believe the answer was that you can't create transparent windows using just SFML. If you require this, you'll need to drop into a lower level and use specific OS functions.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Temp

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: How to make a semi-transparent window?
« Reply #3 on: November 15, 2014, 02:52:51 am »
Awww.... Well I hope there is someone here who had a bit of code example to show me who they handled this problem.. But thanks for the reply!!

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Re: How to make a semi-transparent window?
« Reply #4 on: November 15, 2014, 12:01:14 pm »
For me semi-transparent can mean either a partly visible window, or a window that you can see through.
So in my text below I will speak about non-rectangular windows to refer to the former and semi-transparent for the latter.

I wrote some code last year that creates a non-rectangular window (without borders or title bar).

I haven't had the time to support OS X or make the windows semi-transparent yet though.

But I have uploaded the code now so if you are looking for an example for non-rectangular windows on Windows and Linux then you can look here: https://github.com/texus/TransparentWindows

But I think it wasn't too hard to make a window semi-transparent on Windows, I though I once had it working with only adding a few lines to that code. But I don't have it anymore and I currently don't have the time to look into it. But maybe the code can still help.

Edit:
I have added transparency to the code, but only for Windows.
« Last Edit: November 15, 2014, 11:39:52 pm by texus »
TGUI: C++ SFML GUI

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: How to make a semi-transparent window?
« Reply #5 on: November 16, 2014, 02:35:09 am »
Not sure if you actually want your window to be transparent of if you want your window to be masked. If it's the former, this may help:

WINDOWS ONLY
I quickly threw together these functions that are based on Microsoft's documentation:
void makeWindowTransparent(sf::RenderWindow& window)
{
        HWND hwnd = window.getSystemHandle();
        SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
}
void makeWindowOpaque(sf::RenderWindow& window)
{
        HWND hwnd = window.getSystemHandle();
        SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
        RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
}
inline void setWindowAlpha(sf::RenderWindow& window, sf::Uint8 alpha = 255)
{
        SetLayeredWindowAttributes(window.getSystemHandle(), 0, alpha, LWA_ALPHA);
}

Here's an short, example program that shows these functions in use:
(click to show/hide)

This example program creates a window of a solid colour without any styles and makes it transparent. The window can be moved by clicking and dragging on any part of the window itself. The colour and transparency changes depending on whether or not the window is being dragged. You can close the program using the Escape key; you can also close it using other, standard closing methods.

In this example, I have commented the two lines that call the (Windows only) functions that modify the window's transparency. The example only uses two of the three functions. The third one (makeWindowOpaque), which is unused, allows you to reset the window back to normal if transparency is no longer needed.

It should also show a way to "grab" a window. I noticed that you ended up mixing real-time input and events. I would recommend not using real-time input to determine if the mouse button has been pressed for grabbing as it reads that it's pressed even outside of the window, making your application think it's dragging when it's not. Weirdly, it looks like you copied my previous example of dragging in another post and modified it to this  :P

Be aware that I used SetWindowLongPtr and GetWindowLongPtr, as suggested by the documentation, because they work for both 32-bit and 64-bit. Using SetWindowLong and GetWindowLong only works for 32-bit. See here.

Note: the sf::RenderWindow& parameter in the functions can be made const since it doesn't directly affect that object but I left the const off to show that the window it controls will be modified.
« Last Edit: November 16, 2014, 04:54:28 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Temp

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: How to make a semi-transparent window?
« Reply #6 on: November 17, 2014, 12:32:02 am »
Wow guys, thanks for the detailed replies!!

I can't really check these examples rihgt now but check them out as soon as I can. I was almost thinking of just using TideSDK to all the stuff but now i'll have to research some more about what I really need to use for my program.

Thanks again!