PreferencesPane: afficher la NSView correspondant depuis une toolbar

  • Créateur du sujet Créateur du sujet 6ix
  • Date de début Date de début

6ix

Membre confirmé
12 Juillet 2005
28
0
40
Bonjour,

J'ai décidé de créer une NSToolbar afin de naviguer dans les préférences d'un petit programme; jusque-là pas de souci, le tout marche correctement. Par contre, plutôt que d'assigner une action lorsque l'on appuie sur un bouton de la barre d'outils, j'aimerais évidemment que cela affiche dans ma fenêtre le contenu correspondant à ce bouton.

Je suis parti dans l'idée de faire une fenêtre vide, où viennent se mettrent des NSView différentes; lorsque l'on appuie sur un bouton de la toolbar, la fenêtre charge la bonne NSView grâce à la méthode changeView: (NSString ")viewName que j'ai faite. Là où je câle, c'est au moment d'assigner la bonne action pour la toolbar avec setAction:@selector(uneMéthode) ; en effet, afin de savoir quelle NSView charger, je souhaiterais envoyer un argument à ce moment-là, ce qui donnerait:
[item setAction:@selector(changeView: @"maVue")];
Oui mais voilà, impossible de mettre un paramètre avec @selector... (du moins je ne sais pas comment!)
Ce qui m'embête, c'est que la méthode changeView n'a pas moyen de tester elle-même depuis quel bouton de la toolbar l'action est envoyée, donc je ne vois pas vraiment de solution de rechange de ce côté-ci.
Qqun aurait-il une idée?

Je suis tombé sur un post sur ce forum à ce propos qui parlait de MVPreferences je crois, malheureusement il date de 2ans et les liens ne fonctionnent plus. Si qqun a une solution du genre...

Merci pour votre aide
 
Salut 6ix,

Toutes les méthodes "action" sont de la forme
Bloc de code:
-(void) buttonAction:(id) object
object étant le bouton ayant déclanché l'action.

Il suffit donc de comparer cet objet avec les différents boutons de la toolbar:
Bloc de code:
if(object==button1)
  // bouton 1 sélectionné
else if(object==button2)
  // bouton 2 sélectioné
....

Une autre méthode est d'utiliser les tags pour identifier les boutons cliqués et si tu utilises un NSTabView (en mode tabless) pour les views de ton panneau de préférences, ça devient super fastoche :)

Il faut bien sûr assigner un tag pour chaque bouton de la toolbar:
[button1 setTag:100];
[button2 setTag:101];

et ensuite dans la méthode action:
Bloc de code:
-(void) toolbarButtonAction:(NSButton*) button
{
  [ tabViewContenantLesVues selectTabViewItemAtIndex:[button tag]-100];
}
 
  • J’aime
Réactions: molgow
Je t'ai peut-être mal compris, mais la 1e solution ne m'aide guère, car la méthode qui change la NSView n'est pas la méthode assignée directement au bouton de la toolbar:
Bloc de code:
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar
    itemForItemIdentifier:(NSString *)itemIdentifier
    willBeInsertedIntoToolbar:(BOOL)flag
{
    NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
    
    if ( [itemIdentifier isEqualToString:@"Bouton1"] ) {
		[item setLabel:@"Bouton1"];
		[item setPaletteLabel:[item label]];
		[item setImage:[NSImage imageNamed:@"bouton1"]];
		[item setTarget: self];
		[item setAction:@selector(changeView:)];  // <--- ICI
    }

Tu remarques que cette méthode appelle changeView; cette métode-ci a un paramètre (=le nom du bouton), et affiche la View correspondant à ce bouton. Le problème n'est donc finalement pas de récupérer le nom du bouton, mais plutôt de le passer en paramètre à la méthode changeView...
Il suffit donc de comparer cet objet avec les différents boutons de la toolbar:
Si je pose cette condition dans la méthode changeView, celle-ci ne pourra pas identifer "object".

Par contre je vais essayer ta 2e idée voir ce que cela donne :)
 
Dans ta méthode changeView tu reçois quoi, un toolbarItem ou un bouton ?
Bloc de code:
-(void) changeView:(id) sender
{
  NSLog(@" sender %@",sender); // ???
}
 
Cette méthode n'est pas une action, dans le sens où elle ne reçoit pas d'argument de l'interface graphique; c'est une méthode que je rajoute par après, qui prend une NSString comme argument (qui permet de comparer depuis quel bouton de la toolbar il est envoyé); à noter que cet argument pourrait être le bouton lui-même, qu'il faudrait récupérer comme tu l'as cité plus haut.


Bloc de code:
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar
    itemForItemIdentifier:(NSString *)itemIdentifier
    willBeInsertedIntoToolbar:(BOOL)flag
{
    NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
    
    if ( [itemIdentifier isEqualToString:@"Bouton1"] ) {
		[item setLabel:@"Bouton1"];
		[item setPaletteLabel:[item label]];
		[item setImage:[NSImage imageNamed:@"bouton1"]];
		[item setTarget: self];
		[item setAction:@selector:(changeView:)];  // <-- je mettrai en argument: @"bouton1"
    }
    else if ( [itemIdentifier isEqualToString:@"Bouton2"] ) {
		[item setLabel:@"Bouton2"];
		[item setPaletteLabel:[item label]];
		[item setImage:[NSImage imageNamed:@"bouton2"]];
		[item setTarget: self];
		[item setAction:@selector:(changeView:)];   // <-- je mettrai en argument: @"bouton2"
    }


    return [item autorelease];
}
Bloc de code:
- (void) changeView:(NSString *)viewName
{
	if([viewName compare:@"bouton1"] == NSOrderedSame) {
		[prefWindow setContentView: view1];
	}
	else if([viewName compare:@"bouton2"] == NSOrderedSame) {
		[prefWindow setContentView: view2];
	}
}
 
:heu:

Petit exemple vite fait (en java ;) )
Bloc de code:
/* Controller */

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;

