Bridging Windows/Linux differences 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
Tony0945
Experienced Solver
Experienced Solver
Posts: 96
Joined: Wed Oct 21, 2009 4:02 pm

Bridging Windows/Linux differences

Post by Tony0945 » Tue Aug 10, 2010 1:16 am

Reposted from the wxDev-C++ forum:

When compiling the same wxFrame based code under Windows 2000 and GNOME 2.8, I find the following differences:

1. Windows opens minimized, GNOME opens half-size (correct).

2. Windows has a functional Maximize Button (correct), GNOME has no Maximize button.

3. Windows sizer-sized buttons show full text (correct), GNOME shows truncated text. i.e. "ChannelDown" on Windows, "ChannelDo" on GNOME.

I could use a wxDialog as easily because there is only one frame with standard controls on it. But I read that GNOME dialog boxes don't have maximize buttons.

Can I just add another button and call parent->Maximize() from it? It's kind of kludgy, but I really need to show the frame full-screen.

I can probably toy with the button sizes to get the text to show completely under Linux, but there should be a more seamless way.
Frame style is:

wxTAB_TRAVERSAL | wxCAPTION | wxSYSTEM_MENU | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX

-----------------------------------------------------------------------------
I later found that adding wxRESIZE_BORDER fixed the missing Maximize button in Linux. It was not necessary in Windows. Sounds like a bug or just a difference that should be documented.

Still wondering about the button text.

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Tue Aug 10, 2010 12:22 pm

What version of wxWidgets have you been using? And which port? (i.e. made sure it's wxGTK and not wxX11?) I'm using wx under gnome and I definitely have a maximize button
"Keyboard not detected. Press F1 to continue"
-- Windows

Tony0945
Experienced Solver
Experienced Solver
Posts: 96
Joined: Wed Oct 21, 2009 4:02 pm

Post by Tony0945 » Wed Aug 11, 2010 2:21 am

wxGTK version 2.8.11
With out the RESIZE_BORDER attribute, no maximize button.

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Wed Aug 11, 2010 12:23 pm

Ah, but it is documented ;)
http://docs.wxwidgets.org/trunk/classwx_frame.html wrote: # wxMAXIMIZE_BOX:
Displays a maximize box on the frame. Notice that under wxGTK wxRESIZE_BORDER must be used as well or this style is ignored.
About the button in sizer problem, can you show your code so we can try it?
"Keyboard not detected. Press F1 to continue"
-- Windows

Tony0945
Experienced Solver
Experienced Solver
Posts: 96
Joined: Wed Oct 21, 2009 4:02 pm

Post by Tony0945 » Fri Aug 13, 2010 11:11 pm

Yes, you are right, it is documented. Also, that page explains Item 1 in my list.

Code: Select all

