7
votes

Comment créer une fenêtre transparente avec des boutons non rectangulaires?

Je cherche à faire une fenêtre personnalisée qui ressemblerait à ceci comme ceci (peu importe la photo rapide Photoshop):

text alt p>

Le problème principal que j'ai N'a pas de faire la fenêtre transparente (bien que je suppose que toutes les informations sont les bienvenues!), mais que je veux pouvoir cliquer sur la partie visible des boutons. Par exemple, si je clique uniquement en dehors du haut à gauche de la touche "5", je souhaite inscrire un clic sur le bouton "1" et non le bouton "5", même si j'ai cliqué dans la boîte de sélection de boutons 5 ". Et si je clique juste à l'époque du "coin" du bouton "1", je veux qu'il clique sur tout ce qui est sous ma fenêtre et non sur le bouton. J'ai aussi besoin de pouvoir redimensionner cette fenêtre et les images des boutons doivent redimensionnez-les avec eux. P>

Je pensais à utiliser un Nswindow transparent avec des Nsbuttons transparents contenant des Pngs avec alpha pour chaque bouton, mais je pense que le Les boutons qui se chevauchent seront un problème. P>

J'ai également entendu parler des applications telles que Bowtie, Sweetfm et d'autres personnes utilisant WebKit pour afficher leurs interfaces. Si cela est une possibilité d'au moins 10,3 ce serait intéressant, mais je ne sais pas comment cela fonctionnerait non plus. P>

J'ai regardé autour des masques, des zones ou quelque chose comme ça, mais je n'ai pas tout trouvé encore. Je mettrai à jour ce message comme je trouve plus d'informations (si je le fais!). P>

Toute astuce sur la procédure à suivre? P>

(Notez que je travaille sur 10.4 et Idéalement em> Je dois aussi prendre en charge des versions plus anciennes de Mac OS X.) P>

(aussi, j'ai trouvé l'exemple "Windows arrondi" sur le site d'Apple Dev. Site, mais cela ne fonctionne pas 10.4 plus, donc je ne suis pas sûr que c'est la voie à suivre.) p>

Merci d'avance! P>

MISE À JOUR: H1>

(voir Mise à jour 2, Ce problème est résolu maintenant) em> p>

OK maintenant, je dispose d'une question légèrement différente (mais pas non liée). Ce que je faisais jusqu'à présent, c'est ceci: p>

J'ai opté pour avoir fait un contrôle personnalisé que je pourrai utiliser pour chacun de mes boutons: P>

1- Sous-classe NSControl et Drawrect Drawrect , MouseUp, Mousedragged et Mousedown. De cette façon, je peux obtenir le comportement que je veux lorsque vous faites glisser sur un bouton (déplacez la fenêtre). P>

2- Chargez des images pour chaque bouton étage (même forme mais on est assombri) dans des nsimages et les attire dans le Afficher en utilisant CompossitifsTopoint: FromRect: opération: code> si nécessaire. Les images sont 185 x 185 strong> pixels fichiers PNG avec alpha forts> exportés depuis photoshop. P>

3- Obtenez la représentation bitmap de Nsimage: p>

NSPoint mouse = [self convertPoint:[theEvent locationInWindow] fromView:nil]; // Returns the correct x and y positions on the control (i.e: between 0 and 185 for each axis).

NSColor *colorUnderMouse = [[[unpressedImage representations] objectAtIndex:0] colorAtX:mouse.x y:mouse.y];
float alpha = [colorUnderMouse alphaComponent];


0 commentaires

6 Réponses :


3
votes

Qu'en est-il de remplacer les méthodes d'événement NSresponder ( MouseUp: , MouseDown: , etc) dans vos boutons personnalisés (probablement que vous seriez Sous-classement nscontrol ou nsbutton pour les faire)? Dans ces méthodes, vous pouvez calculer correctement votre rectangle de liaison (ou votre cercle, dans ce cas) et effectuez un test de toucher simple avec les coordonnées du clic pour voir si le clic doit être manipulé.

Vous pourriez également être en mesure de trouver de l'aide dans les documents de traitement des événements d'Apple, en particulier sur Evénements de souris et Vues personnalisées .


3 commentaires

