Skip to content

Commit

Permalink
Added BaseWindow class so it can be reused for other OSes.
Browse files Browse the repository at this point in the history
  • Loading branch information
asweigart committed Aug 16, 2019
1 parent b06c7ea commit 4412790
Show file tree
Hide file tree
Showing 2 changed files with 350 additions and 281 deletions.
325 changes: 315 additions & 10 deletions src/pygetwindow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@

__version__ = '0.0.7'

import sys
import collections
import sys, collections, pyrect


class PyGetWindowException(Exception):
Expand All @@ -33,18 +32,324 @@ def pointInRect(x, y, left, top, width, height):
return left < x < left + width and top < y < top + height


# NOTE: `Rect` is a named tuple for use in Python, while structs.RECT represents
# the win32 RECT struct. PyRect's Rect class is used for handling changing
# geometry of rectangular areas.
Rect = collections.namedtuple('Rect', 'left top right bottom')
Point = collections.namedtuple('Point', 'x y')
Size = collections.namedtuple('Size', 'width height')


class BaseWindow:
def __init__(self):
pass


def _setupRectProperties(self):
def _onRead(attrName):
r = self._getWindowRect()
self._rect._left = r.left # Setting _left directly to skip the onRead.
self._rect._top = r.top # Setting _top directly to skip the onRead.
self._rect._width = r.right - r.left # Setting _width directly to skip the onRead.
self._rect._height = r.bottom - r.top # Setting _height directly to skip the onRead.

def _onChange(oldBox, newBox):
self.moveTo(newBox.left, newBox.top)
self.resizeTo(newBox.width, newBox.height)

r = self._getWindowRect()
self._rect = pyrect.Rect(r.left, r.top, r.right - r.left, r.bottom - r.top, onChange=_onChange, onRead=_onRead)


def _getWindowRect(self):
raise NotImplementedError

def __str__(self):
r = self._getWindowRect(self._hWnd)
width = r.right - r.left
height = r.bottom - r.top
return '<%s left="%s", top="%s", width="%s", height="%s", title="%s">' % (self.__class__.__qualname__, r.left, r.top, width, height, self.title)

def close(self):
"""Closes this window. This may trigger "Are you sure you want to
quit?" dialogs or other actions that prevent the window from
actually closing. This is identical to clicking the X button on the
window."""
raise NotImplementedError


def minimize(self):
"""Minimizes this window."""
raise NotImplementedError


def maximize(self):
"""Maximizes this window."""
raise NotImplementedError


def restore(self):
"""If maximized or minimized, restores the window to it's normal size."""
raise NotImplementedError


def activate(self):
"""Activate this window and make it the foreground window."""
raise NotImplementedError


def resizeRel(self, widthOffset, heightOffset):
"""Resizes the window relative to its current size."""
raise NotImplementedError


def resizeTo(self, newWidth, newHeight):
"""Resizes the window to a new width and height."""
raise NotImplementedError


def moveRel(self, xOffset, yOffset):
"""Moves the window relative to its current position."""
raise NotImplementedError


def moveTo(self, newLeft, newTop):
"""Moves the window to new coordinates on the screen."""
raise NotImplementedError


@property
def isMinimized(self):
"""Returns True if the window is currently minimized."""
raise NotImplementedError

@property
def isMaximized(self):
"""Returns True if the window is currently maximized."""
raise NotImplementedError

@property
def isActive(self):
"""Returns True if the window is currently the active, foreground window."""
raise NotImplementedError

@property
def title(self):
"""Returns the window title as a string."""
raise NotImplementedError

@property
def visible(self):
raise NotImplementedError


# Wrappers for pyrect.Rect object's properties:
@property
def left(self):
return self._rect.left

@left.setter
def left(self, value):
#import pdb; pdb.set_trace()
self._rect.left # Run rect's onRead to update the Rect object.
self._rect.left = value


@property
def right(self):
return self._rect.right

@right.setter
def right(self, value):
self._rect.right # Run rect's onRead to update the Rect object.
self._rect.right = value


@property
def top(self):
return self._rect.top

@top.setter
def top(self, value):
self._rect.top # Run rect's onRead to update the Rect object.
self._rect.top = value