public class Controller {

	
	public NSWindow window; // outlet
	public NSTabView tabView;
	
	private NSToolbar toolbar=new NSToolbar("FileBrowserToolBar");
	private NSDictionary toolbarDic=new NSDictionary
							(
							new Object[] {
										new NSToolbarItem("P1"),
										new NSToolbarItem("P2")
										 },
							new Object[] {
										"P1",
										"P2"
										 }	
						
							);
										 
	
	public void awakeFromNib()
		{
		// panneau 1
		NSToolbarItem item=(NSToolbarItem)toolbarDic.objectForKey("P1");
		NSButton b=new NSButton(new NSRect(0,0,32,32));
		b.setImage(NSImage.imageNamed("Disc Info"));
		b.setBordered(false);
		b.setTag(100);
		item.setView(b);
		item.setMinSize(new NSSize(32,32));
		item.setMaxSize(new NSSize(32,32));
		item.setEnabled(true);
		item.setLabel("Panneau 1");
		item.setAction(new NSSelector("buttonAction",new Class[]{Object.class}));
		item.setTarget(this);
		
		// panneau 2
		item=(NSToolbarItem)toolbarDic.objectForKey("P2");
		b=new NSButton(new NSRect(0,0,32,32));
		b.setImage(NSImage.imageNamed("Disc Right Arrow"));
		b.setBordered(false);
		b.setTag(101);
		item.setView(b);
		item.setMinSize(new NSSize(32,32));
		item.setMaxSize(new NSSize(32,32));
		item.setEnabled(true);
		item.setLabel("Panneau 2");
		item.setAction(new NSSelector("buttonAction",new Class[]{Object.class}));
		item.setTarget(this);
		
		toolbar.setDelegate(this);
		toolbar.setAllowsUserCustomization(true);
		toolbar.setAutosavesConfiguration(true);
		window.setToolbar(toolbar);
		
		
		}

private void ____TOOLBAR_ACTIONS____() {}

	public void buttonAction(NSView o)
		{
		System.out.println("tag du bouton de la methode action:"+o.tag());
		tabView.selectTabViewItemAtIndex(o.tag()-100);
		}

private void ____TOOLBAR_DELEGATES____() {}

	public NSArray toolbarAllowedItemIdentifiers(NSToolbar toolbar)
		{
		return toolbarDic.allKeys();
		}
	
	public NSArray toolbarDefaultItemIdentifiers(NSToolbar toolbar)
		{
		return  toolbarDic.allKeys();
		}

	public NSToolbarItem toolbarItemForItemIdentifier(NSToolbar toolbar, String itemIdentifier, boolean flag)
		{
		return (NSToolbarItem)toolbarDic.objectForKey(itemIdentifier);
		}




}

Si tu tiens à garder tes vues séparées, il suffit de faire:
Bloc de code:
public void buttonAction(NSView o)
		{
               if(o.tag()==100)
                    // setContentView(vue1)
              else if // etc
		
		}