writing dynamic text on wxSplashWindow possible? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

writing dynamic text on wxSplashWindow possible?

Post by evstevemd »

Hi,
Is it possible to write to splash screen mesaages of what currently app is doing. something like adobe apps and many others does?

loading file xyz....
loading plugins...
loading blahbla
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: writing dynamic text on wxSplashWindow possible?

Post by Auria »

Not sure that the factory one allows doing that, but it should be easy to create your own splashscreen
"Keyboard not detected. Press F1 to continue"
-- Windows
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: writing dynamic text on wxSplashWindow possible?

Post by evstevemd »

Auria wrote:Not sure that the factory one allows doing that, but it should be easy to create your own splashscreen
Hi Auria,
almost happy easter :)
I need pointers to even possibilities. I'm using custom splash screen and I wonder if there is any way I could write text on bitmap.
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: writing dynamic text on wxSplashWindow possible?

Post by Auria »

Writing text on a wxBitmap is easily done by creating a wxMemoryDC on that bitmap
"Keyboard not detected. Press F1 to continue"
-- Windows
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: writing dynamic text on wxSplashWindow possible?

Post by evstevemd »

Auria wrote:Writing text on a wxBitmap is easily done by creating a wxMemoryDC on that bitmap
Last question for now. Can that text be erase/overwritten
Sorry for late reply...holidays holidays :)
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: writing dynamic text on wxSplashWindow possible?

Post by Auria »

evstevemd wrote:
Auria wrote:Writing text on a wxBitmap is easily done by creating a wxMemoryDC on that bitmap
Last question for now. Can that text be erase/overwritten
Sorry for late reply...holidays holidays :)
just load the original bitmap again and the text will be gone...
"Keyboard not detected. Press F1 to continue"
-- Windows
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: writing dynamic text on wxSplashWindow possible?

Post by evstevemd »

Auria wrote:
evstevemd wrote:
Auria wrote:Writing text on a wxBitmap is easily done by creating a wxMemoryDC on that bitmap
Last question for now. Can that text be erase/overwritten
Sorry for late reply...holidays holidays :)
just load the original bitmap again and the text will be gone...
I have tried that but it does not work! Here is a code I do use:

Code: Select all

HSplashScreen::HSplashScreen(wxWindow* parent, wxBitmap& bitmap):wxSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT, 6000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE|wxSTAY_ON_TOP) {
	 m_frame = parent;
	 m_bitmap = bitmap;
}

HSplashScreen::~HSplashScreen() {
	m_frame->Show(true);
}

void HSplashScreen::WriteMessage(wxString& message){
	 // Create a memory DC
     wxMemoryDC theDC;
     theDC.SelectObject(m_bitmap);
	 wxPoint pt = wxDefaultPosition;
	 theDC.DrawText(message, pt); 
}
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: writing dynamic text on wxSplashWindow possible?

Post by Auria »

I don't see anywhere in your code that you are trying to remove the text.

Try something like...

Code: Select all

HSplashScreen::HSplashScreen(wxWindow* parent, wxBitmap& bitmap):wxSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT, 6000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE|wxSTAY_ON_TOP) {
    m_frame = parent;
    m_original_bitmap = bitmap;
    m_bitmap = bitmap.GetSubBitmap(wxRect(0, 0, m_original_bitmap.GetWidth(), m_original_bitmap.GetHeight()));
}

HSplashScreen::~HSplashScreen() {
   m_frame->Show(true);
}

void HSplashScreen::WriteMessage(wxString& message){
    // Create a memory DC
    m_bitmap = m_original_bitmap.GetSubBitmap(wxRect(0, 0, m_original_bitmap.GetWidth(), m_original_bitmap.GetHeight()));
     wxMemoryDC theDC;
     theDC.SelectObject(m_bitmap);
    wxPoint pt = wxDefaultPosition;
    theDC.DrawText(message, pt);
}
Notice the 'GetSubBitmap' trick that comes from the docs. Normally wx uses reference-counted COW for bitmaps, so you need GetSubBitmap to get a real copy
"Keyboard not detected. Press F1 to continue"
-- Windows
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: writing dynamic text on wxSplashWindow possible?

