SDL2 jbutton enum? - sdl

I'm having some trouble figuring out what enums I can/should use for SDL2's gamepad/joystick support. I tried using "SDL_CONTROLLER_*", but I ended up with some odd results. For instance:
SDL_Event e;
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_JOYBUTTONDOWN)
{
printf("%d\n", e.jbutton.button);
if (e.jbutton.button == SDL_CONTROLLER_BUTTON_B)
{
printf("HI\n");
}
}
}
I had this code in my function's main loop, and the second print statement goes off when I press the D-pad's DOWN button, instead of when I press the B button. I'm using an XBOX 360 controller, and it gives me no trouble at all when I play other games. Am I even using the correct enum?

A controller has different input handling than the Joystick.
You need to use Controller events:
SDL_CONTROLLERAXISMOTION: controller axis motion
SDL_CONTROLLERBUTTONDOWN: controller button pressed
SDL_CONTROLLERBUTTONUP: controller button released
SDL_CONTROLLERDEVICEADDED: controller connected
SDL_CONTROLLERDEVICEREMOVED: controller disconnected
SDL_CONTROLLERDEVICEREMAPPED: controller mapping updated
As you can see in this page https://wiki.libsdl.org/SDL_EventType.

Related

QSlider postion changes only when minimazing app

I am using QSlider element in my app as a toogle switch. I took this project over from a colleage of mine who left. So far so good, except, that this switch has a black label around it. I can't really change the style and rework everything so, I am stuck with label and slider as switch.
I need to handle events from button clicked and button released. I do it like this-
bool CustomSlider::eventFilter(QObject *obj, QEvent *ev )
{
if (ev->type() == QEvent::MouseButtonRelease)
{
changeSliderValue();
}
if(ev->type() == QEvent::MouseButtonPress){
lastSaved = ui->horizontalSlider->value();
}
return QWidget::eventFilter(obj,ev);
And changeSliderValue()-
void CustomSlider::changeSliderValue()
{
int current = ui->horizontalSlider->value();
if(lastSaved==current){
if(current){
ui->horizontalSlider->setValue(0);
}else{
ui->horizontalSlider->setValue(1);
}
}
}
So, in short, if I click, it saves state of slider and when releasing it checks against saved state. I do it because QSlider has button pressed signal as well. I have put debug messages in my code and funny thing is debug messages fire. So my code works. If I call ui->horizontalSlider->value() I get the correct(changed) value But the slider is not moving. I have tried checking sequences, if it does not change value twice(it does not), I have tried calling repaint() and so far nothing works. Except if don't minimize(via minimize button) or click in different app(like web browser) and then I can see that slider moves to correct postion. I am completely confused. Has anyone encoutered something like this before?

Qt event when widget goes out of sight

Is there a way in Qt to handle situation when any widget of Window goes out of sight. I.e if a widget was in tab control and user have changed active tab, or if user just scrolls and widget goes offscreen, and also when it goes back on screen.
Is that possible to add some code to this two events?
Best if this can be done globally...
Is there a way in Qt to handle situation when any widget of Window goes out of sight. I.e if a widget was in tab control and user have changed active tab, or if user just scrolls and widget goes offscreen, and also when it goes back on screen.
The way the question asked makes one think that the widget show-hide-expose state changes need to be handled:
bool MyWidget::event(QEvent* pEvent)
{
if (pEvent->type() == QEvent::Show)
{
// event "shown"
}
else if (pEvent->type() == QEvent::Hide)
{
// event "hidden"
}
else if (pEvent->type() == QEvent::Expose)
{
// event "exposure changed"
// deal with QExposeEvent and evaluate the exposed region
// QExposeEvent* pExposeEvent = reinterpret_cast<QExposeEvent*>(pEvent);
}
return QWidget::event(pEvent);
}
Best if this can be done globally...
Event filter at the top level widget may solve that. Or you can override event() function for the top level widget but finding what exact widget was affected is another thing.
Refer to QExposeEvent description.

QKeyEvent isAutoRepeat not working?

So, I have an application where if a particular button is kept pressed it plays an audio device, when the button is released it stops the audio device. I use keyPressEvent and KeyReleaseEvent to implement this which is similar to the code below:
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if(event->isAutoRepeat())
{
event->ignore();
}
else
{
if(event->key() == Qt::Key_0)
{
qDebug()<<"key_0 pressed"<<endl;
}
else
{
QWidget::keyPressEvent(event);
}
}
}
void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
if(event->isAutoRepeat())
{
event->ignore();
}
else
{
if(event->key() == Qt::Key_0)
{
qDebug()<<"key_0 released"<<endl;
}
else
{
QWidget::keyReleaseEvent(event);
}
}
}
But apparently isAutoRepeat function isn't working as I can see continuous print out of key_0 pressed and key_0 released despite the fact I haven't released the 0 key after I have pressed it. Is my code wrong or something else is wrong?
Thanks.
EDIT
I think this is happening because the MainWindow loses the keyboard focus. How can I actually find out which widget has the focus? I'm actually using some widgets when Qt::Key_0 pressed, but I thought I set all those possible widgets to Qt::NoFocus, I guess it's not working.
I'm trying to know which widget has the focus by doing the following:
QWidget * wigdet = QApplication::activeWindow();
qDebug()<<wigdet->accessibleName()<<endl;
but it always prints an empty string. How can I make it print the name of the widget which has the keyboard focus?
So as I also stumbled over this issue (and grabKeyboard didn't really help), I begun digging in qtbase. It is connected to X11 via xcb, and by default, in case of repeated keys, X11 sends for each repeated key a release-event immediately followed by a key-press-event. So holding down a key results in a sequence of XCB_BUTTON_RELEASE/XCB_BUTTON_PRESS-events beeing sent to the client (try it out with xev or the source at the end of this page).
Then, qt (qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp) tries to figure out from these events whether its an autorepeat case: when a release is received, it uses a lookahead feature to figure if its followed by a press (with timestamps close enough), and if so it assumes autorepeat.
This does not always work, at least not on all platforms. For my case (old and outworn slow laptop (Intel® Celeron(R) CPU N2830 # 2.16GHz × 2) running ubuntu 16.04), it helped to just put a usleep (500) before that check, allowing the press event following the release event to arrive... it's around line 1525 of qxcbkeyboard.cpp:
// look ahead for auto-repeat
KeyChecker checker(source->xcb_window(), code, time, state);
usleep(500); // Added, 100 is to small, 200 is ok (for me)
xcb_generic_event_t *event = connection()->checkEvent(checker);
if (event) {
...
Filed this as QTBUG-57335.
Nb: The behaviour of X can be changed by using
Display *dpy=...;
Bool result;
XkbSetDetectableAutoRepeat (dpy, true, &result);
Then it wont send this release-press-sequences in case of a hold down key, but using it would require more changes to the autorepeat-detection-logic.
Anyway solved it.
The problem was that I have a widget which is a subclass of QGLWidget which I use to show some augmented reality images from Kinect. This widget takes over the keyboard focus whenever a keyboard button is pressed.
To solve this problem, I needed to call grabKeyboard function from the MainWindow class (MainWindow is a subclass of QMainWindow), so this->grabKeyboard() is the line I needed to add when key_0 button is pressed so that MainWindow doesn't lose the keyboard focus, and then when the key is released I needed to add the line this->releaseKeyboard() to resume normal behaviour, that is, other widgets can have the keyboard focus.

Quick Button Input Fails to Generate any Events in SDL 1.2.15

Lets say we have an input device which is a controller. In addition, lets say we also have some construct which checks for events using "SDL_PollEvent(...)".
In my tests, "SDL_PollEvent(...)" was checked every 3 seconds, if a button is tapped quickly just once or even tapped multiple times during the delay, SDL will not generate the button press nor the button release events. If the very same button which was tapped on the controller, is now pressed and held down, the SDL dose generated those events.
In addition to this very same test, if a keyboard key is tapped quickly just once during the very extreme "SDL_Delay(...)" test, a button pressed event is always generated.
Quick button press and release from the controller device will generate events with "SDL_WaitEvent(...)". But, SDL_INIT_VIDEO and SDL_INIT_EVENTTHREAD must be in the same thread as they can't be separated across multiple SDL_Thread[s] in my case.
Given the delay between event polling and how brief a button press is, my situation needs to know that the button was pressed at minimum once regardless.
What can be done in this situation? So that SDL would generate/poll controller events the very same way as it dose for the keyboard device?
Is SDL 1.2 not capable to do this? Are there other libraries which are better capable at guaranteeing that a button tap event is generated ? Thank you!
bool activity(1);
while(activity) // event polling used in testing
{
std::cout << "\nWaiting...";
SDL_Delay(3000U); // <--- simulating delay for purpose of test
while(SDL_PollEvent(&event_))
{
switch(event_.type)
{
case SDL_JOYBUTTONDOWN :
switch(event_.jbutton.button)
{
case 0U :
...
break;
case 1U :
...
break;
}
break;
case SDL_KEYDOWN :
switch(event_.key.keysym.sym)
{
case SDLK_a :
...
break;
}
break;
}
}
}

MFC button onclick handler

I've 2 mfc buttons that I want to hide when a 3D stl file is being loaded and then show the buttons again when the stl loading is complete. This is to prevent user from re-loading the model when the loading is currently taking place.
The snippet of the code is as below
{ // change control state when model loads
((CButton *)this->GetDlgItem(IDC_RELOAD_STOCK_BUTTON))->ShowWindow(SW_HIDE);
((CButton *)this->GetDlgItem(IDOK))->ShowWindow(SW_HIDE);
UpdateWindow();
}
// this process takes few seconds to load the file in the memory
customStockModel.LoadFile(pathName.GetBuffer(pathName.GetLength()));
{
// change control state when the model has loaded
((CButton *)this->GetDlgItem(IDC_RELOAD_STOCK_BUTTON))->ShowWindow(SW_SHOW);
((CButton *)this->GetDlgItem(IDOK))->ShowWindow(SW_SHOW);
UpdateWindow();
}
The buttons do get hidden and reappear as I expect, but when I click the button area while it's hidden, the onclick handler gets called immediately when the button control reappears on the screen. it seems like the click message is queued and mfc calls the handler once the buttons are activated. What am I doing wrong here?
Ideally you should read your file in a thread - this would allow your application to refresh itself normally and process messages.
Now if you are unsure about this (multi-threading is hard), you can call regularly the following function in your lenghty function to clear up the message loops.
BOOL YourClass::DoEvents()
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
return FALSE;
}
if (!AfxGetApp()->PreTranslateMessage(&msg))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
return TRUE;
}
It will work but "proper programmers" will scream when they see this!
Good luck