I'm struggling to figure out how to properly override a button's ButtonStateChange in the JUCE library. I'm wanting to change the what happens when a button is held down. I'm fairly new to overriding, but I've been able to successfully override other elements in the JUCE library. Though I am having an issue with this topic.
1) I know you create a new class, maybe MyCustomButton, then
2) Inherit the class you are looking to modify, Button::Listener (not sure if I should do private or public inheritance)
3) Copy and paste the code of the function you want to alter, applying the override keyword to the prototype,
but after this, I'm lost. I'm not sure how to let this new class affect a button that already exists. I know i need to add a listener to an existing button in the constructor and remove the listener in the destructor of the GUI component, but still, I don't know how to apply this new ButtonChangeState listener to an existing button.
Any help would be greatly appreciated.
You can create a new class which inherits from one of Juce's button classes (e.g juce::TextButton) and override buttonStateChanged()
class MyCustomButton : public juce::TextButton
{
public:
MyCustomButton();
protected:
void buttonStateChanged() override
{
// do what you want here
}
};
To apply to your already existing button, just change its type to MyCustomButton.
Alternatively, you can make the class where you use the button inherit from juce::Button::Listener and override buttonStateChanged(Button*).
Then all you need is to attach the listener to your button:
class MyWindow : public Component, private juce::Button::Listener
{
public:
MyWindow()
{
m_button.addListener(this);
}
~MyWindow()
{
m_button.removeListener(this);
}
private:
juce::TextButton m_button;
void buttonStateChanged(Button* button) override
{
if (button == &m_button)
{
// do what you want
}
}
};
Related
I create a new class extend CEdit to override some of the message handles.
My ultimate goal is when edit control is on focus, some of the toolbar buttons become available.
I created a bool variable in doc. then the pCmdUI->enable() set to this bool. The onfocus is overridden in new edit control class. I'm having trouble to update this bool vairbale from the onfocus message handle.
void CMFCDoc::OnUpdateTextColor(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(shape_onfocus_);
}
class CMFCDoc : public COleServerDoc
{
...
bool shape_onfocus_;
}
//edit control
#include <afxwin.h>
class CEditControl :
public CEdit
{
public:
CEditControl();
~CEditControl();
DECLARE_MESSAGE_MAP()
afx_msg void OnEnSetfocus();
};
void CEditControl::OnEnSetfocus()
{
//----- I want to update shape_onfocus_ here. -----
this->SetWindowTextA(_T("Hello world"));
}
Assuming your CEditControl instance is a child of some sort of CView, you could go about it like this:
void CEditControl::OnEnSetfocus()
{
CView *view = static_cast<CView *>(GetParent());
CMFCDoc *doc = static_cast<CMFCDoc *>(view->GetDocument());
doc->shape_onfocus_ = true;
...
}
Assuming the edit-control is a child of a CView-derived class, you should better put the OnUpdateUI() handler in the view class, not the document one.
For example, if the view-class is CFormView-derived (dialog), you could simply write:
void CMyView::OnUpdateTextColor(CCmdUI *pCmdUI)
{
pCmdUI->Enable(GetFocus()==GetDlgItem(IDC_MYEDIT));
}
This piece of code works for both SDI and MDI applications.
If the view class is not CFormView-derived (the edit-box was created programmatically), the code above could be modified slightly, and instead of calling GetDlgItem() you should enumerate the view's children list (search your edit-box there).
If the only reason to override the edit-control was to capture the EN_SET/KILLFOCUS messages, sorry this wasn't worth the effort, as you could simply capture these in the view's code. Then the view's message-map would contain:
ON_EN_SETFOCUS(IDC_MYEDIT, &CMyView::OnEnSetfocusMyEdit)
ON_EN_KILLFOCUS(IDC_MYEDIT, &CMyView::OnEnKillfocusMyEdit)
and the view-class code:
void CMyView::OnEnSetfocusMyEdit()
{
// TODO: Add your control notification handler code here
}
void CMyView::OnEnKillfocusMyEdit()
{
// TODO: Add your control notification handler code here
}
These are generated by the wizard. Go to the Class View tab, select your class and then go to the Events page; in the Controls subtree you can find your control and add handlers for its events. But all this is not needed, as you can just use GetFocus()/GetDlgItem() as suggested above.
And as other members said, you can access the document class from any of its views by calling the GetDocument() function.
I am sub-classing QPlainText edit and I would like to be able to intercept undo / redo commands so that I can implement custom functionality.
I realise that I can disable the undo / redo capability with setUndoRedoEnabled and I can detect Ctrl+Z and Ctrl+Y key presses. However, this doesn't seem like the best cross platform way of doing it.
Any advice?
You simply need to reimplement the slots :
class MyTestEdit : public QPlainTextEdit {
Q_OBJECT
public slots:
void redo() { ... }
void undo() { ... }
};
Signal and slots are exactly like other c++ methods. If you reimplement them in a subclass, they will be called instead of the the parent's.
I think you can use "QUndoStack" for this.
In you subclass's constructor (constructor is better), call a method that creates Undo and Redo actions to handle for your class.
Prototype:
//Call this function to register undo and redo actions.
Void methodCrteaesUndoandRedoActions()
{
QUndoStack unStack = new QUndoStack (this);
QAction *undoAct = undoStack->createUndoAction(this);
QAction *RedoAct = undoStack->createRedoAction(this);
}
//Implement below functions in your class to handle the business.
void undo()
{
}
void redo()
{
}
so my problem isn't as much about the code, but about the way to do it.
I'm working on a GUI and I want my buttons to know who there parent is. And of course, the window knows which buttons it has.
This creates a circular dependency, since both need to be able to access the others methods and attributes, at least that's what I would prefer.
I found a solution that works, but I'm not very happy with it:
I created a third object to which button writes, what it wants the window to do. And the window checks this third object for commands.
I wanted to ask you, if you know of a better way to this, since I couldn't find any other way, that works for me.
Thanks!
I'd suggest create a window interface. Provide a back pointer to the window interface in the constructor of the button. The window that owns the button depends on the button and the button depends on the window interface. No circular dependency.
struct IWindow {
};
struct Button {
IWindow* window_;
Button(IWindow* window) : window_(window){}
};
struct WindowWithButton : IWindow {
Button button_;
WindowWithButton() : button_(this) {}
};
Then add virtual methods to IWindow that are implemented by WindowWithButton so that Button can get the information it needs from the WindowWithButton.
It's a standard pattern:
struct Window; // Forward-declare the parent
struct Button {
void pingParent(); // Only declare members which need
// more than superficial knowledge of Window
Window* parent; // Ok, we know there is a Window, somewhere
};
struct Window {
unique_ptr<Button> child;
// Other functions using the button
void pingpong() {child->pingParent();}
void ping(){}
};
/*optional inline*/ void Button::pingParent() {
parent->ping();
}
According to the help of Qt for QWebPage [Slot ShoudInteruptJavaScript], located here:
This function is called when a JavaScript program is running for a long period of time.
If the user wanted to stop the JavaScript the implementation should return true; otherwise false.
The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons.
Warning: Because of binary compatibility constraints, this function is not virtual. If you want to provide your own implementation in a QWebPage subclass, reimplement the shouldInterruptJavaScript() slot in your subclass instead. QtWebKit will dynamically detect the slot and call it.
I don't want qt show a message when javascript runnig for long period of time.
So, how can i reimplement ShoudInteruptJavaScript? and where should i create it?
Please show me a sample
Thanks
All the info you need is in the documentation.
Create a new custom class that inherits from QWebPage, make sure it's a Q_OBJECT to receive signals.
class MyFunkyPage : public QWebPage {
Q_OBJECT
public slots:
bool shouldInterruptJavaScript() {
QApplication::processEvents(QEventLoop::AllEvents, 42);
// Ignore the error
return false;
}
};
Set the page of your QWebView to a custom subclass of QWebPage.
setPage(new MyFunkyPage());
Then when your page gets this signal it won't stop the script from executing, and it won't show a dialog.
The MyFunkyPage solution potentially leaks memory and causes crashes because the object passed to setPage has no parent and setPage does not take ownership. Instead,
class QWebPageWithoutJsWarning : public QWebPage {
Q_OBJECT
public:
QWebPageWithoutJsWarning(QObject* parent = 0) : QWebPage(parent) {}
public slots:
bool shouldInterruptJavaScript() {
return false;
}
};
Set the page of your QWebView to the custom subclass of QWebPage, parented on the WebView,
void suppressJSWarning(QWebView& webView) {
webView.setPage(new QWebPageWithoutJsWarning(&webView));
}
#anson-mackeracher almost had it right.
Qt needs it to be a private slot, not a public one. Here's what works for my class:
class MyFunkyPage : public QWebPage {
Q_OBJECT
private slots:
bool shouldInterruptJavaScript() {
// Ignore the error (return true to kill the runaway JavaScript)
return false;
}
};
Set the page of your QWebView to a custom subclass of QWebPage.
setPage(new MyFunkyPage());
I just tested this with Qt 4.8.4 and it works like a charm. I didn't need the processEvents call.
I have few questions on this Subjects.
I created a class for buttons, the class has problem.
Problem is:
1. I wanna create function to be called if button is clicked, the problem is that every single button gonna do different thing if it was clicked. So i don't know how i can create function that will do different thing for every button.
I have no idea how i should design my interface.
If you can give me an idea on how i should design my GUI that would be great.
This is my button class
class GUIButtons
{
public:
GUIButtons(void);
~GUIButtons(void);
void LoadMesh(string fileName, int startAnimation, LPDIRECT3DDEVICE9 d3ddev);
void Render(float timeElapsed, D3DXMATRIX *matWorld);
void EventProc(HWND hWnd, UINT msg, LPDIRECT3DDEVICE9 d3ddev);
void Picking(HWND hWnd, LPDIRECT3DDEVICE9 d3ddev);
private:
CXFileEntity *Button;
};
EDIT 2:
Guys is this possible?
I create two functions and than ill point one function to another.
Something like this
void a()
{
....
}
void b() = a;
EDIT 3:
Ok should i use this way for the onClick() function.
void Onclick( void(*fun) )
{
fun();
}
i pass a function to OnClick than it calls the function.
should i use this way?
Use inheritance/polymorphism: The base class is GUIButtons, and every new individual button derives from that base clase:
class MyButton : public GUIButtons { ... }
And then the functionality for a click comes in a virtual method onClick() or whatever.
More detail:
class GUIButtons
{
... \\ lots of stuff
virtual void onClick() { };
};
class CloseButton : public GUIButtons
{
...
virtual void onClick()
{
//code to close window
}
};
class SettingsButton : public GUIButtons
{
...
virtual void onClick()
{
//stuff to open settings menu
}
};
Button click is an action/event. You can encapsulate the click action as a class. This action is interpreted and used differently by the application that uses the button widget. The gui library has to notify that a button has been clicked with the relevant information. You can refer to popular GUI libraries like Qt or Gtk+ as examples to know how they implement GUI events and much more.
I recommend you the book "DirectX 9 User Interfaces: Design and Implementation". I have it and i may say that you'll find there everything what you need!!!;)