I have been trying for a very long time (well a few days) to create a toggle button. A button having a up or down state.
Took over a day to realize it is not possible to create an owner drawn toggle button, a checkbox and pushlike does not work. When using owner drawn there is no difference between a checkbox or regular button (MSDN also notes you cant use owner drawn with any of those styles.)
From reading I found out you have to do it yourself, normally not a problem at all, but I cannot get any real "responsiveness." That is, if I click fast, nothing happens, sometimes I will click and it changes states, other times not and only updates when I click a different button.
I created a global variable for if the button should be shown in up or down state. In the commands I have it set that when the button, IDC_BTN_TOGGLE, it will set the opposite value on the bool.
Then the draw item part:
// button down
if ((pDIS->itemState & ODS_SELECTED) || showButtonDown) {
oldBrush = (HBRUSH)SelectObject(pDIS->hDC, theme.hBrush[BRUSH_BUTTON2]);
}
// button up
else {
oldBrush = (HBRUSH)SelectObject(pDIS->hDC, theme.hBrush[BRUSH_BUTTON]);
}
All my buttons are owner drawn and run through this. showButtonDown is only true when it is drawing IDC_BTN_TOGGLE and the top bool is true as well.
The normal buttons function normally, when I click them, it instantly shows the down state, release, back to normal, the toggle button is barely responsive.
Related
I have a strange issue that I have been unable to determine the cause. Basically, I created a 2D view with pan and zoom functionality and a scene with items that can moved with grid snapping. To move an item in the scene I extended Scene::mousePressEvent to get a pointer to the item and Scene::mouseMoveEvent to keep the item tracked on the cursor. To drop the item, I used Scene::mousePressEvent again. To pan, I extended View::mousePressEvent, View::mouseReleaseEvent, and View::mouseMoveEvent and to zoom I extended View::wheelEvent.
Now for the symptoms:
I start the application with an item in the Scene. If I click and hold, then move the mouse, the item moves as intended. As soon as I release the mouse button, the item stops moving. I can click to drop and the item is placed according to the drop code in Scene::mousePressEvent. Try again and still the item only moves when the mouse button is pressed.
Then comes the strange part: If I use the mouse wheel to zoom the View, everything performs as expected after that event. The mouse is clicked to select an item, it moves as I move the mouse and drops when I click again.
So the obvious solution:
wheelEvent(new QWheelEvent(QPointF(0,0),0,Qt::NoButton,Qt::NoModifier));
called at the creation of the View and everything works fine. It calls the extended View::wheelEvent with no change to the view and before the scene is even created, but afterwards the programs behaves as expected.
So I'm here to see if any of the excellent Qt experts out there can explain this strange behavior. Any comments or direction are appreciated.
In case it helps, here is the View::wheelEvent override code. tform is a QTransform with which I maintain zoom. Also, I've tried with and without the call to the base method but there is no change in behavior.
void SchematicView::wheelEvent(QWheelEvent* event)
{
// Scale the view / do the zoom
double scaleFactor = 1.1;
if(event->delta() > 0 && tform.m11() < max_zoom) {
tform.scale(scaleFactor,scaleFactor);
} else if (event->delta() < 0 && tform.m11() > min_zoom){
tform.scale(1.0/scaleFactor,1.0/scaleFactor);
}
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setTransform(tform);
QGraphicsView::wheelEvent(event);
}
Without a SSCCE to look at and test with, it's hard to say for sure, but what you're describing sounds a lot like your mouseMoveEvent() callback is only getting called when the mouse button is being held down during the move. That, in turn, sounds a lot like the expected behavior for mouseMoveEvent(), as documented in QWidget::mouseMoveEvent():
If mouse tracking is switched off, mouse move events only occur if a
mouse button is pressed while the mouse is being moved. If mouse
tracking is switched on, mouse move events occur even if no mouse
button is pressed.
If that is indeed the problem, then a call to setMouseTracking(true) may get you the behavior you are looking for.
On a broader level, note that there are easier ways of obtaining the behavior you are trying to implement -- for example, to allow the user to drag and drop items in a QGraphicsScene, all you really have to do is call setFlags(QGraphicsItem::ItemIsMovable) on any QGraphicsItems that you want the user to be able to drag around. No hand-coding of event handlers is necessary unless you are trying to obtain some non-standard behaviors.
I am new to cocos2d-x and I am developing a game in x-code using cocos2d-x2.0.4. In my game I created a button using CCcontrolbutton. Now I want to drag my button to one place to another. I tried with all the CCControlEvents but it doesn't work. Now I want to know, is it possible to drag and drop a button using CCControlbutton. I pasted my code which I have used to create the button.
button1 = CCControlButton::create(CCScale9Sprite::create("7.png"));
button1->setAdjustBackgroundImage(false);
button1->setPosition( ccp(winwsize/6, winhsize/7) );
button1->addTargetWithActionForControlEvents(this, cccontrol_selector(plus::add),CCControlEventTouchDragOutside);
button1->addTargetWithActionForControlEvents(this, cccontrol_selector(plus::add),CCControlEventTouchDragInside);
this->addChild(button1, 4);
In add() I have given the code to enter next scene. But now it is entering while clicking the button. But i want while drag it to one position to another. If it is possible to drag a button using CCControlbutton then please give me some sample codes. Thanks.
The events CCControlEventTouchDragInside and CCControlEventTouchDragOutside are happening when the user's touch (his fingertip) is entering or leaving your button while already or still touching the touchscreen (or while the mouse button is still pressed while the mouse pointer moves).
You would need to observe the dragging process yourself. Starting with a click on your button, change the button's position while the user is dragging (to visualize the dragging process), and then call plus::add() when the dragging ends in your target area.
How to make a toggle button in MFC dialog,?
Like the one you usually used in switching on the wifi in smart phone, push like switch button and radion buttons are not my needs,
Uptil now i reached to changing the switch button to push like effect but i need the real toggle button effect as describe about those in smartphones.
Remember that it supports dragging to on from off and vice versa.... :(
You can keep 2 images that are visible when button is pressed and one when button is not pressed. Now you can use CBitmapButton::LoadBitmaps or CButton::SetBitmap to change the image everytime the button is clicked. Make sure to invalidate the button so that new image can take effect.
//load your bitmaps (in constructor if dialog)
m_wifionBitmap.LoadBitmap(IDB_WIFION);
m_wifioffBitmap.LoadBitmap(IDB_WIFIOFF);
// In turn_on_wifi()
CButton* pButton = (CButton*)GetDlgItem(IDC_WIFI_TOGGLE_BUTTON);
pButton->SetBitmap(HBITMAP)m_wifionBitmap);
// In turn_off_wifi()
CButton* pButton = (CButton*)GetDlgItem(IDC_WIFI_TOGGLE_BUTTON);
pButton->SetBitmap(HBITMAP)m_wifioffBitmap);
I'm making my first game in Irrlicht (C++), an RTS with mouse control
and when you select a tile (by clicking on it) it lights up and some gui button appear on the screen (not in a gui window mind you, I like it this way):
http://i1139.photobucket.com/albums/n549/Adam_Halley-Prinable/Untitled2.png
However, since i switched to mouse control, the buttons wont register my mouse clicks. The click goes straight through the button and selects the tile behind instead:
http://i1139.photobucket.com/albums/n549/Adam_Halley-Prinable/Untitled3.png
Is there a way I can say "Buttons get top priority for clicks"?
I'm using MyEventReceiver, which i've messed around with to accept mouse clicks and that.
Thanks a bunch :D
If anyone else has the same problem, ill tell you how I solved it :)
Go through the MyEventReceiver.h and get rid of all the "return true;"'s in the mouse section.
Don't ask me why, but it works, and appears to have no side effects. Make sure you leave the "return false;" at the end of the section there.
Your event receiver fires before the GUI gets access to the event, if you want to pass it to the GUI then you can do this by manually posting it to the GUIEnvironment in your event receiver.
if (guienv->postEventFromUser(event))
return true; // abort because the gui wanted it
// .. pick nodes
// possibly post event to scene manager
return true; // remember to return true so gui/smgr don't get the event again
I created a simple dialog-based application, and in the default CDialog added three buttons (by drag-and-dropping them) using the Visual Studio editor.
The default OK and Cancel buttons are there too.
I want to set the focus to button 1 when I click button 3.
I set the property Flat to true in the properties for muy buttons.
I coded this:
void CbuttonfocusDlg::OnBnClickedButton3()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_BUTTON1)->SetFocus();
Invalidate();
}
But the boder in button1 is never drawn. The caret (the dotted line indicating focus) is only drawn if I pressed TAB any time before clicking button 3.
I want the button to look exactly as it looks after I click it. Showing the dotted line inside the button programatically, would be a plus.
What I want:
What I get:
Use WM_NEXTDLGCTL.
See Reymond Chen's "How to set focus in a dialog box":
void SetDialogFocus(HWND hdlg, HWND hwndControl)
{
SendMessage(hdlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, TRUE);
}
By calling UpdateWindow, the button is being redrawn before the focus change can take effect. The Invalidate should be sufficient by itself, the window will get repainted when everything settles down.
This draws the thick border around the button:
static_cast<CButton*>(GetDlgItem(IDC_BUTTON1))->SetButtonStyle(BS_DEFPUSHBUTTON);
A more elegant way to do this would be to define a CButton member variable in CbuttonfocusDlg and associate it to the IDC_BUTTON1 control, and then calling
this->m_myButton.SetButtonStyle(BS_DEFPUSHBUTTON);
This makes the button to which I'm setting the focus the default button, but note that when the focus goes to a control (inside the dialog) that is not a button, the default button is once more the original default button set in the dialog resource, in this case the "Ok" button.
I am following Joel's suggestion. But slightly different with the API used in that link, my one is :
PostMessage(WM_NEXTDLGCTL, (WPARAM)(pwnd->GetSafeHwnd()), TRUE);