Skip to content

Implement FigureManager.resize for macosx backend #16992

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions lib/matplotlib/backends/backend_macosx.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ def __init__(self, figure):
FigureCanvasBase.__init__(self, figure)
width, height = self.get_width_height()
_macosx.FigureCanvas.__init__(self, width, height)
self._device_scale = 1.0
self._dpi_ratio = 1.0

def _set_device_scale(self, value):
if self._device_scale != value:
self.figure.dpi = self.figure.dpi / self._device_scale * value
self._device_scale = value
if self._dpi_ratio != value:
# Need the new value in place before setting figure.dpi, which
# will trigger a resize
self._dpi_ratio, old_value = value, self._dpi_ratio
self.figure.dpi = self.figure.dpi / old_value * self._dpi_ratio

def _draw(self):
renderer = self.get_renderer(cleared=self.figure.stale)
Expand All @@ -77,8 +79,8 @@ def resize(self, width, height):
dpi = self.figure.dpi
width /= dpi
height /= dpi
self.figure.set_size_inches(width * self._device_scale,
height * self._device_scale,
self.figure.set_size_inches(width * self._dpi_ratio,
height * self._dpi_ratio,
forward=False)
FigureCanvasBase.resize_event(self)
self.draw_idle()
Expand Down
52 changes: 29 additions & 23 deletions src/_macosx.m
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ - (void)close;
@interface View : NSView <NSWindowDelegate>
{ PyObject* canvas;
NSRect rubberband;
BOOL inside;
NSTrackingRectTag tracking;
@public double device_scale;
}
Expand Down Expand Up @@ -337,6 +336,14 @@ static CGFloat _get_device_scale(CGContextRef cr)

NSRect rect = NSMakeRect(0.0, 0.0, width, height);
self->view = [self->view initWithFrame: rect];
self->view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved |
NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect);
[self->view addTrackingArea: [
[NSTrackingArea alloc] initWithRect: rect
options: opts
owner: self->view
userInfo: nil]];
[self->view setCanvas: (PyObject*)self];
return 0;
}
Expand Down Expand Up @@ -704,7 +711,6 @@ static CGFloat _get_device_scale(CGContextRef cr)
[window setTitle: [NSString stringWithCString: title
encoding: NSASCIIStringEncoding]];

[window setAcceptsMouseMovedEvents: YES];
[window setDelegate: view];
[window makeFirstResponder: view];
[[window contentView] addSubview: view];
Expand Down Expand Up @@ -804,6 +810,22 @@ static CGFloat _get_device_scale(CGContextRef cr)
}
}

static PyObject*
FigureManager_resize(FigureManager* self, PyObject *args, PyObject *kwds)
{
int width, height;
if (!PyArg_ParseTuple(args, "ii", &width, &height)) {
return NULL;
}
Window* window = self->window;
if(window)
{
// 36 comes from hard-coded size of toolbar later in code
[window setContentSize: NSMakeSize(width, height + 36.)];
}
Py_RETURN_NONE;
}

static PyMethodDef FigureManager_methods[] = {
{"show",
(PyCFunction)FigureManager_show,
Expand All @@ -825,6 +847,11 @@ static CGFloat _get_device_scale(CGContextRef cr)
METH_NOARGS,
"Returns the title of the window associated with the figure manager."
},
{"resize",
(PyCFunction)FigureManager_resize,
METH_VARARGS,
"Resize the window (in pixels)."
},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -1564,8 +1591,6 @@ - (View*)initWithFrame:(NSRect)rect
{
self = [super initWithFrame: rect];
rubberband = NSZeroRect;
inside = false;
tracking = 0;
device_scale = 1;
return self;
}
Expand All @@ -1574,7 +1599,6 @@ - (void)dealloc
{
FigureCanvas* fc = (FigureCanvas*)canvas;
if (fc) fc->view = NULL;
[self removeTrackingRect: tracking];
[super dealloc];
}

Expand Down Expand Up @@ -1703,8 +1727,6 @@ - (void)windowDidResize: (NSNotification*)notification
width = size.width;
height = size.height;

[self setFrameSize: size];

PyGILState_STATE gstate = PyGILState_Ensure();
PyObject* result = PyObject_CallMethod(
canvas, "resize", "ii", width, height);
Expand All @@ -1713,11 +1735,6 @@ - (void)windowDidResize: (NSNotification*)notification
else
PyErr_Print();
PyGILState_Release(gstate);
if (tracking) [self removeTrackingRect: tracking];
tracking = [self addTrackingRect: [self bounds]
owner: self
userData: nil
assumeInside: NO];
[self setNeedsDisplay: YES];
}

Expand Down Expand Up @@ -1760,8 +1777,6 @@ - (void)mouseEntered:(NSEvent *)event
{
PyGILState_STATE gstate;
PyObject* result;
NSWindow* window = [self window];
if ([window isKeyWindow]==false) return;

int x, y;
NSPoint location = [event locationInWindow];
Expand All @@ -1778,29 +1793,20 @@ - (void)mouseEntered:(NSEvent *)event
else
PyErr_Print();
PyGILState_Release(gstate);

[window setAcceptsMouseMovedEvents: YES];
inside = true;
}

- (void)mouseExited:(NSEvent *)event
{
PyGILState_STATE gstate;
PyObject* result;
NSWindow* window = [self window];
if ([window isKeyWindow]==false) return;

if (inside==false) return;
gstate = PyGILState_Ensure();
result = PyObject_CallMethod(canvas, "leave_notify_event", "");
if(result)
Py_DECREF(result);
else
PyErr_Print();
PyGILState_Release(gstate);

[[self window] setAcceptsMouseMovedEvents: NO];
inside = false;
}

- (void)mouseDown:(NSEvent *)event
Expand Down