2017-04-11 3 views
1

Je construis SDL2 applications pour macOS en utilisant C++. J'ai besoin d'un défilement «basique» pour une application (comme un navigateur Web). J'y parviens en utilisant l'événement SDL_MouseWheel, ce qui me donne un défilement «windows-like» entièrement fonctionnel. J'utilise un Macbook Pro et je veux apporter.Lisse (inertielle) défilement avec SDL2?

la fonctionnalité du trackpad Tout simplement, je vous demande un meilleur algorithme de défilement (défilement trackpad du MacBook, le défilement à inertie)

Je sais que sur le SDL_MultiGesture événement, mais je ne sais pas vraiment comment mettre les choses ensemble pour atteindre le résultat que je veux.

+0

La question semble un peu vague et large dans la portée.Pouvez-vous le réduire un peu, en donnant peut-être un exemple de ce que vous avez actuellement et en expliquant comment vous voulez modifier le comportement? – paddy

+0

Je veux implémenter le défilement inertiel en utilisant SDL2 (probablement avec SDL_MultiGesture) et je veux de l'aide ou un exemple pour cela. –

Répondre

1

Bon, voici la réponse au problème.

Tout d'abord, vous devrez le faire manuellement. Je suppose également que vous connaissez SDL2 et C++.
* Note: Je ne fais défiler que pour Y-Axis (vous pouvez le faire pour les deux si vous voulez).

Tout d'abord nous aurons besoin des variables:

int scrolling;    // flag (scrolling or not) 
int scroll_sensitivity = 40; // how fast we want to scroll 
double scroll_Y = 0;   // current scrolling amount (on Y-Axis) 
double scroll_acceleration;  // scrolling speed 
double scroll_friction = 0.001; // how fast we decelerate 
double scroll_prev_pos;   // previous event's position 

Après que vous aurez besoin de gérer l'événement SDL_MultiGesture:

case SDL_MULTIGESTURE:{ 
    if(event.mgesture.numFingers == 2){ 
    if(scrolling == 0){ 
     scrolling = 1; 
     scroll_prev_pos = event.mgesture.y; 
    } else{ 
     double dy = event.mgesture.y - scroll_prev_pos; 
     scroll_acceleration = dy * 40; 
     scroll_prev_pos = event.mgesture.y; 
     scrolling = 1; 
    } 
    } 
    break; 
} 

, nous devons également arrêter le défilement sur l'événement SDL_FingerDown:

case SDL_FINGERDOWN:{ 
    scrolling = 0; 
    break; 
} 

Ensuite, nous voulons mettre à jour scroll_Y (mettez-le dans votre fonction "mise à jour"):

if(scrolling){ 
    if(scroll_acceleration > 0) scroll_acceleration -= scroll_friction; 
    if(scroll_acceleration < 0) scroll_acceleration += scroll_friction; 
    if(abs(scroll_acceleration) < 0.0005) scroll_acceleration = 0; 
    scroll_Y += scroll_sensitivity * scroll_acceleration; 
    // Here you have to set your scrolling bounds i.e. if(scroll_Y < 0) scroll_Y = 0; 
} 

Enfin, nous voulons rendre selon nos valeurs de défilement:

SDL_Rect rect = {some_x, some_y + scroll_Y, some_w, some_h}; 
SDL_RenderCopy(renderer, some_texture, NULL, &rect); 

This is it!
J'ai une application entièrement fonctionnelle avec le code ci-dessus, donc je suis sûr à 100% que cela fonctionne comme supposé. Si vous avez des problèmes (parce que ce n'est pas du code réel, c'est plus comme un algorithme), contactez-moi. Comme je l'ai mentionné précédemment, je suppose que vous connaissez déjà assez bien SDL et C++, donc je crois que vous êtes capable de comprendre la mise en œuvre. En outre, je sais que cette solution peut devenir meilleure, donc si vous avez quelque chose à ajouter/modifier, dites-le!

Passez une bonne journée!

2

J'ai rencontré le même problème, et il s'avère que SDL opts out of momentum scroll events en désactivant le AppleMomentumScrollSupported par défaut dans le système par défaut de l'utilisateur.

Vous pouvez réactiver cette fonction dans votre application avec le bit Objective-C++ suivant, et vos événements SDL_MouseWheel seront lissés.

NSDictionary *appDefaults = [[NSDictionary alloc] initWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], @"AppleMomentumScrollSupported", 
          nil]; 
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; 
[appDefaults release];