Source code for wbia.plottool.screeninfo

# -*- coding: utf-8 -*-
import sys
import utool as ut
import numpy as np

try:
    import wbia.guitool as gt
    from wbia.guitool.__PYQT__ import QtWidgets
    from wbia.guitool.__PYQT__ import QtCore
except ImportError:
    try:
        from PyQt4 import QtGui as QtWidgets
        from PyQt4 import QtCore
    except ImportError:
        pass
    try:
        from PyQt5 import QtWidgets  # NOQA
        from PyQt5 import QtCore  # NOQA
    except ImportError:
        pass
    print('Warning: guitool did not import correctly')
# (print, print_, printDBG, rrr, profile) = ut.inject(__name__, '[screeninfo]', DEBUG=True)
ut.noinject(__name__, '[screeninfo]')


DEFAULT_MAX_ROWS = 3


# Win7 Areo
WIN7_SIZES = {
    'os_border_x': 20,
    'os_border_y': 35,
    'os_border_h': 30,
    'win_border_x': 17,
    'win_border_y': 10,
    'mpl_toolbar_y': 10,
}

# Ubuntu (Medeterrainian Dark)
GNOME3_SIZES = {
    'os_border_x': 0,
    'os_border_y': 35,  # for gnome3 title bar
    'os_border_h': 0,
    'win_border_x': 5,
    'win_border_y': 30,
    'mpl_toolbar_y': 0,
}

for key in GNOME3_SIZES:
    GNOME3_SIZES[key] += 5