@property
def bottom(self):
return self._rect.bottom

@bottom.setter
def bottom(self, value):
self._rect.bottom # Run rect's onRead to update the Rect object.
self._rect.bottom = value


@property
def topleft(self):
return self._rect.topleft

@topleft.setter
def topleft(self, value):
self._rect.topleft # Run rect's onRead to update the Rect object.
self._rect.topleft = value


@property
def topright(self):
return self._rect.topright

@topright.setter
def topright(self, value):
self._rect.topright # Run rect's onRead to update the Rect object.
self._rect.topright = value


@property
def bottomleft(self):
return self._rect.bottomleft

@bottomleft.setter
def bottomleft(self, value):
self._rect.bottomleft # Run rect's onRead to update the Rect object.
self._rect.bottomleft = value


@property
def bottomright(self):
return self._rect.bottomright

@bottomright.setter
def bottomright(self, value):
self._rect.bottomright # Run rect's onRead to update the Rect object.
self._rect.bottomright = value


@property
def midleft(self):
return self._rect.midleft

@midleft.setter
def midleft(self, value):
self._rect.midleft # Run rect's onRead to update the Rect object.
self._rect.midleft = value


@property
def midright(self):
return self._rect.midright

@midright.setter
def midright(self, value):
self._rect.midright # Run rect's onRead to update the Rect object.
self._rect.midright = value


@property
def midtop(self):
return self._rect.midtop

@midtop.setter
def midtop(self, value):
self._rect.midtop # Run rect's onRead to update the Rect object.
self._rect.midtop = value


@property
def midbottom(self):
return self._rect.midbottom

@midbottom.setter
def midbottom(self, value):
self._rect.midbottom # Run rect's onRead to update the Rect object.
self._rect.midbottom = value


@property
def center(self):
return self._rect.center

@center.setter
def center(self, value):
self._rect.center # Run rect's onRead to update the Rect object.
self._rect.center = value


@property
def centerx(self):
return self._rect.centerx

@centerx.setter
def centerx(self, value):
self._rect.centerx # Run rect's onRead to update the Rect object.
self._rect.centerx = value


@property
def centery(self):
return self._rect.centery

@centery.setter
def centery(self, value):
self._rect.centery # Run rect's onRead to update the Rect object.
self._rect.centery = value


@property
def width(self):
return self._rect.width

@width.setter
def width(self, value):
self._rect.width # Run rect's onRead to update the Rect object.
self._rect.width = value


@property
def height(self):
return self._rect.height

@height.setter
def height(self, value):
self._rect.height # Run rect's onRead to update the Rect object.
self._rect.height = value


@property
def size(self):
return self._rect.size

@size.setter
def size(self, value):
self._rect.size # Run rect's onRead to update the Rect object.
self._rect.size = value


@property
def area(self):
return self._rect.area

@area.setter
def area(self, value):
self._rect.area # Run rect's onRead to update the Rect object.
self._rect.area = value


@property
def box(self):
return self._rect.box

@box.setter
def box(self, value):
self._rect.box # Run rect's onRead to update the Rect object.
self._rect.box = value



if sys.platform == 'darwin':
raise NotImplementedError('PyGetWindow currently does not support macOS. If you have Appkit/Cocoa knowledge, please contribute! https://github.com/asweigart/pygetwindow') # TODO - implement mac
elif sys.platform == 'win32':
from ._pygetwindow_win import Win32Window, getActiveWindow, getActiveWindowTitle, getWindowsAt, getWindowsWithTitle, getAllWindows, getAllTitles
Window = Win32Window
else:
raise NotImplementedError('PyGetWindow currently does not support Linux. If you have Xlib knowledge, please contribute! https://github.com/asweigart/pygetwindow')


# NOTE: `Rect` is a named tuple for use in Python, while structs.RECT represents
# the win32 RECT struct. PyRect's Rect class is used for handling changing
# geometry of rectangular areas.
Rect = collections.namedtuple('Rect', 'left top right bottom')
Point = collections.namedtuple('Point', 'x y')
Size = collections.namedtuple('Size', 'width height')

0 comments on commit 4412790

Please sign in to comment.