Post by evstevemd »

Auria wrote:I don't see anywhere in your code that you are trying to remove the text.

Try something like...

Code: Select all

HSplashScreen::HSplashScreen(wxWindow* parent, wxBitmap& bitmap):wxSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT, 6000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE|wxSTAY_ON_TOP) {
    m_frame = parent;
    m_original_bitmap = bitmap;
    m_bitmap = bitmap.GetSubBitmap(wxRect(0, 0, m_original_bitmap.GetWidth(), m_original_bitmap.GetHeight()));
}

HSplashScreen::~HSplashScreen() {
   m_frame->Show(true);
}

void HSplashScreen::WriteMessage(wxString& message){
    // Create a memory DC
    m_bitmap = m_original_bitmap.GetSubBitmap(wxRect(0, 0, m_original_bitmap.GetWidth(), m_original_bitmap.GetHeight()));
     wxMemoryDC theDC;
     theDC.SelectObject(m_bitmap);
    wxPoint pt = wxDefaultPosition;
    theDC.DrawText(message, pt);
}
Notice the 'GetSubBitmap' trick that comes from the docs. Normally wx uses reference-counted COW for bitmaps, so you need GetSubBitmap to get a real copy
Nothing works, in fact even text is not written. I suspect the points from wxDefaultPosition (-1,-1) is out of bitmap.
Is there a way to get coordinates that are within wxSplashScreen image?
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: writing dynamic text on wxSplashWindow possible?

Post by PB »

I am probably overlooking something here but I don't see you setting the updated bitmap (with text) to the window actually doing the splash screen paitning and asking it to redraw itself? :S

I tried the simplest implementation possible, it seems to work properly (on Windows XP)

Code: Select all

#include <wx/wxprec.h>

#ifndef WX_PRECOMP
    // Include your minimal set of headers here, or wx.h
#include <wx/wx.h>
#endif

#include <wx/stdpaths.h>
#include <wx/filename.h>
#include <wx/splash.h>

class TextSplashScreen : public wxSplashScreen
{
public:
    TextSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds, wxWindow* parent)
        : wxSplashScreen (bitmap,  splashStyle, milliseconds, parent, wxID_ANY)
    {        
        wxASSERT(bitmap.IsOk());

        m_noTextBitmap = bitmap;
    }

    void SetText(const wxString& text)
    {                
        wxBitmap bitmap(m_noTextBitmap);        
        
        if (!text.empty()) {
            wxMemoryDC memDC;
            
            memDC.SelectObject(bitmap);
            
            memDC.SetBackgroundMode(wxTRANSPARENT);
            memDC.SetTextForeground(*wxRED);        
            memDC.DrawText(text, 0, 0);
            
            memDC.SelectObject(wxNullBitmap);
        }
        m_window->SetBitmap(bitmap);
        m_window->Refresh();
        m_window->Update();
    }
private:
    wxBitmap m_noTextBitmap;
};

class MyFrame : public wxFrame
{
public:
    MyFrame()
        : wxFrame(NULL, wxID_ANY, _("Test"))
    {        
        
        wxBitmap bitmap(wxFileName(wxStandardPaths::Get().GetDataDir(), "horse.bmp").GetFullPath(), wxBITMAP_TYPE_BMP);
        if (bitmap.IsOk()) {
            TextSplashScreen* splash = new TextSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT,
                6000, NULL);

            splash->SetText(wxT("Loading configuration..."));
            wxMilliSleep(1500);
            splash->SetText(wxT("Loading textures..."));
            wxMilliSleep(1500);
            splash->SetText(wxT("Doing whatever..."));            
        }
    }	
};