[docs]def infer_monitor_specs(res_w, res_h, inches_diag): """ monitors = [ dict(name='work1', inches_diag=23, res_w=1920, res_h=1080), dict(name='work2', inches_diag=24, res_w=1920, res_h=1200), dict(name='hp-129', inches_diag=25, res_w=1920, res_h=1080), dict(name='?-26', inches_diag=26, res_w=1920, res_h=1080), dict(name='?-27', inches_diag=27, res_w=1920, res_h=1080), ] for info in monitors: name = info['name'] inches_diag = info['inches_diag'] res_h = info['res_h'] res_w = info['res_w'] print('---') print(name) inches_w = inches_diag * res_w / np.sqrt(res_h**2 + res_w**2) inches_h = inches_diag * res_h / np.sqrt(res_h**2 + res_w**2) print('inches diag = %.2f' % (inches_diag)) print('inches WxH = %.2f x %.2f' % (inches_w, inches_h)) #inches_w = inches_diag * res_w/sqrt(res_h**2 + res_w**2) """ import sympy # Build a system of equations and solve it inches_w, inches_h = sympy.symbols( 'inches_w inches_h'.split(), real=True, positive=True ) res_w, res_h = sympy.symbols('res_w res_h'.split(), real=True, positive=True) (inches_diag,) = sympy.symbols('inches_diag'.split(), real=True, positive=True) equations = [ sympy.Eq(inches_diag, (inches_w ** 2 + inches_h ** 2) ** 0.5), sympy.Eq(res_w / res_h, inches_w / inches_h), ] print('Possible solutions:') query_vars = [inches_w, inches_h] for solution in sympy.solve(equations, query_vars): print('Solution:') reprstr = ut.repr3( ut.odict(zip(query_vars, solution)), explicit=True, nobr=1, with_comma=False ) print(ut.indent(ut.autopep8_format(reprstr)))
# (inches_diag*res_w/sqrt(res_h**2 + res_w**2), inches_diag*res_h/sqrt(res_h**2 + res_w**2))
[docs]def get_resolution_info(monitor_num=0): r""" Args: monitor_num (int): (default = 0) Returns: dict: info CommandLine: python -m wbia.plottool.screeninfo get_resolution_info --show xrandr | grep ' connected' grep "NVIDIA" /var/log/Xorg.0.log Example: >>> # DISABLE_DOCTEST >>> from wbia.plottool.screeninfo import * # NOQA >>> monitor_num = 1 >>> for monitor_num in range(get_number_of_monitors()): >>> info = get_resolution_info(monitor_num) >>> print('monitor(%d).info = %s' % (monitor_num, ut.repr3(info, precision=3))) """ import wbia.guitool as gt app = gt.ensure_qtapp()[0] # NOQA # screen_resolution = app.desktop().screenGeometry() # width, height = screen_resolution.width(), screen_resolution.height() # print('height = %r' % (height,)) # print('width = %r' % (width,)) desktop = QtWidgets.QDesktopWidget() screen = desktop.screen(monitor_num) ppi_x = screen.logicalDpiX() ppi_y = screen.logicalDpiY() dpi_x = screen.physicalDpiX() dpi_y = screen.physicalDpiY() # This call is not rotated correctly # rect = screen.screenGeometry() # This call has bad offsets rect = desktop.screenGeometry(screen=monitor_num) # This call subtracts offsets weirdly # desktop.availableGeometry(screen=monitor_num) pixels_w = rect.width() # for num in range(desktop.screenCount()): # pass pixels_h = rect.height() # + rect.y() """ I have two monitors (screens), after rotation effects they have the geometry: (for example) S1 = {x: 0, y=300, w: 1920, h:1080} S2 = {x=1920, y=0, w: 1080, h:1920} Here is a pictoral example G--------------------------------------C------------------- | | | A--------------------------------------| | | | | | | | | | | | S1 | | | | S2 | | | | | | | | | | |--------------------------------------B | | | | | | | ----------------------------------------------------------D Desired Info G = (0, 0) A = (S1.x, S1.y) B = (S1.x + S1.w, S1.y + S1.h) C = (S2.x, S2.y) D = (S2.x + S1.w, S2.y + S2.h) from PyQt4 import QtGui, QtCore app = QtCore.QCoreApplication.instance() if app is None: import sys app = QtGui.QApplication(sys.argv) desktop = QtGui.QDesktopWidget() rect1 = desktop.screenGeometry(screen=0) rect2 = desktop.screenGeometry(screen=1) """ # I want to get the relative positions of my monitors # pt = screen.pos() # pt = screen.mapToGlobal(pt) # pt = screen.mapToGlobal(screen.pos()) # Screen offsets seem bugged # off_x = pt.x() # off_y = pt.y() # print(pt.x()) # print(pt.y()) # pt = screen.mapToGlobal(QtCore.QPoint(0, 0)) # print(pt.x()) # print(pt.y()) off_x = rect.x() off_y = rect.y() # pt.x(), pt.y() inches_w = pixels_w / dpi_x inches_h = pixels_h / dpi_y inches_diag = (inches_w ** 2 + inches_h ** 2) ** 0.5 mm_w = inches_w * ut.MM_PER_INCH mm_h = inches_h * ut.MM_PER_INCH mm_diag = inches_diag * ut.MM_PER_INCH ratio = min(mm_w, mm_h) / max(mm_w, mm_h) # pixel_density = dpi_x / ppi_x info = ut.odict( [ ('monitor_num', monitor_num), ('off_x', off_x), ('off_y', off_y), ('ratio', ratio), ('ppi_x', ppi_x), ('ppi_y', ppi_y), ('dpi_x', dpi_x), ('dpi_y', dpi_y), # 'pixel_density', pixel_density), ('inches_w', inches_w), ('inches_h', inches_h), ('inches_diag', inches_diag), ('mm_w', mm_w), ('mm_h', mm_h), ('mm_diag', mm_diag), ('pixels_w', pixels_w), ('pixels_h', pixels_h), ] ) return info
[docs]def get_number_of_monitors(): gt.ensure_qtapp() desktop = QtWidgets.QDesktopWidget() if hasattr(desktop, 'numScreens'): n = desktop.numScreens() else: n = desktop.screenCount() return n
[docs]def get_monitor_geom(monitor_num=0): r""" Args: monitor_num (int): (default = 0) Returns: tuple: geom CommandLine: python -m wbia.plottool.screeninfo get_monitor_geom --show Example: >>> # DISABLE_DOCTEST >>> from wbia.plottool.screeninfo import * # NOQA >>> monitor_num = 0 >>> geom = get_monitor_geom(monitor_num) >>> result = ('geom = %s' % (ut.repr2(geom),)) >>> print(result) """ gt.ensure_qtapp() desktop = QtWidgets.QDesktopWidget() rect = desktop.availableGeometry(screen=monitor_num) geom = (rect.x(), rect.y(), rect.width(), rect.height()) return geom
[docs]def get_monitor_geometries(): gt.ensure_qtapp() monitor_geometries = {} desktop = QtWidgets.QDesktopWidget() if hasattr(desktop, 'numScreens'): n = desktop.numScreens() else: n = desktop.screenCount() for screenx in range(n): rect = desktop.availableGeometry(screen=screenx) geom = (rect.x(), rect.y(), rect.width(), rect.height()) monitor_geometries[screenx] = geom return monitor_geometries
[docs]def get_stdpxls(): if sys.platform.startswith('win32'): stdpxls = WIN7_SIZES elif sys.platform.startswith('linux'): stdpxls = GNOME3_SIZES else: stdpxls = GNOME3_SIZES return stdpxls
[docs]def get_xywh_pads(): stdpxls = get_stdpxls() w_pad = stdpxls['win_border_x'] y_pad = stdpxls['win_border_y'] + stdpxls['mpl_toolbar_y'] # Pads are applied to all windows x_pad = stdpxls['os_border_x'] y_pad = stdpxls['os_border_y'] return (x_pad, y_pad, w_pad, y_pad)
[docs]def get_avail_geom(monitor_num=None, percent_w=1.0, percent_h=1.0): stdpxls = get_stdpxls() if monitor_num is None: monitor_num = 0 monitor_geometries = get_monitor_geometries() try: (startx, starty, availw, availh) = monitor_geometries[monitor_num] except KeyError: (startx, starty, availw, availh) = next(monitor_geometries.values()) available_geom = ( startx, starty, availw * percent_w, (availh - stdpxls['os_border_h']) * percent_h, ) return available_geom
[docs]def get_valid_fig_positions( num_wins, max_rows=None, row_first=True, monitor_num=None, percent_w=1.0, percent_h=1.0, ): """ Returns a list of bounding boxes where figures can be placed on the screen """ if percent_h is None: percent_h = 1.0 if percent_w is None: percent_w = 1.0 if max_rows is None: max_rows = DEFAULT_MAX_ROWS available_geom = get_avail_geom(monitor_num, percent_w=percent_w, percent_h=percent_h) # print('available_geom = %r' % (available_geom,)) startx, starty, avail_width, avail_height = available_geom nRows = num_wins if num_wins < max_rows else max_rows nCols = int(np.ceil(num_wins / nRows)) win_height = avail_height / nRows win_width = avail_width / nCols (x_pad, y_pad, w_pad, h_pad) = get_xywh_pads() # print('startx, startx = %r, %r' % (startx, starty)) # print('avail_width, avail_height = %r, %r' % (avail_width, avail_height)) # print('win_width, win_height = %r, %r' % (win_width, win_height)) # print('nRows, nCols = %r, %r' % (nRows, nCols)) def get_position_ix(ix): if row_first: rowx = ix % nRows colx = int(ix // nRows) else: colx = ix % nCols rowx = int(ix // nCols) w = win_width - w_pad h = win_height - h_pad x = startx + colx * (win_width) + x_pad y = starty + rowx * (win_height) + y_pad return (x, y, w, h) valid_positions = [get_position_ix(ix) for ix in range(num_wins)] return valid_positions