plusieurs vue avec une tool bar est-ce possible ?

chaps31chaps31 Membre
00:54 modifié dans API AppKit #1
En fait j'aimerais faire exactement ce que fais une tabView mais avec une toolBar, je l'ai déjà  vu dans des applis, des fenêtres de préférences... Est-ce réellement possible (s'agit-il réellement de toolbar) ? Et comment faire, je me vois mal empiler des view et faire des setHidden:YES / NO.

Merci.

Réponses

  • AliGatorAliGator Membre, Modérateur
    00:54 modifié #2
    Ben utilises une NSTabView, comme tu le ferais à  la base... met les objets sur chacune de tes vues de tes onglets comme tu veux... et une fois que tu es prêt, dans les propriétés du NSTabView, choisis le type "Tabless", ce qui aura pour effet de masquer les onglets dans ton interface ;)

    Après il suffit de lier le clic sur tes boutons de ta ToolBar à  la méthode [tt]selectTabViewItemAtIndex:[/tt] en passant le bon index selon le ToolBarItem cliqué pour changer "l'onglet" affiché (ou plutôt la vue associée, puisque l'onglet en lui-même n'apparaà®t pas) ;)
  • chaps31chaps31 Membre
    00:54 modifié #3
    trop fort 
  • uocramuocram Membre
    00:54 modifié #4
    Plus cool encore, avec des views de taille différente et l'animation pour passer de l'une à  l'autre (comme pour les prefs système) :

    1. crées une view par toolbarItem, par exemple generalView, printView et advancedView
    2. Dans Preferences.h : NSView  *blankView; qui sert à  vider la fenêtre lors de la transition : plus élégant
    3. dans l'awakeFromNib tu installes la 1ere view par défaut :
    - (void)awakeFromNib<br />{<br />	[self setupToolbar];<br />	[[self window] setContentSize:[generalView frame].size];<br />	[[self window] setContentView:generalView];<br />	blankView = [[NSView alloc] init];<br />	[[self window] setTitle:NSLocalizedString(@&quot;Preferences generales&quot;, nil)];<br />	[prefsToolbar setSelectedItemIdentifier:@&quot;General&quot;];<br />}<br />
    

    4. une méthode pour redimensionner la fenêtre des prefs lors du changement de view :
    - (void)resizeWindowToSize:(NSSize)newSize<br />{<br />	NSRect	aFrame;<br />	float	newHeight = newSize.height;<br />	float	newWidth = newSize.width;<br />	<br />	aFrame = [[self window] contentRectForFrameRect:[[self window] frame]];<br />	aFrame.origin.y += aFrame.size.height;<br />	aFrame.origin.y -= newHeight;<br />	aFrame.size.height = newHeight;<br />	aFrame.size.width = newWidth;<br />	aFrame = [[self window] frameRectForContentRect:aFrame];<br />	[[self window] setFrame:aFrame<br />					display:YES<br />					animate:YES];<br />}<br />
    

    5. les méthodes IBAction pour le changement de view :
    - (IBAction)general:(id)sender<br />{<br />	[[self window] setTitle:NSLocalizedString(@&quot;Preferences generales&quot;, nil)];<br />	[[self window] setContentView:blankView];<br />	[self resizeWindowToSize:[generalView frame].size];<br />	[[self window] setContentView:generalView];<br />}<br /><br />- (IBAction)printPrefs:(id)sender<br />{<br />	[[self window] setTitle:NSLocalizedString(@&quot;Preferences Impression&quot;, nil)];<br />	[[self window] setContentView:blankView];<br />	[self resizeWindowToSize:[printView frame].size];<br />	[[self window] setContentView:printView];<br />}<br /><br />- (IBAction)advancedPrefs:(id)sender<br />{<br />	[[self window] setTitle:NSLocalizedString(@&quot;Preferences avancees&quot;, nil)];<br />	[[self window] setContentView:blankView];<br />	[self resizeWindowToSize:[advancedView frame].size];<br />	[[self window] setContentView:advancedView];<br />}<br />
    

    6. nettoyer dans dealloc :
    [blankView release];
  • chaps31chaps31 Membre
    00:54 modifié #5
    :o  Merci beaucoup il faut que j'épluche tout ça ...

    Sinon question bête comment je vais pour que l'icone d'un item de la tool bar change lorsque je suis sur la vue qu'elle active, qu'elle apparaisse donc sélectionnée (grisée ou "appuyée"). J'ai beau chercher je ne trouve pas la méthode adéquat... :)beta:

    Encore merci.
  • Philippe49Philippe49 Membre
    janvier 2009 modifié #6
    [sender setEnabled:NO];

    Non, cela ne marche pas !

    setHighlighted non plus, d'ailleurs ce n'est pas dans la doc de NSToolBarItem.

    Pour l'instant à  part changer l'image ... ou supprimer la target du toolbaritem ...
    .
  • Philippe49Philippe49 Membre
    janvier 2009 modifié #7
    Ne serait-ce pas setSelectedItemIdentifier ?


    Toolbars that need to indicate item selection must specify the items that can be selected by implementing the delegate method toolbarSelectableItemIdentifiers:. This method returns an array containing the identifiers of the items that can be selected. The example Listing 1in returns all the identifiers for the preferences implementation.

    Listing 1  Example implementation of toolbarSelectableItemIdentifiers:
    - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar;
    {
        // Optional delegate method: Returns the identifiers of the subset of
        // toolbar items that are selectable. In our case, all of them
        return [NSArray arrayWithObjects:GeneralPreferences,
                                        AccountPreferences,
                                        AppearancePreferences,
                                        FontsAndColorsPreferences,
                                        AdvancedPreferences, nil];
    }
    Your application can specify the currently selected toolbar item using the method setSelectedItemIdentifier: passing the identifier for the desired toolbar item. The currently selected toolbar item is returned by the method selectedItemIdentifier:. If there is no currently selected, nil is returned.


  • chaps31chaps31 Membre
    00:54 modifié #8
    Merci, ça me semble être le bon chemin en effet, seul hic, les identifier de mes item... Introuvable dans IB... J'ai mis les Label ça ne marche pas, pas d ' outlet possible...  B) Comment ça marche ? La doc d'Apple comme souvent n'aide pas énormément... Objective-cocoa grace à  vous beaucoup plus  :P
  • Philippe49Philippe49 Membre
    00:54 modifié #9
    Si tu ne trouves pas dans IB, tu initialises par le code :
    - (id)initWithItemIdentifier:(NSString *)itemIdentifier

    Les ToolbarItem standards ont déjà  un identifier (voir Constants dans NSToolbarItem Reference)
  • AliGatorAliGator Membre, Modérateur
    janvier 2009 modifié #10
    ?? Comment ça la doc Apple n'aide pas énormément ? Tout est pourtant expliqué dedans si je ne m'abuse : Dans ce doc et et ici en particulier ;)

    Il suffit donc d'implémenter la méthode [tt]toolbarSelectableItemIdentifiers[/tt] en lui faisant retourner la liste des "ToolbarItems identifiers" que tu utilises dans ta toolbar...
    Après soit ce sont des identifieurs maison et dans ce cas tu as dû les rentrer dans IB (à  moins d'avoir créé ta ToolBar et tes items par code), soit ce sont des identifieurs prédéfinis par Apple (et tu utilise des Toolbar items classiques avec des icônes fournies par Apple) et dans ce cas ils sont indiqués dans la doc
    There are a couple of standard toolbar item identifiers that NSToolbar knows about. NSToolbarSeparatorItemIdentifier is the standard vertical line separator. NSToolbarSpaceItemIdentifier is a fixed width space. NSToolbarFlexibleSpaceItemIdentifier is a variable width space. Additionally, there are NSToolbarShowColorsItemIdentifier, NSToolbarShowFontsItemIdentifier, NSToolbarPrintItemIdentifier, and NSToolbarCustomizeToolbarItemIdentifier. These items are accessible only by identifier.
    Et de toute façon tu les as certainement choisi depuis un menu déroulant dans IB, même si la dénomination dans IB (dans ton popup) n'est certainement pas la même (plus human readable) que celle à  utiliser dans le code (constante C).

    Sino si tu veux que tous soient sélectables, tu peux sans doute toujours faire en sorte que cette delegate method retourne le NSArray retourné par visibleItems ou encore par la delegate methode toolbarAllowedItemIdentifiers...
  • Philippe49Philippe49 Membre
    00:54 modifié #11
    Tu as également l'identifier attribué par IB avec [sender itemIdentifier];

    A l'essai c'est plutôt rigolo : "6AB2AF8E-B9E5-428D-B053-96B1ECC912AA"


  • chaps31chaps31 Membre
    00:54 modifié #12
    Le problème est que je ne vois pas les identifier... :crackboom:- pour mes item de toolbar j'ai des label, c'est la même chose ?
  • Philippe49Philippe49 Membre
    00:54 modifié #13
    dans 1232471972:

    Le problème est que je ne vois pas les identifier... :crackboom:- pour mes item de toolbar j'ai des label, c'est la même chose ?

    Non les label c'est autre chose : The receiver's label, which normally appears in the toolbar
    Je n'ai pas trouvé. Si cela est, c'est un manque dans IB. Mais rien ne t'empêche
    • soit de créer toi-même ton toolbarItem avec initWIthItemIdentifier, et de le rajouter à  la toolbar dans le code.
    •  ou de positionner les item dans la toolbar par IB, puis relever les identifier attribués par IB lors d'un appel comme validateToolbarItem: qui est envoyé à  la target de l'item.
  • uocramuocram Membre
    00:54 modifié #14
    Pour qu'un item "développeur" apparaisse dans la toolbar il faut implémenter cette méthode déléguée :
    // méthode d&#39;insertion de chaque item &quot;programmeur&quot; dans la toolbar<br />- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar<br />&nbsp; &nbsp; &nbsp; itemForItemIdentifier:(NSString *)itemIdentifier<br />&nbsp; willBeInsertedIntoToolbar:(BOOL)flag<br />{<br />&nbsp; &nbsp; NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease];<br />	<br />	if ([itemIdentifier isEqual:@&quot;Infos&quot;])&nbsp; // @&quot;Infos&quot; : chaine identifiant l&#39;itemIdentifier DIFFERENT des labels (cela pourrait être @&quot;Informations&quot; ou @&quot;AProposDe&quot; ou @&quot;Zorro&quot;, mais toujours le même identifiant à  utiliser comme référence de l&#39;item dans chaque méthode déléguée de la toolbar, comme les 2 citées à  la fin du post)<br />	{<br />		// intitulé du label affiché sous l&#39;item dans la toolbar<br /> 		[toolbarItem setLabel:NSLocalizedString(@&quot;Infos&quot;, nil)];<br />		// intitulé du label affiché sous l&#39;item dans la palette de paramètrage de la toolbar<br />		[toolbarItem setPaletteLabel:NSLocalizedString(@&quot;Infos&quot;, nil)];<br />		// intitulé affiché dans le toolTip lorsque vous laissez le pointeur inactif au dessu d&#39;un item<br />		[toolbarItem setToolTip:NSLocalizedString(@&quot;Afficher les Infos&quot;, nil)];<br />		// image de l&#39;item affiché dans la toolbar (nom de l&#39;image .png .tiff .icns etc)<br />		// il suffit que cette image soit dans les ressources du mainBundle<br />		[toolbarItem setImage:[NSImage imageNamed:@&quot;Infos.tiff&quot;]];<br />		// la cible de l&#39;action déclenchée par un clic sur l&#39;item est AppController<br />		[toolbarItem setTarget:self];<br />		// l&#39;action déclenchée est showInfos:<br />		[toolbarItem setAction:@selector(showInfos:)];<br />	} <br />	if ([itemIdentifier isEqual:@&quot;AutreItem&quot;])<br />	{<br />		.........<br />	}<br />	else&nbsp; <br />	{<br />		// itemIdentifier non supporté par cocoa ou par le programmeur<br />		toolbarItem = nil;<br />	}<br />	return toolbarItem;<br />}<br />
    


    Il faut donc au minimum :
    - un label interface
    - un label palette de customization
    - un tooltip
    - une image (celle visible dans la toolbar et dans la palette) (plus compliqué quand c'est un control : NSPopUpMenu, NSSearchField, etc)
    - une cible (AppController, celle qui implémente la méthode showInfos:)
    - une action (showInfow:)
    Si il n'y a pas d'image => on ne voit rien (ou juste le label si on les affiche).
    Si il n'y a pas d'action implémentée l'itemIdentifier est inactivé.

    Il faut aussi insérer l'item dans la liste des items autorisés avec :
    - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar;
    


    et éventuellement dans la liste des items par défaut, avec :
    - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
    




  • uocramuocram Membre
    00:54 modifié #15
    et bien sur le rendre sélectable (si nécessaire, comme pour une fenêtre de préférences) comme l'a décrit Philippe49 plus haut, en l'ajoutant à  la liste des sélectables, toujours avec le même identifier :
    - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar;<br />{<br />&nbsp; &nbsp; return [NSArray arrayWithObjects:<br />		@&quot;General&quot;,<br />		@&quot;Advance&quot;,<br />		@&quot;Infos&quot;,&nbsp;  // item référencé par son identifiant<br />		nil];<br />}<br /><br />
    

  • chaps31chaps31 Membre
    00:54 modifié #16
    Bigre, merci, y'a du travail pour les programmeur Apple car si je comprend bien faire une toolbar avec des items perso passe obligatoirement par xcode, adieu IB.... Je vais m'y atteler, merci encore.

    Quoique... Ma toolbar purement IB fonctionne, il y a les images les labels... mais le seul truc non géré par IB est la modification de l'apparence après un clic... En mettant tout via Xcode les images se modifieront comme on le voit dans de nombreuses fenêtre de préférence où l'icone prend un aspect "enfoncé" ?
  • AliGatorAliGator Membre, Modérateur
    00:54 modifié #17
    Et tu n'aimes pas ma solution pour "gruger" un peu ?
    Non testée en vrai, mais je ne vois pas pourquoi ça ne marcherait pas...

    L'idée c'est donc juste que si tu veux que tous tes ToolBarItems soient "selectable", il suffit de faire renvoyer par la méthode [tt]toolbarSelectableItemIdentifiers[/tt]... la liste de tous les identifiers possibles de ta ToolBar ! Donc retourne ce [toolbar visibleItems] ou encore [delegate toolbarAllowedItemIdentifiers], non ?
    Ca ne fait qu'une seule méthode à  implémenter, et tout le reste de ta ToolBar peut continuer à  être gérée dans IB.
  • chaps31chaps31 Membre
    00:54 modifié #18
    Avant tout, un grand merci à  tous, grâce à  toutes vos intervention j'ai résolu le problème.

    1) J'ai créé ma tollbar avec mes icones perso via IB uniquement.
    2) J'ai créé dans xcode une classe de gestion de ma toolbar et désigné cette classe comme delegate de ma toolbar.
    3) J'ai implémenté dans cette classe la méthode delegate :
    - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar<br />{	<br />	int i;<br />	NSMutableArray *idTab=[[NSMutableArray alloc] init];<br />	for(i=0;i&lt;[[toolbar visibleItems] count];i++)<br />	{<br />		if(![[[[toolbar visibleItems] objectAtIndex:i] itemIdentifier] isEqualTo:@&quot;NSToolbarSeparatorItem&quot;])[idTab addObject:[[[toolbar visibleItems] objectAtIndex:i] itemIdentifier]];<br />	}<br />	return idTab;<br />}
    


    Ca marche impec j'ai mes jolies icônes qui s'enfonce.  :adios!:

    NB : Seul hic la méthode déléguée est appelée au clic sur un item de la toolbar, donc lors du premier affichage l'item par défaut n'est pas dans son état "enfoncé", je n'ai pas réfléchi mais à  mon avis cela ne va pas être bien difficile à  résoudre.  ;)
  • AliGatorAliGator Membre, Modérateur
    00:54 modifié #19
    Salut,

    1) J'avais bien pensé aux séparateurs (et dans ce cas quitte à  les éliminer, autant peut-être éliminer aussi les items de type Space et FlexibleSpace ?) mais je ne suis même pas sûr qu'il faille les supprimer du tableau que tu retournes en fait : étant donné leur statut un peu particulier, je pense qu'ils ne seront jamais sélectionnables, qu'ils soient dans le tableau retourné par [tt]toolbarSelectableItemIdentifiers[/tt] ou pas. Enfin bien sûr ça reste à  vérifier en testant.

    En fait je pense que quand tu cliques sur un ToolbarItem, Cocoa appelle cette delegate method, puis regarde si l'identifier du ToolbarItem cliqué se trouve dans ce tableau pour savoir s'il doit le sélectionner ou pas. Et comme un NSToolbarSeparatorItem n'est pas cliquable...

    Donc si c'est bien comme ça que ça fonctionne, ça n'a pas d'incidence de laisser les identifieurs de séparateur dans le tableau, autant retourner directement [tt][toolbar visibleItems][/tt] sans autre forme de procès

    2) Sinon si tu gardes ton code, d'une part je te conseille d'utiliser la constante [tt]NSToolbarSeparatorItemIdentifier[/tt] (cf doc de NSToolbarItem) plutôt que la chaà®ne @NSToolbarSeparatorItem. C'est plus propre, ça évite les problèmes si un jour la valeur change, et surtout ça te signale le problème si tu fais une faute de frappe dans la constante

    3) De plus, dans ton code, tu crées un NSMutableArray mais tu ne respectes pas les règles de base de gestion mémoire. Il te manque un autorelease sur ton idTab. Ou alors au lieu de le créer avec alloc/init (et de rajouter donc l'autorelease), utilise le constructeur de commodité "array" qui est équivalent à  alloc/init/autorelease.
  • chaps31chaps31 Membre
    00:54 modifié #20
    1) Je le note...
    2° Je renote... moins vite...
    3) je note aussi  :P

    Merci  o:)

    En effet petit oubli.. hum et mon projet va nécessiter autant de mémoire que Vista... Pardon de dire des grossièretés  :P
  • uocramuocram Membre
    00:54 modifié #21
    Sinon en utilisant les tags dans les toolbarItems, tu peux savoir précisément les items à  rendre sélectables (par ex. en "tagant" les toolbarItems à  sélectionner de 1000 pour le 1er à  100x, par défaut dans IB ils sont mis à  -1) :
    - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar;<br />{<br />	NSMutableArray	*selectableItemsArray = [[[NSMutableArray alloc] init] autorelease];<br />	NSArray			*visibleItemsArray = [toolbar visibleItems];<br />	int				i, count = [visibleItemsArray count];<br />	for (i = 0; i &lt; count; i++)<br />	{<br />		NSToolbarItem	*item = [visibleItemsArray objectAtIndex:i];<br />		int	itemTag = [item tag];<br />		if (itemTag == 1000 + i)<br />		{<br />			[selectableItemsArray addObject:[item itemIdentifier]];<br />		}<br />	}<br />	return selectableItemsArray;<br />}<br /><br />
    

  • uocramuocram Membre
    00:54 modifié #22
    Cela permet d'en garder certains non sélectables (je ne sais pas si cela à  un intérêt mais bon, c'est plus précis)
  • uocramuocram Membre
    00:54 modifié #23
    Et pour sélectionner le 1er au démarrage de l'appli :
    - (void)selectFirstToolbarItem:(NSToolbar *)toolbar<br />{<br />	NSArray			*visibleItemsArray = [toolbar visibleItems];<br />	int				i, count = [visibleItemsArray count];<br />	for (i = 0; i &lt; count; i++)<br />	{<br />		NSToolbarItem	*item = [visibleItemsArray objectAtIndex:i];<br />		int	itemTag = [item tag];<br />		if (itemTag == 1000)<br />		{<br />			[toolbar setSelectedItemIdentifier:[item itemIdentifier]];<br />		}<br />	}<br />}<br /><br />- (void)awakeFromNib<br />{<br />	[self selectFirstToolbarItem:[mainWindow toolbar]];<br />}<br /><br />
    


    C'est le même problème pour la méthode déléguée :
    - (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem;
    



  • uocramuocram Membre
    00:54 modifié #24
    Ou alors autre possibilité :

    les IBOutlets connectés dans IB :
    IBOutlet NSToolbarItem	*firstItem;<br />	IBOutlet NSToolbarItem	*secondItem;<br />
    


    et la méthode de sélection au démarrage devient par exemple :
    - (void)selectFirstToolbarItem:(NSToolbar *)toolbar<br />{<br />	[toolbar setSelectedItemIdentifier:[firstItem itemIdentifier]];<br />}<br /><br />
    


    Mais c'est plus de code et moins "générique".


  • chaps31chaps31 Membre
    00:54 modifié #25
    Le problème est : comment relier les outlet avec les objets dans IB ??? Ca ne marche pas avec une toolbar ou ses items... B)
  • uocramuocram Membre
    00:54 modifié #26
    Il faut connecter dans le panel de création de la Toolbar (qui correspond aux items "allowed") ouvert comme dans l'image ci-dessous.
    Les items visibles dans la Toolbar (panel fermé) sont les items par défaut.
    Tout le paramètrage se fait dans le panel, sauf, actuellement, le choix selectable ou non et la validation ou non des items qui demandent encore du code. Mais cela peut changer dans les prochaines versions d'IB.
  • chaps31chaps31 Membre
    janvier 2009 modifié #27
    Ca marche pas.... Les items ne se sélectionnent pas lorsque je "tire" le lien dans IB  B)

    EDIT : Quand je balade le lien dans IB il me semble qu'il y a un beau bug, un rectangle de sélection apparait mais il n'encadre rien... il est dans le vide avec dessus le nom d'un de mes item de toolbar, et lorsque je passe sur les items il ne se passe rien...
  • uocramuocram Membre
    00:54 modifié #28
    S'il n'est pas lourd, poste ton projet pour inspection (c'est plus facile quand on n'a pas le nez dedans).
Connectez-vous ou Inscrivez-vous pour répondre.