Méthode print sur un NSView

LeLaidLeLaid Membre
mars 2009 modifié dans API AppKit #1
Salut à  vous   :P

J'ai un soucis avec l'impression d'une view.
Dans und fenêtre j'ai une view (NSView) dans laquelle je fais des jolis dessins  ;D
J'ai ajouté un bouton qui permet d'appeler le paneau d'impression.

Le hic c'est que ma view est "rognée"... Je ne vois pas comment spécifier la région à  imprimer.
Dans ma view j'ai ceci:

picture2klu.th.png

Quand je veux imprimer j'ai ceci:

picture3b.th.png

Comment fais-je? Qq'un peut m'aider?

Pascal

Réponses

  • schlumschlum Membre
    04:52 modifié #2
    Il faut re-dessiner ton ensemble de Julia dans une autre vue dédiée à  d'impression s'il est trop grand...

    Ou alors le couper en morceaux :
    http://developer.apple.com/documentation/Cocoa/Conceptual/Printing/Tasks/PaginatingViews.html
  • LeLaidLeLaid Membre
    04:52 modifié #3
    Ok mais comment puis-je savoir à  priori si ça va être trop grand?
    Au niveau de l'écran le dessin de n'est pas plus grand qu'une page A4  :(

    Bon je vais essayer...

    Merci pour la réponse

    ps. Il ne s'agit pas d'un ensemble de Julia mais d'une fractale basée sur le dessin récursif (les ensembles de Julia sont dessinés par pixel comme Mandelbrot non?)


  • schlumschlum Membre
    04:52 modifié #4
    Exact, c'est un dragon fractal, j'ai pas regardé d'assez près...  :P

    N'oublie pas qu'il y a les marges, plus grand qu'une page A4 OK, mais qu'une page A4 moins les marges ?
  • LeLaidLeLaid Membre
    04:52 modifié #5
    Bon ok, je vais essayer de réduire la taille du dessin.
    Merci.

    Ca s'appele le dragon? Ok. Cette fonction récursive est assez marante à  manipuler.
    Par exemple on peut aussi obtenir ceci:

    picture1trr.th.png
  • LeLaidLeLaid Membre
    04:52 modifié #6
    Bon, j'y arrive pas....

    J'ai essayé ceci:
    - printView est l'action qui est appelée quand je clique sur le bouton "print"
    - fractalView est une iVar de type class qui hérite de NSView.

    - (IBAction) printView: (id) sender<br />{<br />	NSPrintInfo *myPrinterSettings;<br />	myPrinterSettings = [[NSPrintInfo alloc] init];<br />	[myPrinterSettings setHorizontalPagination:NSFitPagination];<br />	[fractalView print: nil];<br />	[myPrinterSettings release];<br />}
    


    Je dois sûrement foire quelque part....

    schlum, je sais que c'est pas super exitant pour toi mais si tu peux me donner un indice....

    Pascal
  • schlumschlum Membre
    04:52 modifié #7
    Moi quand je gère de l'impression, je crée une classe dédiée (qui change son contexte graphique puis appelle le drawRect de la classe de base).
  • LeLaidLeLaid Membre
    04:52 modifié #8
    Tu aurais un eemple  8--)
    Parceque je suis plutot débutant... et j'avoue ne pas bien comprendre ta réponse  :-\\
  • schlumschlum Membre
    04:52 modifié #9
    //<br />//&nbsp; SudokuPrintView.m<br />//&nbsp; SudokuX<br />//<br />//&nbsp; Created by schlum on 15/12/06.<br />//&nbsp; Copyright schlum Corporation 2006 . All rights reserved.<br />//<br /><br />#import &quot;SudokuPrintView.h&quot;<br />#import &quot;SudokuView.h&quot;<br />#import &quot;PreferenceController.h&quot;<br /><br /><br /><br />@implementation SudokuPrintView<br /><br /><br /><br />- (id)initWithFrame:(NSRect)frame<br />{<br />&nbsp; &nbsp; if(self=[super initWithFrame:frame])<br />&nbsp; &nbsp; &nbsp; &nbsp; mainView = nil;<br />&nbsp; &nbsp; return self;<br />}<br /><br /><br /><br />- (id)initWithFrame:(NSRect)frame mainView:(SudokuView*)v;<br />{<br />	if(self=[self initWithFrame:frame]) {<br />		[v retain];<br />		[mainView release];<br />		mainView = v;<br />	}<br />	return self;<br />}<br /><br /><br /><br />- (void)dealloc<br />{<br />	[mainView release];<br />	[super dealloc];<br />}<br /><br /><br /><br />- (void)drawRect:(NSRect)rect<br />{	<br />	// Square view -&gt; get side size<br />	float size = [mainView bounds].size.width;<br />	// Get print zone parameters<br />	NSRect bounds = [self bounds];<br />	float width = bounds.size.width;<br />	float height = bounds.size.height;<br />	// Calculate minimum side<br />	float min = width&gt;height?height:width;<br />	float minPrefs = [[NSUserDefaults standardUserDefaults] floatForKey:kSDKXDefPrintMaxSize];<br />	if(minPrefs&lt;min)<br />		min = minPrefs;<br />		<br />	// Graphics context<br />	CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];<br />	<br />	// Save graphics context<br />	CGContextSaveGState(myContext);<br />	<br />	// Translate &amp; scale<br />	CGContextTranslateCTM(myContext,(width-min)/2.,(height-min)/2.);<br />	CGContextScaleCTM(myContext,min/size,min/size);<br />	<br />	[mainView drawRect:[mainView bounds]<br />		&nbsp;  forPrinting:YES];<br />	<br />	// Restore graphics context<br />	CGContextRestoreGState(myContext);<br />}<br /><br /><br /><br />- (BOOL)knowsPageRange:(NSRange*)rptr<br />{<br />	rptr-&gt;location = 1;<br />	rptr-&gt;length = 1;<br />	return YES;<br />}<br /><br /><br /><br />- (NSRect)rectForPage:(int)pageNum<br />{<br />	return [self bounds];<br />}<br /><br /><br /><br />@end
    

  • LeLaidLeLaid Membre
    04:52 modifié #10
    Merci  :-*
    Je peux aussi avoir le header?  :P
  • schlumschlum Membre
    04:52 modifié #11
    //<br />//&nbsp; SudokuPrintView.h<br />//&nbsp; SudokuX<br />//<br />//&nbsp; Created by schlum on 15/12/06.<br />//&nbsp; Copyright schlum Corporation 2006 . All rights reserved.<br />//<br /><br />#import &lt;Cocoa/Cocoa.h&gt;<br />@class SudokuView;<br /><br /><br /><br />@interface SudokuPrintView : NSView<br />{<br />	SudokuView *mainView;<br />	float drawWidth;<br />}<br /><br /><br /><br />// Constructor<br />- (id)initWithFrame:(NSRect)frame mainView:(SudokuView*)v;<br /><br /><br /><br />@end
    

  • LeLaidLeLaid Membre
    04:52 modifié #12
    Je peux aussi voir ta méthode drawRect:forPrinting de ta class SudokuView?  <3
  • schlumschlum Membre
    04:52 modifié #13
    Euh, non, y en a pour près de 2000 lignes dont une grosse partie en CoreGraphics, elle ne t'apporterait rien...
    Considère qu'elle fait juste un "NSFillRect(rect);"
  • LeLaidLeLaid Membre
    04:52 modifié #14
    Mmmm...
    Encore une question  8--) enfin, deux...

    Que fait la méthode drawRect:forPrinting que la méthode drawRect: ne fait pas?

    Où puis-je trouver la définition de la constante kSDKXDefPrintMaxSize ?

    Encore merci :)
  • LeLaidLeLaid Membre
    04:52 modifié #15
    En fait, je vois partout (dans des exemples Apple) des constantes du style kCommandStrokedAndFilledRects et je ne vois pas où ces constantes sont documentées....  :why?: :why?: :why?: :why?: :why?:
  • schlumschlum Membre
    mars 2009 modifié #16
    dans 1237385620:

    Que fait la méthode drawRect:forPrinting que la méthode drawRect: ne fait pas?


    Alors ça je peux répondre facilement  :)

    - (void)drawRect:(NSRect)rect<br />{<br />	[self drawRect:rect forPrinting:NO];<br />}
    


    C'est une petite astuce qui permet d'avoir un comportement différent si on dessine pour l'impression ou pour l'application (par exemple gérer le N&B joliment etc.)
  • schlumschlum Membre
    04:52 modifié #17
    dans 1237385620:

    Où puis-je trouver la définition de la constante kSDKXDefPrintMaxSize ?


    ça ça te sert pas, c'est un define sur une chaà®ne statique qui est une clé pour les préférences user...
    En gros ça permet de récupérer la taille max pour l'impression que l'utilisateur a choisie dans les préférences.
  • schlumschlum Membre
    04:52 modifié #18
    dans 1237386623:

    En fait, je vois partout (dans des exemples Apple) des constantes du style kCommandStrokedAndFilledRects et je ne vois pas où ces constantes sont documentées....  :why?: :why?: :why?: :why?: :why?:


    Pour ça, je vais te donner une astuce...
    Tu cherches sur Google "kCommandStrokedAndFilledRects site:developer.apple.com"  :P
  • AliGatorAliGator Membre, Modérateur
    04:52 modifié #19
    Dans Xcode :
    - Alt + Double-clic sur un nom de constante ou de méthode dans le code pour ouvrir la doc dessus
    - Pomme (Commande) + Double-clic sur un nom de constante ou de méthode dans le code pour ouvrir la définition (de la méthode dans le .h typiquement) de l'élément cliqué.

    En l'occurrence, pour le cas qui nous intéresse : kSDKXDefPrintMaxSize est une constante définie par schlum lui-même dans son projet (enfin je suppose).
    Et de même j'imagine fort que [tt]drawRect:forPrinting:[/tt] est juste une méthode à  lui dans sa classe, dans laquelle il a mis tout le code qu'habituellement on met dans [tt]drawRect:[/tt], et il aurait alors implémenté son [tt]drawRect:[/tt] simplement, en faisant appel à  sa méthode [tt][self drawRect:rect forPrinting:NO];[/tt]. Ce qui permet de capitaliser le code utilisé dans son drawRect pour le dessin à  l'écran et le code utilisé pour imprimer (pour "dessiner sur le contexte d'impression").

    Enfin ce ne sont que des suppositions, j'ai pas vu son code, mais ça me semblerait somme toutes logique.
  • schlumschlum Membre
    04:52 modifié #20
    Tout juste  :P
  • LeLaidLeLaid Membre
    mars 2009 modifié #21
    Génial ces racourcis :) Merci AliGator.

    schlum, encore merci pour ton aide... Je commence (un peu) à  comprendre mais j'ai encore des trous... En ce qui concerne drawRectForPrinting c'est limpide  :o

    Ca veut donc dire que tout le travail consitant à  faire entrer une vue sur une page doit être codé? Il n'existe pas des méthodes standard?

    J'ai essayé avec le code ci-dessous:

    - (IBAction) printView: (id) sender<br />{<br />	NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo]; //1<br />	[printInfo setHorizontalPagination: NSFitPagination]; //2<br />	[printInfo setVerticalPagination: NSFitPagination]; //3<br />	[printInfo setOrientation:NSLandscapeOrientation]; //4<br />	NSPrintOperation *printOp = [NSPrintOperation printOperationWithView: fractalView&nbsp; printInfo:printInfo];<br />	[printOp setShowPanels: YES];<br />	[printOp runOperation];<br />}
    


    Les lignes 2 et 3 semblent complètement ignorées... alors que la 4 marche correctement :(
    Pourant ces dans la doc apple que j'ai trouvé les deux lignes en questions (voir "fit to page"):

    http://developer.apple.com/documentation/Cocoa/Conceptual/Printing/Concepts/pagination.html#//apple_ref/doc/uid/20001051

    Une idée?
  • schlumschlum Membre
    04:52 modifié #22
    dans 1237453740:

    Ca veut donc dire que tout le travail consitant à  faire entrer une vue sur une page doit être codé? Il n'existe pas des méthodes standard?


    Je t'ai donné le code de la méthode standard...
    Changer le contexte avec un scale puis appeler la fonction de dessin de la vue originale !
  • LeLaidLeLaid Membre
    04:52 modifié #23
    Encore une question...  :o pour ma compréhension...

    Ton code aurais put être écrit en utilisant NSGraphicsContext et NSAffineTransform ou sont-ce des choses totalement différentes (de NSGraphicsContext, CGContextTranslateCTM et CGContextScaleCTM)?

    Quoiqu'il en soit merci bcp pour toutes ces réponses. Ca commence à  prendre forme dans ma tête  :crackboom:-
  • schlumschlum Membre
    04:52 modifié #24
    Je n'utilise pas NSAffineTransform donc je ne peux pas te répondre (je ne sais pas si on peut transformer le contexte directement avec NSAffineTransform).
Connectez-vous ou Inscrivez-vous pour répondre.