Mon NSCursor change tout seul !

ChachaChacha Membre
octobre 2005 modifié dans API AppKit #1
Salut,

(Attention, question longue, car j'ai mis toutes les explications du contexte au début; le code présenté marche, il est juste là  pour l'exhaustivité)
La question est : j'ai tout bien fait comme y faut, mais le méchant Cocoa change mon curseur tout seul sans que je lui demande. Pourquoi ?

Pour ShapeOnYou, http://www.objective-cocoa.org/forum/index.php?topic=1251.msg13528#msg13528, je me suis penché sur le problème du changement de curseurs.
Si je suis en mode "drag"n drop", j'ai un curseur normal; en mode "rotate", une main; et en mode "fill" une croix.
Comme je veux que ce changement ne se fasse que dans la zone de dessin, j'ai donc surchargé "mouseEntered" et "mouseExited" de cette façon:
<br />-(void) mouseEntered:(NSEvent*)event<br />{<br />  NSLog(@&quot;mouse entered&quot;);<br />  if (cursorMode == CURSOR_MODE_FILL)<br />  {<br />    [[NSCursor crosshairCursor] push];<br />    NSLog(@&quot;[[NSCursor crosshairCursor] push]&quot;);<br />  }<br />  else if (cursorMode == CURSOR_MODE_ROTATE)<br />  {<br />    [[NSCursor openHandCursor] push];<br />    NSLog(@&quot;[[NSCursor openHandCursor] push]&quot;);<br />  }<br />  else<br />  {<br />    [[NSCursor currentCursor] push];<br />    NSLog(@&quot;[[NSCursor currentCursor] push]&quot;);<br />  }<br />}<br /><br />-(void) mouseExited:(NSEvent*)event<br />{<br />  NSLog(@&quot;mouse exited&quot;);<br />  [NSCursor pop];<br />  NSLog(@&quot;[NSCursor pop]&quot;);<br />}<br />


Bien sûr, j'ai ajouté un tracking rectangle (addTrackingRect...) et ça marche très bien.

Cependant, on peut changer le mode d'édition (drag'n drop/rotate/fill) avec un raccourci clavier, donc le curseur peut se trouver dans la NSView à  ce moment là . Il faut donc prévoir de pouvoir le rafraà®chir lors d'un changement de mode; c'est chose faite :

<br />-(IBAction) changeCursorMode:(id)sender<br />{<br />  NSLog(@&quot;changeCursorMode&quot;);<br />  sender = sender ? sender : cursorModeSelector;<br />  cursorMode = (cursor_mode_t) [[sender selectedCell] tag];<br />  NSPoint p = [[self window] mouseLocationOutsideOfEventStream];<br />  p = [self convertPoint:p fromView:nil];<br />  if (NSPointInRect(p, [self bounds]))<br />  {<br />    if (cursorMode == CURSOR_MODE_FILL)<br />    {<br />      [[NSCursor crosshairCursor] set];<br />      NSLog(@&quot; [[NSCursor crosshairCursor] set]&quot;);<br />    }<br />    else if (cursorMode == CURSOR_MODE_ROTATE)<br />    {<br />      [[NSCursor openHandCursor] set];<br />      NSLog(@&quot; [[NSCursor openHandCursor] set]&quot;);<br />    }<br />    else<br />    {<br />      [[NSCursor arrowCursor] set];<br />      NSLog(@&quot; [[NSCursor arrowCursor] set]&quot;);<br />    }<br />  }<br />}<br />


Encore une subtilité : quand on a plusieurs documents qui se chevauchent, si on en ferme un avec Pomme-W, la souris peut se retrouver au milieu de la NSView du document qui était dessous. Il faut donc encore prévoir de rafraà®chir le curseur dans ce cas.
<br />-(void) windowDidBecomeMainNotification:(NSNotification*)notification<br />{<br />  MyDocument* myDocument = [[[notification object] windowController] document];<br />  if (myDocument)<br />    [[myDocument myView] changeCursorMode:nil];//update<br />}<br />




>Le problème commence ici<


Avec tout ça, je m'attendais à  ce que tout marche bien. Et en effet, tout marche bien, sauf dans un cas, c'est à  l'ouverture d'un nouveau document (soit au démarrage de l'appli, soit avec Pomme-N).
Dans ce cas, dans le windowDidBecomeMain, myDocument a bien une valeur non nil, changeCursorMode est bien appelé, le curseur change bien pendant une fraction de seconde, mais il redevient une flèche ensuite.
Et je ne comprends pas pourquoi il redevient une flèche : aucun message n'apparaà®t dans la console qui montre que ce soit mon code qui en est responsable.

Pour forcer le rafraà®chissement, il suffit de sortir/rentrer dans la vue, ou simplement déclencher le "changeCursorMode" avec un raccourci clavier (dans ce cas, avec Pomme-1 2 ou 3, ou <espace>)
Si vous n'avez pas très bien compris ce qui se passe, vous pouvez essayer de lancer le programme http://www.objective-cocoa.org/forum/index.php?topic=1251.msg13528#msg13528
J'ai laissé les messages de debug dans la console.

Merci !

+
Chacha

Réponses

  • octobre 2005 modifié #2
    Pourquoi tu n'utilises pas les méthodes 'standards' de NSView pour la gestion des curseurs?
    - addCursorRect:cursor:
    - removeCursorRect:cursor:
    - discardCursorRects
    - resetCursorRects
  • ChachaChacha Membre
    12:41 modifié #3
    dans 1129105838:

    Pourquoi tu n'utilises pas les méthodes 'standards' de NSView pour la gestion des curseurs?

    Parce que cela ne me permet pas de changer le curseur en fonction du mode d'édition !

    +
    Chacha
  • elfelf Membre
    12:41 modifié #4
    Euh et si tu essayais de lancer un NSTimer qui fait l'action que tu lance dans windowDidBecomeMain (c'etais ca non?) et qui une seconde ou une demi plus tard execute l'action, peut etre ca viens du fait que ton app c'est pas encore lance...
Connectez-vous ou Inscrivez-vous pour répondre.