/**** MyApp ****/
class MyApp : public wxApp
{
public:	
	virtual bool OnInit()
	{
		if (!wxApp::OnInit())
			return false;       	

        wxInitAllImageHandlers();        

        MyFrame* frame = new MyFrame();
        frame ->Show();

        return true;
	}
};

IMPLEMENT_APP(MyApp)
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: writing dynamic text on wxSplashWindow possible?

Post by evstevemd »

PB wrote:I am probably overlooking something here but I don't see you setting the updated bitmap (with text) to the window actually doing the splash screen paitning and asking it to redraw itself? :S

I tried the simplest implementation possible, it seems to work properly (on Windows XP)

Code: Select all

#include <wx/wxprec.h>

#ifndef WX_PRECOMP
    // Include your minimal set of headers here, or wx.h
#include <wx/wx.h>
#endif

#include <wx/stdpaths.h>
#include <wx/filename.h>
#include <wx/splash.h>

class TextSplashScreen : public wxSplashScreen
{
public:
    TextSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds, wxWindow* parent)
        : wxSplashScreen (bitmap,  splashStyle, milliseconds, parent, wxID_ANY)
    {        
        wxASSERT(bitmap.IsOk());

        m_noTextBitmap = bitmap;
    }

    void SetText(const wxString& text)
    {                
        wxBitmap bitmap(m_noTextBitmap);        
        
        if (!text.empty()) {
            wxMemoryDC memDC;
            
            memDC.SelectObject(bitmap);
            
            memDC.SetBackgroundMode(wxTRANSPARENT);
            memDC.SetTextForeground(*wxRED);        
            memDC.DrawText(text, 0, 0);
            
            memDC.SelectObject(wxNullBitmap);
        }
        m_window->SetBitmap(bitmap);
        m_window->Refresh();
        m_window->Update();
    }
private:
    wxBitmap m_noTextBitmap;
};

class MyFrame : public wxFrame
{
public:
    MyFrame()
        : wxFrame(NULL, wxID_ANY, _("Test"))
    {        
        
        wxBitmap bitmap(wxFileName(wxStandardPaths::Get().GetDataDir(), "horse.bmp").GetFullPath(), wxBITMAP_TYPE_BMP);
        if (bitmap.IsOk()) {
            TextSplashScreen* splash = new TextSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT,
                6000, NULL);

            splash->SetText(wxT("Loading configuration..."));
            wxMilliSleep(1500);
            splash->SetText(wxT("Loading textures..."));
            wxMilliSleep(1500);
            splash->SetText(wxT("Doing whatever..."));            
        }
    }	
};

/**** MyApp ****/
class MyApp : public wxApp
{
public:	
	virtual bool OnInit()
	{
		if (!wxApp::OnInit())
			return false;       	

        wxInitAllImageHandlers();        

        MyFrame* frame = new MyFrame();
        frame ->Show();

        return true;
	}
};

IMPLEMENT_APP(MyApp)
Thanks PB, that works fine.
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
Buzz
Earned a small fee
Earned a small fee
Posts: 10
Joined: Sun May 27, 2007 5:10 pm
Location: Belgium

Re: writing dynamic text on wxSplashWindow possible?

Post by Buzz »

Hi,

Three years later, I'd like to continue on this thread.

The code sample provided by PB works fine on Windows and Linux, but on OSX, the text is not updated at each call to SetText().
It looks like the bitmap and text are only updated when I leave the wxFrame's constructor.

Did anybody succeed to make it work on OSX ? or am I missing something somewhere ?

I'm running wxCOCOA 3.0.0 on OSX 10.10.1

Thanks for any clue.
Buzz.
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: writing dynamic text on wxSplashWindow possible?

Post by evstevemd »

I will post stripped code of what I use in my app ... once at home!
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
Buzz
Earned a small fee
Earned a small fee
Posts: 10
Joined: Sun May 27, 2007 5:10 pm
Location: Belgium

Re: writing dynamic text on wxSplashWindow possible?

Post by Buzz »

Cool ! Thanks !
Post Reply