0
votes

I went through several posts on dragging but couldn't find an answer to my problem.

I can use the mouseDown and mouseUp events to track the current positions and redraw the resized pane. What I want is to show the real time movement of the pane. Everytime mouseDragged event is fired, y coordinate of the new location is taken and setFrame is called to redraw. The window seems to flicker and gets stuck finally (title bar goes out of bounds and hidden) as it seems to miss the final events in the run loop.

Is there a way to solve this problem?

The view has been implemented in the following way

  • NSSplitView (divided into sections left dock, right dock, etc.)
  • NSView is used to implement a sub view inside the dock
  • NSTableView is used inside the NSView to hold multiple "panels"
  • There can be several panels inside this table view (one below another)

I need to resize these panels by dragging the border line. For this I'm using an NSButton in the bottom.(I want to show a thicker separation line there)

Here is the code for mouseDown, mouseUp, mouseDragged callbacks, used to resize the panel

-(void)mouseDown:(NSEvent *)theEvent {
  draggingInProgress = YES;
  firstDraggingPointFound = NO; 
}

-(void)mouseUp:(NSEvent *)theEvent {
  if (!draggingInProgress) {
      return;
  }
  NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil];
  if (firstDraggingPointFound) {
      [_delegate heightChanged:[NSNumber numberWithFloat:(point.y - previousDragPosition)]];
}


  draggingInProgress = NO;
  [_delegate heightChangingEnded]; //draggingInProgress is set to NO
}

-(void)mouseDragged:(NSEvent *)theEvent {
  if (!draggingInProgress) {
      return;
  }
  NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil];
  if (firstDraggingPointFound) {
      [_delegate heightChanged:[NSNumber numberWithFloat:(point.y - previousDragPosition)]];
  } else {
    firstDraggingPointFound = YES;
  }
  previousDragPosition = point.y;
}

//Delegate method
-(void)heightChanged:(NSNumber *)change {
  NSRect f = [[self view] frame];
  f.size.height += [change floatValue];
  if (f.size.height < 100) {
      f.size.height = 100;
  }
  [[self view] setFrame:f];
  [self.panelViewModel setPanelHeight:f.size.height];
  if (_heightChangeDelegate) {
      [_heightChangeDelegate heightChangedForPanel:self];
  }
  [[self view] setFrame:f];
}

What would be the problem here? Is there a better way to do this?

1

1 Answers

0
votes

First off, I wouldn’t use the word “Panel” to describe what you want, since an “NSPanel” is a kind of “NSWindow”. Let’s call them “panes.”

Second, I wouldn’t use an NSTableView to contain your panes. NSTableView really isn’t designed for that, it’s for tabular data. You can use an NSStackView, which IS designed for it, or just use raw constraints and autolayout, manually setting the top of each pane to equal the bottom of the previous one.