void TonysTVplayerFrm::CreateGUIControls()
{
	//Do not add custom code between
	//GUI Items Creation Start and GUI Items Creation End
	//wxDev-C++ designer will remove them.
	//Add the custom code before or after the blocks
	
   
	
	////GUI Items Creation Start

	wxInitAllImageHandlers();   //Initialize graphic format handlers

	wxArrayString arrayStringFor_ChannelList;
	ChannelList = new wxComboBox(this, ID_CHANNELLIST, wxT("ChannelList"), wxPoint(198, 266), wxSize(121, 21), arrayStringFor_ChannelList, 0, wxDefaultValidator, wxT("ChannelList"));

	VolumeSlider = new wxSlider(this, ID_VOLUMESLIDER, 0, 0, 10, wxPoint(194, 219), wxSize(139, 21), wxSL_HORIZONTAL | wxSL_SELRANGE , wxDefaultValidator, wxT("VolumeSlider"));
	VolumeSlider->SetRange(0,10);
	VolumeSlider->SetValue(0);

	wxBitmap MuteButton_BITMAP (TonysTVplayerFrm_MuteButton_XPM);
	MuteButton = new wxBitmapButton(this, ID_MUTEBUTTON, MuteButton_BITMAP, wxPoint(152, 215), wxSize(38, 26), wxBU_AUTODRAW, wxDefaultValidator, wxT("MuteButton"));

	StopButton = new wxButton(this, ID_STOPBUTTON, wxT("STOP"), wxPoint(106, 216), wxSize(42, 26), 0, wxDefaultValidator, wxT("StopButton"));

	PauseButton = new wxButton(this, ID_PAUSEBUTTON, wxT("PAUSE"), wxPoint(56, 216), wxSize(50, 26), 0, wxDefaultValidator, wxT("PauseButton"));

	PlayButton = new wxButton(this, ID_PLAYBUTTON, wxT("PLAY"), wxPoint(4, 216), wxSize(47, 26), 0, wxDefaultValidator, wxT("PlayButton"));

	ChannelDownButton = new wxButton(this, ID_CHANNELDOWNBUTTON, wxT("Channel DOWN"), wxPoint(99, 268), wxSize(95, 30), 0, wxDefaultValidator, wxT("ChannelDownButton"));

	ChannelUPButton = new wxButton(this, ID_CHANNELUPBUTTON, wxT("Channel UP"), wxPoint(4, 269), wxSize(95, 30), 0, wxDefaultValidator, wxT("ChannelUPButton"));

	Video = new wxuserTVCtrl(this, ID_VIDEO,wxT(""), wxPoint(-2, 3), wxSize(360, 240) );
	Video->Enable(false);
	Video->ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE);

	SetTitle(wxT("TonysTVplayer"));
	SetIcon(wxNullIcon);
	SetSize(8,8,367,350);
	Center();
	
	////GUI Items Creation End
	muted_map= new wxBitmap (TonysTVplayerFrm_muted_MuteButton_XPM);
	unmuted_map = new wxBitmap (TonysTVplayerFrm_MuteButton_XPM);
	muted = false;

	
    //
    //  Create and attach the sizers
    //
    wxFlexGridSizer* sizer = new wxFlexGridSizer(2, 1, 0, 0);
    wxBoxSizer* ChannelRowSizer = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* ControlRowSizer = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* ControlColumnSizer= new wxBoxSizer(wxVERTICAL);
  
    this->SetSizer(sizer);
    this->SetAutoLayout(true);
    sizer->AddGrowableRow(0);
    sizer->AddGrowableCol(0);
	
    sizer->Add(Video, 5, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
    ChannelRowSizer->Add(ChannelUPButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    ChannelRowSizer->Add(ChannelDownButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    ChannelRowSizer->Add(ChannelList, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    
    ControlRowSizer->Add(PlayButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    ControlRowSizer->Add(PauseButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    ControlRowSizer->Add(StopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    ControlRowSizer->Add(MuteButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    ControlRowSizer->Add(VolumeSlider, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    
    ControlColumnSizer->Add(ChannelRowSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    sizer->Add(ControlRowSizer,0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
    sizer->Add(ControlColumnSizer, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
   
   
    PopulateChannelList(arrayStringFor_ChannelList);
    ChannelList->Show();
   
    VolumeSlider->SetRange(0,100);
    VolumeSlider->SetValue(50);
    volume=0.5;
#ifndef __LINUX__   
// On Linux, the size of the video through GetBestSize() 
//            and the duration is not available until AFTER the media starts playing for a while 
    Video->SetSize(Video->GetBestSize());
#endif    
    Video->SetVolume(volume);
//    Video->Enable(true);
    Video->SetChannel(m_channel);
    Video->LoadSource(DefaultChannel.type);
    ChannelList->SetSelection(ChannelList->FindString(m_channel.displaystring));
}
wxuserTVCtrl is derived from wxMediaCtrl. It adds some functions for loading and channel selection.
In Linux, the ChannelDownButton only displays "Channel DO" and part of the E in the Pause button is clipped.

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Sat Aug 14, 2010 5:24 pm

Well, looking at that code, the clipping is normal :

Code: Select all

        ChannelDownButton = new wxButton(this, ID_CHANNELDOWNBUTTON, wxT("Channel DOWN"), wxPoint(99, 268), wxSize(95, 30), 0, wxDefaultValidator, wxT("ChannelDownButton"));

        ChannelUPButton = new wxButton(this, ID_CHANNELUPBUTTON, wxT("Channel UP"), wxPoint(4, 269), wxSize(95, 30), 0, wxDefaultValidator, wxT("ChannelUPButton"));
You're using absolute positions and sizes. wx is listening to you and creates the button with the size you requested it to; maybe that size is correct on Windows with your current theme and font - but you should never rely on absolute sizes since as soon as the font or theme (or the OS) changes, you're no more guaranteed the size is OK anymore. Please use sizers so that they may determine the appropriate size

The easiest way to let the sizers do is to replace the absolute sizes (e.g. wxSize(95, 30)) by wxDefaultSize; this tells the sizer to automatically determine the best size for each button. Once I changed all absolute wxSizes to wxDefaultSize, buttons no more clip

For reference, the code I used is this :

Code: Select all

#include "wx/wx.h"

typedef wxPanel wxuserTVCtrl;

class MyFrame : public wxFrame
{
    wxComboBox* ChannelList;
    wxSlider* VolumeSlider;
    wxBitmapButton* MuteButton;
    wxButton* PauseButton;
    wxButton* PlayButton;
    wxButton* StopButton;
    
public:
    MyFrame() : wxFrame(NULL, wxID_ANY,  wxT("Hello wxWidgets"), wxPoint(50,50), wxSize(800,600))
    {
        //Do not add custom code between
        //GUI Items Creation Start and GUI Items Creation End
        //wxDev-C++ designer will remove them.
        //Add the custom code before or after the blocks
        
        
        
        ////GUI Items Creation Start
        
        wxInitAllImageHandlers();   //Initialize graphic format handlers
        
        wxArrayString arrayStringFor_ChannelList;
        ChannelList = new wxComboBox(this, wxNewId(), wxT("ChannelList"), wxPoint(198, 266), wxSize(121, 21), arrayStringFor_ChannelList, 0, wxDefaultValidator, wxT("ChannelList"));
        
        VolumeSlider = new wxSlider(this, wxNewId(), 0, 0, 10, wxPoint(194, 219), wxSize(139, 21), wxSL_HORIZONTAL | wxSL_SELRANGE , wxDefaultValidator, wxT("VolumeSlider"));
        VolumeSlider->SetRange(0,10);
        VolumeSlider->SetValue(0);
        
        wxBitmap MuteButton_BITMAP ("/Users/mmg/adblock.png");
        MuteButton = new wxBitmapButton(this, wxNewId(), MuteButton_BITMAP, wxPoint(152, 215), wxSize(38, 26), wxBU_AUTODRAW, wxDefaultValidator, wxT("MuteButton"));
        
        StopButton = new wxButton(this, wxNewId(), wxT("STOP"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, wxT("StopButton"));
        
        PauseButton = new wxButton(this, wxNewId(), wxT("PAUSE"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, wxT("PauseButton"));
        
        PlayButton = new wxButton(this, wxNewId(), wxT("PLAY"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, wxT("PlayButton"));
        
        wxButton* ChannelDownButton = new wxButton(this, wxNewId(), wxT("Channel DOWN"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, wxT("ChannelDownButton"));
        
        wxButton* ChannelUPButton = new wxButton(this, wxNewId(), wxT("Channel UP"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, wxT("ChannelUPButton"));
        
        wxuserTVCtrl* Video = new wxuserTVCtrl(this, wxNewId(), wxPoint(-2, 3), wxSize(360, 240) );
        Video->Enable(false);
        //Video->ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE);
        
        SetTitle(wxT("TonysTVplayer"));
        SetIcon(wxNullIcon);
        SetSize(8,8,367,350);
        Center();
        
        ////GUI Items Creation End
        wxBitmap* muted_map= new wxBitmap ("/Users/mmg/adblock.png");
        wxBitmap* unmuted_map = new wxBitmap ("/Users/mmg/adblock.png");
        bool muted = false;
        
        
        //
        //  Create and attach the sizers
        //
        wxFlexGridSizer* sizer = new wxFlexGridSizer(2, 1, 0, 0);
        wxBoxSizer* ChannelRowSizer = new wxBoxSizer(wxHORIZONTAL);
        wxBoxSizer* ControlRowSizer = new wxBoxSizer(wxHORIZONTAL);
        wxBoxSizer* ControlColumnSizer= new wxBoxSizer(wxVERTICAL);
        
        this->SetSizer(sizer);
        this->SetAutoLayout(true);
        sizer->AddGrowableRow(0);
        sizer->AddGrowableCol(0);
        
        sizer->Add(Video, 5, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
        ChannelRowSizer->Add(ChannelUPButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        ChannelRowSizer->Add(ChannelDownButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        ChannelRowSizer->Add(ChannelList, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        
        ControlRowSizer->Add(PlayButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        ControlRowSizer->Add(PauseButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        ControlRowSizer->Add(StopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        ControlRowSizer->Add(MuteButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        ControlRowSizer->Add(VolumeSlider, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        
        ControlColumnSizer->Add(ChannelRowSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
        sizer->Add(ControlRowSizer,0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
        sizer->Add(ControlColumnSizer, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
        
        
        //PopulateChannelList(arrayStringFor_ChannelList);
        ChannelList->Show();
        
        VolumeSlider->SetRange(0,100);
        VolumeSlider->SetValue(50);
        float volume=0.5;
#ifndef __LINUX__   
        // On Linux, the size of the video through GetBestSize()
        //            and the duration is not available until AFTER the media starts playing for a while
        Video->SetSize(Video->GetBestSize());
#endif   
        //Video->SetVolume(volume);
        //    Video->Enable(true);
        //Video->SetChannel(m_channel);
        //Video->LoadSource(DefaultChannel.type);
        Video->SetBackgroundColour(*wxBLACK);
        //ChannelList->SetSelection(ChannelList->FindString(m_channel.displaystring)); 
        
        Fit();
    }
};

class MyApp: public wxApp
{
    wxFrame* m_frame;
public:
    
    bool OnInit()
    {
        m_frame = new MyFrame();
        m_frame->Show();
        return true;
    } 
    
};

IMPLEMENT_APP(MyApp)
"Keyboard not detected. Press F1 to continue"
-- Windows

Post Reply