• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Small animation inside NSCell (progress bar)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Small animation inside NSCell (progress bar)


  • Subject: Re: Small animation inside NSCell (progress bar)
  • From: Andy Lee <email@hidden>
  • Date: Sun, 22 Feb 2009 14:06:36 -0500

On Feb 22, 2009, at 1:18 PM, malcom wrote:
Hello,
I'm working on a subclass of NSCell that draws a custom style progress bar.
Everything works fine, it draws correctly and I've made the code to
make indeterminate animation (the method should be called by a timer).
So I've created a NSTimer in my NSCell subclass, but when I try to run
the program itself it only animates the last row of the table. In fact
seems only a timer is created (while I'm pretty sure that each NSCell
displayed is a different subclass because it display correctly
different data).
What's the problem in here?

I assume you mean "different instance" rather than "different subclass," in which case you need to know there actually *isn't* a different cell instance for each row. There is one cell instance per column and the cell is reused as needed to draw each row. I suspect that's your problem.


... However my big question is another. If I can get this method
working I'll have n timers for n cell istances that draw a short
portion of the entire tableview. It seems to be pretty expensive... so
what? What's the correct way to update only "indeterminate" cells with
a single timer? Is there a better way.

Just off the top of my head... rather than tie the timer to the cell, I wonder if having a timer that tells the table view to setNeedsDisplay:YES would work. This would force it to redraw all its cells when the timer fires. Feels like there should be a better solution, but again this is off the top of my head.


--Andy



The code below is my class.



#define DEFAULT_PROGRESSBAR_LEN	100
#define DEFAULT_PROGRESSBAR_HEG	12

@implementation WGUICell_ProgressBar

- (id) init
{
	self = [super init];
	if (self != nil) {
		[self setIndeterminate: YES];
		_bar_width = DEFAULT_PROGRESSBAR_LEN;
		_bar_height = DEFAULT_PROGRESSBAR_HEG;
		_bar_includeCloseButton = YES;
		_bar_maxValue = 100.0;
		_bar_currentValue = 75.0;
	}
	return self;
}

- (void) setDoubleValue:(double) _val {
	if (_val > _bar_maxValue) _val = _bar_maxValue;
	_bar_currentValue = _val;
}

- (void) setMaxValue:(double) _max {
	_bar_maxValue = _max;
}

- (BOOL) isIndetermimate {
	return _indeterminate;
}

- (void) setIndeterminate:(BOOL) _ind {
_indeterminate = _ind;
if (!_ind) {
[_timer invalidate];
} else {
_stepOfIndeterminate = 0;
_timer = [[NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:@selector(_updateIndeterminateProgress)
userInfo:nil repeats:YES] retain];
[ ((WGUITorrents_Table*)[self controlView]) _changeProgressBarsStyle];

}
}


#define BAR_WIDTH 100

- (NSRect) progressBarRect {
	return _barRect;
}

- (void) _updateIndeterminateProgress {
	NSLog(@"refresh %@",self);
	[[self controlView] setNeedsDisplayInRect: _barRect];
	//	[[self controlView] setNeedsDisplay: YES];

	_stepOfIndeterminate++;
}

- (void) setRepresentedObject:(id) _obj forColumn:(NSTableColumn *) _col {
[_representedObj release];
_representedObj = [_obj retain];
}



- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {

// the point where the progress bar starts
NSPoint originBar = NSMakePoint(cellFrame.origin.x+75, cellFrame.origin.y+19);

// draw bar itself
NSImage *backgroundStructure = [self _createProgressBarStructure];
NSRect barRect = NSMakeRect(originBar.x, originBar.y, BAR_WIDTH, 12);
_barRect = barRect;
[backgroundStructure drawInRect: barRect fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:1.0];

if (!_indeterminate) {
NSImage *progression_value = [self _drawDeterminateProgressBarValue: barRect];
NSRect _fillRect = NSMakeRect(originBar.x, originBar.y,
[progression_value size].width, _bar_height);
[progression_value setFlipped:YES];
[progression_value drawInRect: _fillRect
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction: 1.0];
} else {
NSImage *indeterminateProgression = [self _drawIndetermination];
NSRect _fillRect = NSMakeRect(originBar.x+1, originBar.y+1,
[indeterminateProgression size].width, [indeterminateProgression
size].height);
[indeterminateProgression setFlipped:YES];
[indeterminateProgression drawInRect: _fillRect
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}


}


- (NSImage *) _drawIndetermination {
NSImage *_double_prog = [[NSImage alloc] initWithSize: NSMakeSize(
(_bar_width*2)-2, _bar_height-2)];
[_double_prog lockFocus];
[[NSColor colorWithPatternImage: [NSImage
imageNamed:@"ind_progressbar.png"]] set];
NSBezierPath *p =[NSBezierPath bezierPathWithRect: NSMakeRect(0, 0,
(_bar_width*2)-2, _bar_height-2)];
[p fill];
[_double_prog unlockFocus];

NSImage *_portionVisible = [[NSImage alloc]
initWithSize:NSMakeSize(_bar_width-2, _bar_height-2)];
[_portionVisible lockFocus];

// back to the start of animation
if (_stepOfIndeterminate == _bar_width)
_stepOfIndeterminate = 0;

NSRect _portionsToPutInVisible = NSMakeRect(_stepOfIndeterminate, 0,
_bar_width-2, _bar_height-2);
[_double_prog setFlipped:YES];
[_double_prog drawInRect: NSMakeRect(0, 0, _bar_width-2, _bar_height-2)
fromRect:_portionsToPutInVisible operation:NSCompositeSourceOver
fraction:1.0];
[_portionVisible unlockFocus];
[_double_prog release];
return [_portionVisible autorelease];
/*
NSImage *prog = [[NSImage alloc]
initWithSize:NSMakeSize(_bar_width-2, _bar_height-2)];
[prog lockFocus];
NSColor *c = [NSColor colorWithPatternImage:[NSImage
imageNamed:@"ProgressIndeterminate.png"]];
[c set];
NSBezierPath *p =[NSBezierPath bezierPathWithRect:
NSMakeRect(0, 0, _bar_width, _bar_height)];
[p fill];
[prog unlockFocus];
return [prog autorelease];*/
}


- (NSImage *) _drawDeterminateProgressBarValue:(NSRect ) _barRect {
// x = (valore / valore max) * lungh barra
// x = (_bar_currentValue / _bar_maxValue)*_bar_width
double x_progressWidth = (_bar_currentValue/ _bar_maxValue)*_bar_width;
NSImage *prog = [[NSImage alloc]
initWithSize:NSMakeSize(x_progressWidth, _bar_height)];
[prog lockFocus];
[[NSColor colorWithPatternImage:[NSImage
imageNamed:@"ProgressBlue12.png"]] set];
NSBezierPath *p = [NSBezierPath bezierPathWithRect:NSMakeRect(0, 0,
x_progressWidth, _bar_height)];
[p fill];
[prog unlockFocus];
return [prog autorelease];
}


-copyWithZone:(NSZone *)zone
{
WGUICell_ProgressBar *cell = (WGUICell_ProgressBar *)[super copyWithZone:zone];
cell->_representedObj = [_representedObj retain];
cell->_timer = [_timer retain];
cell->_closeButtonRect = _closeButtonRect;
cell->_bar_currentValue = _bar_currentValue;
cell->_bar_maxValue =_bar_maxValue;
cell->_bar_width =_bar_width;
cell->_bar_height =_bar_height;
cell->_bar_includeCloseButton =_bar_includeCloseButton;
// cell->_indeterminate =_indeterminate;
//cell->_barRect =_barRect;
// cell->_stepOfIndeterminate =_stepOfIndeterminate;


return cell;
}


- (NSImage *) _createProgressBarStructure {
	// create offscreen structure
	NSImage *back = [[NSImage alloc] initWithSize:NSMakeSize(_bar_width,
_bar_height)];
	[back lockFocus];

	// draw background in the middle
	NSColor *middle_progressbarImg = [NSColor
colorWithPatternImage:[NSImage imageNamed:@"middle_progressbar.png"]];
	[middle_progressbarImg set];
	NSBezierPath *p = [NSBezierPath bezierPathWithRect: NSMakeRect(1, 0,
_bar_width-1, _bar_height)];
	[p fill];

	NSImage *lbar = [NSImage imageNamed:@"end_progressbar.png"];
	// left start part
	[lbar setFlipped:YES];
	[lbar drawInRect: NSMakeRect(0,0, 1, _bar_height)
			fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

	// right end part
	[lbar setFlipped:NO];
	[lbar drawInRect: NSMakeRect(_bar_width-1, 0, 1, _bar_height)
			fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
	[back unlockFocus];
	return [back autorelease];
}


@end _______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


aglee



_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Small animation inside NSCell (progress bar) (From: malcom <email@hidden>)

  • Prev by Date: Re: NSNotificationCenter : multiple messages sent tothe same observer?
  • Next by Date: Creating Subclass in Core Data
  • Previous by thread: Small animation inside NSCell (progress bar)
  • Next by thread: Obtaining Display EDID (DDC) Information From User Level App
  • Index(es):
    • Date
    • Thread