Merci, ce serait une possibilité pour le bouton central, mais avec les boutons extérieurs qui seraient plus difficiles et nécessitent un code de vérification des limites ... Et si je change de position de mon bouton pour une raison quelconque? (Ce n'est pas un projet personnel, donc cela peut être sujet à changement malheureusement), je devrais alors réécrire la majeure partie de mon code de contrôle de sélection ... Y aurait-il un moyen de le faire avec une sorte de masque? Dites "laissez le clic passer à travers si le bitmap est transparent à ce stade"?


Je ne pense pas que vous puissiez le faire avec un masque comme vous pensez (détection de transparence, etc.). Ce sont des formes assez basiques (cercles partiels pour les boutons extérieurs sous un cercle complet pour l'intérieur). Vous pouvez accéder aux coordonnées et aux dimensions actuelles des commandes en code et utilisez celles-ci pour calculer les limites de frappe afin que vous ne soyez pas du cap de rien. Utilisez le fait que le bouton central est en haut à votre avantage.


Il est possible d'utiliser la détection de transparence (alpha) et cela fonctionne très bien et bien que la méthode que j'utilise pour le moment est de 10,4+, il existe un moyen de le faire en utilisant quelque chose d'autre que Coloratx: Y: Tant que vous avez accès à Le bitmaprep, comme Mahboudz a souligné.



2
votes

Qu'en est-il de tout faire un seul contrôle? Cela pourrait créer un petit complexe peu complexe, mais on dirait que vous faites un dessin personnalisé quand même.

Si vous l'avez fait comme un simple contrôle, vous pouvez d'abord vérifier et voir si le point de clic est dans le cercle central. Si ce n'est pas le cas, tout ce que vous avez à faire est d'identifier quel quadrant il est de savoir quel "bouton" appartient (tout en vérifiant également que le clic s'adapte dans le cercle extérieur).

Alternativement, vous pouvez créer une vue transparente sur vos boutons qui capture les événements de clic et les transmet à la commande appropriée en fonction de la logique que je viens de spécifier.


0 commentaires

2
votes

Semblable à la réponse de Marc W, dans votre propre méthode d'événement, vous pouvez vérifier la valeur alpha du clic sur le bitmap et ignorer si l'alpha est inférieur à une certaine valeur.

Pour obtenir le bitmap, Lisez ceci .

Vous devez maintenant avoir un bitmap Pointeur comme celui-ci (pseudocode - vous devrez remplir les morceaux): xxx

Alors, vous pouvez le faire pour obtenir le pixel qui vous intéresse, et testez-le : xxx

Cela ouvre quelques possibilités pour vous, comme ayant une bague autour de votre cercle intérieur inerte et n'appartiendrons à aucun des quadrants ou du cercle moyen . Bien sûr, il y a toujours d'autres moyens de faire ces choses sans recourir à Pixel-Wrangling: -)


5 commentaires

Cela ressemble davantage à ce que je voudrais faire, de cette façon si la forme de mon contrôle change, il devrait s'ajuster automatiquement. Existe-t-il une méthode de vérification de l'opacité d'une image à un point spécifique de l'image d'un bouton? (Je pense que ce serait moins de travail pour sous-classer un nsbutton au lieu de sous-classement Nsview et dessin manuellement, mais s'il n'est pas possible de vérifier l'alpha avec un bouton, je vais très probablement aller avec Nsview).


J'ajoute que les informations de manutention bitmap dans ma réponse.


Merci beaucoup, je vais voir ce que je peux faire avec ça!


Bien que j'utilise maintenant l'API de cacao pour la détection alpha, le fait que vous avez mentionné le contexte bitmap m'a signalé dans la bonne direction. Je vais aussi regarder votre code lorsque je dois supporter plus de 10.4, mais pour l'instant Coloratx: Y: sur le NSBITMAPIMAGEREP fonctionnera. Merci pour l'aide!


Je ne savais même pas sur Coloratx!



1
votes

Si vous générez les formes dans le code à l'aide de NsBezierPath, testez si un clic est à l'intérieur de l'une des formes est une doublure: envoyer la forme A Point de contient: Message.

Je ferais cela une vue unique qui possède les cinq chemins. Lorsque vous dessinez, dessinez le Centre un dernier; Lorsque vous répondez à un événement de la souris, testez-le d'abord. Donnez à cette vue une propriété d'action par segment et éventuellement une cible par segment également, en fonction de ce dont vous avez besoin.


1 commentaires

Votre solution est très intéressante, je ne savais pas que vous pourriez frapper le test NsBezierPaths comme celui-ci. Cela viendra sûrement utile. Mais dans mon cas (avec les formes changeant une propagatique non négligeable), je pense que ce serait beaucoup de réécrire si je change jamais quelque chose. Je vais d'abord essayer le bitmap alpha-tester d'abord et si cela ne fonctionne pas comme j'espère que ça va essayer ça. Merci d'avoir pris le temps de répondre à ma question!



1
votes

Vous auriez besoin de faire deux choses:

  1. Remplacement de Nsview's Wittest: Méthode pour renvoyer NIVE Chaque fois que le clic est en dehors de l'image, le clic à cette vue est ignoré et passée à la vue qui le chevauche.
  2. Remplacement de Mousedown: et implémentez votre propre boucle de suivi de la souris (en utilisant NSVENTVERTrackingRunLoopMode) qui vérifie également si le point est dans une zone non transparente. Nsbitmapimagere ou Nsimage a un ColorAtX: Y: méthode ou quelque chose comme un chapeau que vous pouvez utiliser pour ces derniers.

0 commentaires

0
votes

solution MU ne fonctionne que sur des boutons non intersect. J'ai un bouton non rectangulaire, qui doit changer d'images de gris au vert.

Bouton d'échantillon Je change de bouton de gradient régulier comme celui-ci

propriétés

c'est tout. J'espère que cela aident quelqu'un.


0 commentaires