Unvanted focus

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
Kocsonya
In need of some credit
In need of some credit
Posts: 9
Joined: Fri May 18, 2018 6:45 am

Unvanted focus

Post by Kocsonya »

First, sorry if it is a totally dumb question.
I have quite some C behind me but am a complete C++ newbie, picking it up primarily for wxWidgets.

I'd like to have a class derived from wxTextCtrl which is set to read-only. That works fine. However, it still receives focus and the cursor blinks in the otherwise immutable text field. My derived class looks like this:

Code: Select all

class MyClass : public wxTextCtrl
{
public:
  MyClass( wxWindow *parent, wxWindowId id );

  virtual bool AcceptsFocus() { return false; }

  ... other members ...
};
and at the moment the constructor does nothing but calls wxTextCtrl::Create to set the parent, window ID and the wxTE_READONLY flag.

If I put some debug print in the AcceptsFocus() method it reveals that it is never actually called.
The IsFocusable() and CanAcceptFocus() methods of the object return true.
I don't think that that would matter, but it's all on Linux.

So, the question would be, could someone tell me what complete misunderstanding of C++, virtual functions and the general operation of wxWidgets renders that code inoperable? I'm serious, I know very little of either subject, so even a minor enlightenment would be most appreciated.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: Unvanted focus

Post by PB »

For starters, you actually did not override the method, notice the missing "const" specifier. If you use a compiler with support for C++11 or newer, you can use "override" specifier and the compiler tells you when you make such a mistake.

Still, even overriding the method may not help and you may need to do some other stuff. Read-only text controls should accept focus and show cursor, it makes easy to select and copy the text.
Kocsonya
In need of some credit
In need of some credit
Posts: 9
Joined: Fri May 18, 2018 6:45 am

Re: Unvanted focus

Post by Kocsonya »

Thank you, I'll work out the const qualifier's role and meaning. As per the standards, well, I have gcc, which is as far as I know is C++11 capable. The problem is the user, not the compiler. My C++ knowledge stems from "C++ Primer" by Lippman, from '98.

Regarding the selection, I won't need that - the field will be part of a more complex widget and clicking on it will do other stuff, so the user will not be able to select its content (and it is deliberately so). So if (properly) overriding AcceptsFocus() will render the widget impossible to have a cursor in it or selecting text from it, that's actually the goal, not an unwanted side effect.

Thanks for your help!
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Unvanted focus

Post by doublemax »

Maybe a wxHtmlWindow would be more suitable for your purpose.
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: Unvanted focus

Post by PB »

I just tested on MSW and returning false has no effect on the control being focusable.

Code: Select all

#include <wx/wx.h>

class UnfocusableTextCtrl : public wxTextCtrl
{
public:
    UnfocusableTextCtrl(wxWindow* parent)
        : wxTextCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2)
    {}

    bool AcceptsFocus() const override { return false; }
};


class MyDialog: public wxDialog
{
public:
    MyDialog()
        : wxDialog(NULL, wxID_ANY, _("Test"))
    {
        wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);

        wxTextCtrl* textCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, 
            wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);        
        textCtrl->ChangeValue("abcdefg");
        bSizer->Add(textCtrl, 1, wxEXPAND | wxALL , 5);
        
        textCtrl = new UnfocusableTextCtrl(this);
        textCtrl->ChangeValue("abcdefg");   
        bSizer->Add(textCtrl, 1, wxEXPAND | wxALL , 5);

        bSizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxALL, 5);

        SetSizer(bSizer);
    }	

};


class MyApp : public wxApp
{
public:
    virtual bool OnInit()
    {     
        MyDialog().ShowModal();               
        return false;
    }
}; wxIMPLEMENT_APP(MyApp);
I have no experience with Linux, but on MSW, if you do not want the user to be able to focus a control, you Disable() it. However, this changes the control appearance, so the user can tell this control cannot be interacted with. More importantly, the scrollbars are disabled as well...

As doublemax wrote, perhaps you are better off using another control, I suppose multiline static text is not good enough for your purpose?
Kocsonya
In need of some credit
In need of some credit
Posts: 9
Joined: Fri May 18, 2018 6:45 am

Re: Unvanted focus

Post by Kocsonya »

Well, then maybe I indeed need to look for an other control.
The aim is to have a single-line text widget which for all intents and purposes behaves like static text but *looks* like a TextEntry widget which is enabled and does not have the focus and has nothing selected in it.

I really don't mind what control I use for that purpose, so any suggestion is welcome. If it's easier to make static text look like TextEntry I'm happy to use that.

What I really want is this: There is an entry field that looks exactly as any other text entry field. It shows some text, which is the human-readable representation of a non-textual object that the widget represents. If the user clicks on the text field (i.e. wants to edit it), a modal pop-up comes up and the user can interact with that to change the underlying non-textual value of the object and when the popup closes, the new value's textual representation is shown in the text field.

Similar to the wxComboBox in read-only mode, except that a) there's no separate button for the pop-up and b) the pop-up is not a listbox and c) the actual value of the object is not textual.

Thanks again.
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Unvanted focus

Post by doublemax »

A wxStaticText with wxBORDER_SUNKEN looks almost the same as a wxTextCtrl when you set the background color to white. (Ar least under Windows, i didn't check any other platform.)
Use the source, Luke!
Kocsonya
In need of some credit
In need of some credit
Posts: 9
Joined: Fri May 18, 2018 6:45 am

Re: Unvanted focus

Post by Kocsonya »

Just to add a bit to the topic:
I played with the focus accept/refuse virtual functions and it seems that the function AcceptsFocusFromKeyboard() is the key.

That method is actually called and if that returns false, the wxTextCtrl widget accepts focus neither by a mouse click nor by keyboard (Tab) traversal.

So it seems that it's a documentation issue, as according to the docs that method controls only the keyboard traversal, but in practice (at least on Linux) it seems to be the overall switch for focus acceptance.

Neither the AcceptsFocus() nor the AcceptsFocusRecursive() methods are called for the widget, only the AccepsFocusFromKeyboard().
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Unvanted focus

Post by ONEEYEMAN »

Hi,
As this forum is for developers by developers (no core-devs here), you can try to send an E-mail to wx-dev ML to inquire about that and ask for the docs update.

Just mention you system/OS name, GTK+ version and wx version.

Thank you.
Post Reply