NSView redraw?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • NSView redraw?

    moin,
    ich habe eine zeichenfläche gemacht (abgeleitet von NSView) mit drawRect funktion. Funzt soweit aber wenn ich jetzt ein Polygon (NSBezierPath) erstellt habe - wie bekomme ich dieses nun auf meine Zeichenfläche. Hab das zugrundeliegende System glaube falsch verstanden...



    mfg
    d

    Quellcode

    1. - (void)drawRect:(NSRect)rect
    2. {
    3. NSBezierPath *theGround = [NSBezierPath bezierPathWithRect:rect];
    4. NSColor *theBGColor = [NSColor colorWithDeviceRed:(float)0.4 green:(float)0.8 blue:(float)0.1 alpha:(float)1.0];
    5. [theBGColor set];
    6. [theGround fill];
    7. theBGColor = [NSColor colorWithDeviceRed:(float)0.3 green:(float)0.3 blue:(float)0.0 alpha:(float)1.0];
    8. [theBGColor set];
    9. [theGround setLineWidth:4.];
    10. [theGround stroke];
    11. }
    Alles anzeigen
  • RE: NSView redraw?

    also: ^^

    der Parameter "rect" enthält immer die komplette zu zeichenende und sichtbare(!) Fläche

    sprich du zeichnest mit deinem pfad als erstes eine Rechteck über deine komplette sichtbare fläche
    und dann willst du noch eine rahmen ringsrum zeichnen? der liegt dann ja genau auf der sichtbarkeitsgrenze...

    mach einfach mal zum test dein rect in dem pfad kleiner damit du siehst wo er gezeichnet wird

    btw es ist nciht notwendig in den NSColor parametern immer ein cast auf (float) zu machen wenn du die numerale als 0.0 oder 0.3 sprich mit einem dezimalpunkt angibst erkennt der compiler das automatisch als floating point value ^^

    achja - unter umständen mußt du deinem View mitteilen das er sich neu zeichnen soll:

    ein [myView setNeedsDisplay:YES]; an geeigneter stelle (nicht in drawRect: !!) markiert deinen view das er sich neu zeichnen soll

    ansonsten mal das fenster mit dem view in den hintergrund schieben und wieder vor holen ^^; um ganz schnell zu sehen ob was passiert...
    snafu
    :() { :|: &};:
    sometimes i dream in hex
    Obey gravity! Because its a law!
  • ??

    zeichnen kannst du immer nur in der drawRect: methode

    das heißt du kannst auch "von aussen" darauf zeichnen in dem du lockFocus und unlockFocus messages sendest - was aber in deinem fall etwas unnötig ist

    simpel ausgdrückt:

    in deiner drawRect: machst du ein [mypath stroke];

    und in deiner "punktesamelmethode" setzt du deine Punkte [myPath lineToPoint: newPoint];

    ...

    drawRect: wird imemr aufgerufen wenn das system möchte das dein View sich zeichnet

    also sollte darin alles was gezeichnet werden soll dort drinn stehen

    verwaltungskram oder eventauswertung macht man in eignene methoden setzt entsprechende fieldvariablen neu etc.

    zumal du nicht weißt wann dein view immer wieder neu gezeichnet werden muß
    snafu
    :() { :|: &};:
    sometimes i dream in hex
    Obey gravity! Because its a law!
  • Komisch, bei mir geht das einfach nicht!

    Bei mir sieht die "NSView-subKlasse" teils so aus:

    Quellcode

    1. #import "PalCanvas.h"
    2. #import "Shape.h"
    3. @implementation PalCanvas
    4. - (id)initWithFrame:(NSRect)frameRect
    5. {
    6. if ((self = [super initWithFrame:frameRect]) != nil) {
    7. shape = [Shape new];
    8. [self setNeedsDisplay:YES];
    9. }
    10. return self;
    11. }
    12. - (void)drawRect:(NSRect)rect
    13. {
    14. NSBezierPath *theGround = [NSBezierPath bezierPathWithRect:rect];
    15. NSColor *theBGColor = [NSColor colorWithDeviceRed:(float)0.4 green:(float)0.8 blue:(float)0.1 alpha:(float)1.0];
    16. [theBGColor set];
    17. [theGround fill];
    18. theBGColor = [NSColor colorWithDeviceRed:(float)0.3 green:(float)0.3 blue:(float)0.0 alpha:(float)1.0];
    19. [theBGColor set];
    20. [theGround setLineWidth:4.];
    21. [theGround stroke];
    22. NSBezierPath *theShape = [shape getTheCurrentPath];
    23. [theShape stroke];
    24. [theWindow setAcceptsMouseMovedEvents:YES];
    25. }
    26. - (void)printLen
    27. // gibt die zurueckgelegte Strecke zurueck
    28. {
    29. int x = xPosE-xPosS;
    30. int y = yPosE-yPosS;
    31. NSLog(@"X-Strecke: %i", abs(x));
    32. NSLog(@"Y-Strecke: %i", abs(y));
    33. }
    Alles anzeigen


    und shape hat ua diese Funktion

    Quellcode

    1. - (NSBezierPath *)getTheCurrentPath
    2. {
    3. NSBezierPath *path = [NSBezierPath bezierPath];
    4. NSEnumerator *enumerator = [pointArray objectEnumerator];
    5. id anObject;
    6. while (anObject = [enumerator nextObject]) {
    7. [path lineToPoint:(NSPoint)[anObject getPoint]];
    8. NSLog(@"----> lineToPoint ");
    9. }
    10. [[NSColor blueColor]set];
    11. [path setLineWidth:3];
    12. return path;
    13. }
    Alles anzeigen

    Aber diese wird NIE aufgerufen. Dieses wiederspricht sich aber mit deinen Beschreibungen.

    drawRect: wird imemr aufgerufen wenn das system möchte das dein View sich zeichnet
    das System entscheidet das???

    Komme einfach nicht weiter - hat noch jemand gute Links mit Beispielen??

    mfg
    d
  • Mir sind mal mehrere Sachen aufgefalllen...

    1. Wenn Du [shape stroke] aufrufst impliziert das, daß Shape eine Subclass von NSBezierPath ist, in der Shape.h steht aber "Shape : NSObject"
    2. In der Shape.m in der init steht [super init]. Mach daraus mal ein self = [super init].
    3. In der Shape.m allokierst Du bei jedem Aufruf von getTheCurrentPath einen neuen NSBezierPath. Kann man, muß man aber nicht. Das wird immerhin bei jedem Zeichnen neu aufgerufen und das ist teuer. Ich würde daraus eine nette Subclass von NSBezierPath machen.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Hier meine Beobachtungen:
    1. [[NSColor blueColor]set]; sollte NICHT in getTheCurrentPath stehen, weil das logisch nichts miteinander zu tun hat

    2. gibt es keinen moveToPoint - eigentlich müßte das sogar eine Exception auslösen.
    Probiere mal NSLog(@"%@", theShape); ob das evtl. nil ist
    und - (void)appendBezierPathWithPoints:(NSPoint *)points count:(int)count

    -- hns
  • also das wichtige steht ja schon hier

    also änder mal die init wie das seb2 schon gesagt hat also self = [suber init];

    dann - ruf das drawRect: nciht von hand auf schreib dafür ein "setNeedsDisplay:"

    und das wichtigste setz in deiner "shape" klasse bei der generierung als erstes den startpunkt des pfades mit moveToPoint:

    desweiteren sollte das setzen deiner blauen farbe in deine drawRect: methode wandern...

    ich hab mal dein projekt zum laufen gebracht allerdings hab ich nciht alles überprüft sondern nur das was mir auf die schnelle aufgefallen ist

    PS: du hast da viele viele sachen wo du mit coordinaten spielst ... dir ist aufgefallen das in cocoa coordinaten immer in floats angegeben werden und nicht in int?
    snafu
    :() { :|: &};:
    sometimes i dream in hex
    Obey gravity! Because its a law!