HW8 Complete
This commit is contained in:
105
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__init__.py
vendored
Normal file
105
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__init__.py
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
import matplotlib
|
||||
from matplotlib import cbook
|
||||
from matplotlib.backend_bases import _Backend
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# NOTE: plt.switch_backend() (called at import time) will add a "backend"
|
||||
# attribute here for backcompat.
|
||||
|
||||
|
||||
def _get_running_interactive_framework():
|
||||
"""
|
||||
Return the interactive framework whose event loop is currently running, if
|
||||
any, or "headless" if no event loop can be started, or None.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Optional[str]
|
||||
One of the following values: "qt5", "qt4", "gtk3", "wx", "tk",
|
||||
"macosx", "headless", ``None``.
|
||||
"""
|
||||
QtWidgets = (sys.modules.get("PyQt5.QtWidgets")
|
||||
or sys.modules.get("PySide2.QtWidgets"))
|
||||
if QtWidgets and QtWidgets.QApplication.instance():
|
||||
return "qt5"
|
||||
QtGui = (sys.modules.get("PyQt4.QtGui")
|
||||
or sys.modules.get("PySide.QtGui"))
|
||||
if QtGui and QtGui.QApplication.instance():
|
||||
return "qt4"
|
||||
Gtk = sys.modules.get("gi.repository.Gtk")
|
||||
if Gtk and Gtk.main_level():
|
||||
return "gtk3"
|
||||
wx = sys.modules.get("wx")
|
||||
if wx and wx.GetApp():
|
||||
return "wx"
|
||||
tkinter = sys.modules.get("tkinter")
|
||||
if tkinter:
|
||||
for frame in sys._current_frames().values():
|
||||
while frame:
|
||||
if frame.f_code == tkinter.mainloop.__code__:
|
||||
return "tk"
|
||||
frame = frame.f_back
|
||||
if 'matplotlib.backends._macosx' in sys.modules:
|
||||
if sys.modules["matplotlib.backends._macosx"].event_loop_is_running():
|
||||
return "macosx"
|
||||
if sys.platform.startswith("linux") and not os.environ.get("DISPLAY"):
|
||||
return "headless"
|
||||
return None
|
||||
|
||||
|
||||
@cbook.deprecated("3.0")
|
||||
def pylab_setup(name=None):
|
||||
"""
|
||||
Return new_figure_manager, draw_if_interactive and show for pyplot.
|
||||
|
||||
This provides the backend-specific functions that are used by pyplot to
|
||||
abstract away the difference between backends.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name : str, optional
|
||||
The name of the backend to use. If `None`, falls back to
|
||||
``matplotlib.get_backend()`` (which return :rc:`backend`).
|
||||
|
||||
Returns
|
||||
-------
|
||||
backend_mod : module
|
||||
The module which contains the backend of choice
|
||||
|
||||
new_figure_manager : function
|
||||
Create a new figure manager (roughly maps to GUI window)
|
||||
|
||||
draw_if_interactive : function
|
||||
Redraw the current figure if pyplot is interactive
|
||||
|
||||
show : function
|
||||
Show (and possibly block) any unshown figures.
|
||||
"""
|
||||
# Import the requested backend into a generic module object.
|
||||
if name is None:
|
||||
name = matplotlib.get_backend()
|
||||
backend_name = (name[9:] if name.startswith("module://")
|
||||
else "matplotlib.backends.backend_{}".format(name.lower()))
|
||||
backend_mod = importlib.import_module(backend_name)
|
||||
# Create a local Backend class whose body corresponds to the contents of
|
||||
# the backend module. This allows the Backend class to fill in the missing
|
||||
# methods through inheritance.
|
||||
Backend = type("Backend", (_Backend,), vars(backend_mod))
|
||||
|
||||
# Need to keep a global reference to the backend for compatibility reasons.
|
||||
# See https://github.com/matplotlib/matplotlib/issues/6092
|
||||
global backend
|
||||
backend = name
|
||||
|
||||
_log.debug('backend %s version %s', name, Backend.backend_version)
|
||||
return (backend_mod,
|
||||
Backend.new_figure_manager,
|
||||
Backend.draw_if_interactive,
|
||||
Backend.show)
|
||||
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/__init__.cpython-37.pyc
vendored
Normal file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/__init__.cpython-37.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/backend_ps.cpython-37.pyc
vendored
Normal file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/backend_ps.cpython-37.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/backend_wx.cpython-37.pyc
vendored
Normal file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/backend_wx.cpython-37.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/qt_compat.cpython-37.pyc
vendored
Normal file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/qt_compat.cpython-37.pyc
vendored
Normal file
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/tkagg.cpython-37.pyc
vendored
Normal file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/tkagg.cpython-37.pyc
vendored
Normal file
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/windowing.cpython-37.pyc
vendored
Normal file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/windowing.cpython-37.pyc
vendored
Normal file
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/wx_compat.cpython-37.pyc
vendored
Normal file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/__pycache__/wx_compat.cpython-37.pyc
vendored
Normal file
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_backend_agg.cpython-37m-darwin.so
vendored
Executable file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_backend_agg.cpython-37m-darwin.so
vendored
Executable file
Binary file not shown.
84
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_backend_pdf_ps.py
vendored
Normal file
84
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_backend_pdf_ps.py
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
"""
|
||||
Common functionality between the PDF and PS backends.
|
||||
"""
|
||||
|
||||
import functools
|
||||
|
||||
import matplotlib as mpl
|
||||
from .. import font_manager, ft2font
|
||||
from ..afm import AFM
|
||||
from ..backend_bases import RendererBase
|
||||
|
||||
|
||||
@functools.lru_cache(50)
|
||||
def _cached_get_afm_from_fname(fname):
|
||||
with open(fname, "rb") as fh:
|
||||
return AFM(fh)
|
||||
|
||||
|
||||
class RendererPDFPSBase(RendererBase):
|
||||
# The following attributes must be defined by the subclasses:
|
||||
# - _afm_font_dir
|
||||
# - _use_afm_rc_name
|
||||
|
||||
def flipy(self):
|
||||
# docstring inherited
|
||||
return False # y increases from bottom to top.
|
||||
|
||||
def option_scale_image(self):
|
||||
# docstring inherited
|
||||
return True # PDF and PS support arbitrary image scaling.
|
||||
|
||||
def option_image_nocomposite(self):
|
||||
# docstring inherited
|
||||
# Decide whether to composite image based on rcParam value.
|
||||
return not mpl.rcParams["image.composite_image"]
|
||||
|
||||
def get_canvas_width_height(self):
|
||||
# docstring inherited
|
||||
return self.width * 72.0, self.height * 72.0
|
||||
|
||||
def get_text_width_height_descent(self, s, prop, ismath):
|
||||
# docstring inherited
|
||||
if mpl.rcParams["text.usetex"]:
|
||||
texmanager = self.get_texmanager()
|
||||
fontsize = prop.get_size_in_points()
|
||||
w, h, d = texmanager.get_text_width_height_descent(
|
||||
s, fontsize, renderer=self)
|
||||
return w, h, d
|
||||
elif ismath:
|
||||
parse = self.mathtext_parser.parse(s, 72, prop)
|
||||
return parse.width, parse.height, parse.depth
|
||||
elif mpl.rcParams[self._use_afm_rc_name]:
|
||||
font = self._get_font_afm(prop)
|
||||
l, b, w, h, d = font.get_str_bbox_and_descent(s)
|
||||
scale = prop.get_size_in_points() / 1000
|
||||
w *= scale
|
||||
h *= scale
|
||||
d *= scale
|
||||
return w, h, d
|
||||
else:
|
||||
font = self._get_font_ttf(prop)
|
||||
font.set_text(s, 0.0, flags=ft2font.LOAD_NO_HINTING)
|
||||
w, h = font.get_width_height()
|
||||
d = font.get_descent()
|
||||
scale = 1 / 64
|
||||
w *= scale
|
||||
h *= scale
|
||||
d *= scale
|
||||
return w, h, d
|
||||
|
||||
def _get_font_afm(self, prop):
|
||||
fname = (
|
||||
font_manager.findfont(
|
||||
prop, fontext="afm", directory=self._afm_font_dir)
|
||||
or font_manager.findfont(
|
||||
"Helvetica", fontext="afm", directory=self._afm_font_dir))
|
||||
return _cached_get_afm_from_fname(fname)
|
||||
|
||||
def _get_font_ttf(self, prop):
|
||||
fname = font_manager.findfont(prop)
|
||||
font = font_manager.get_font(fname)
|
||||
font.clear()
|
||||
font.set_size(prop.get_size_in_points(), 72)
|
||||
return font
|
||||
981
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_backend_tk.py
vendored
Normal file
981
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_backend_tk.py
vendored
Normal file
@@ -0,0 +1,981 @@
|
||||
from contextlib import contextmanager
|
||||
import logging
|
||||
import math
|
||||
import os.path
|
||||
import sys
|
||||
import tkinter as tk
|
||||
from tkinter.simpledialog import SimpleDialog
|
||||
import tkinter.filedialog
|
||||
import tkinter.messagebox
|
||||
|
||||
import numpy as np
|
||||
|
||||
import matplotlib
|
||||
from matplotlib import backend_tools, cbook, rcParams
|
||||
from matplotlib.backend_bases import (
|
||||
_Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
|
||||
StatusbarBase, TimerBase, ToolContainerBase, cursors)
|
||||
from matplotlib.backend_managers import ToolManager
|
||||
from matplotlib._pylab_helpers import Gcf
|
||||
from matplotlib.figure import Figure
|
||||
from matplotlib.widgets import SubplotTool
|
||||
from . import _tkagg
|
||||
|
||||
try:
|
||||
from ._tkagg import Win32_GetForegroundWindow, Win32_SetForegroundWindow
|
||||
except ImportError:
|
||||
@contextmanager
|
||||
def _restore_foreground_window_at_end():
|
||||
yield
|
||||
else:
|
||||
@contextmanager
|
||||
def _restore_foreground_window_at_end():
|
||||
foreground = Win32_GetForegroundWindow()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if rcParams['tk.window_focus']:
|
||||
Win32_SetForegroundWindow(foreground)
|
||||
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
backend_version = tk.TkVersion
|
||||
|
||||
# the true dots per inch on the screen; should be display dependent
|
||||
# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
|
||||
PIXELS_PER_INCH = 75
|
||||
|
||||
cursord = {
|
||||
cursors.MOVE: "fleur",
|
||||
cursors.HAND: "hand2",
|
||||
cursors.POINTER: "arrow",
|
||||
cursors.SELECT_REGION: "tcross",
|
||||
cursors.WAIT: "watch",
|
||||
}
|
||||
|
||||
|
||||
def blit(photoimage, aggimage, offsets, bbox=None):
|
||||
"""
|
||||
Blit *aggimage* to *photoimage*.
|
||||
|
||||
*offsets* is a tuple describing how to fill the ``offset`` field of the
|
||||
``Tk_PhotoImageBlock`` struct: it should be (0, 1, 2, 3) for RGBA8888 data,
|
||||
(2, 1, 0, 3) for little-endian ARBG32 (i.e. GBRA8888) data and (1, 2, 3, 0)
|
||||
for big-endian ARGB32 (i.e. ARGB8888) data.
|
||||
|
||||
If *bbox* is passed, it defines the region that gets blitted.
|
||||
"""
|
||||
data = np.asarray(aggimage)
|
||||
height, width = data.shape[:2]
|
||||
dataptr = (height, width, data.ctypes.data)
|
||||
if bbox is not None:
|
||||
(x1, y1), (x2, y2) = bbox.__array__()
|
||||
x1 = max(math.floor(x1), 0)
|
||||
x2 = min(math.ceil(x2), width)
|
||||
y1 = max(math.floor(y1), 0)
|
||||
y2 = min(math.ceil(y2), height)
|
||||
bboxptr = (x1, x2, y1, y2)
|
||||
else:
|
||||
photoimage.blank()
|
||||
bboxptr = (0, width, 0, height)
|
||||
_tkagg.blit(
|
||||
photoimage.tk.interpaddr(), str(photoimage), dataptr, offsets, bboxptr)
|
||||
|
||||
|
||||
class TimerTk(TimerBase):
|
||||
'''
|
||||
Subclass of :class:`backend_bases.TimerBase` that uses Tk's timer events.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
interval : int
|
||||
The time between timer events in milliseconds. Default is 1000 ms.
|
||||
single_shot : bool
|
||||
Boolean flag indicating whether this timer should operate as single
|
||||
shot (run once and then stop). Defaults to False.
|
||||
callbacks : list
|
||||
Stores list of (func, args) tuples that will be called upon timer
|
||||
events. This list can be manipulated directly, or the functions
|
||||
`add_callback` and `remove_callback` can be used.
|
||||
|
||||
'''
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
TimerBase.__init__(self, *args, **kwargs)
|
||||
self.parent = parent
|
||||
self._timer = None
|
||||
|
||||
def _timer_start(self):
|
||||
self._timer_stop()
|
||||
self._timer = self.parent.after(self._interval, self._on_timer)
|
||||
|
||||
def _timer_stop(self):
|
||||
if self._timer is not None:
|
||||
self.parent.after_cancel(self._timer)
|
||||
self._timer = None
|
||||
|
||||
def _on_timer(self):
|
||||
TimerBase._on_timer(self)
|
||||
|
||||
# Tk after() is only a single shot, so we need to add code here to
|
||||
# reset the timer if we're not operating in single shot mode. However,
|
||||
# if _timer is None, this means that _timer_stop has been called; so
|
||||
# don't recreate the timer in that case.
|
||||
if not self._single and self._timer:
|
||||
self._timer = self.parent.after(self._interval, self._on_timer)
|
||||
else:
|
||||
self._timer = None
|
||||
|
||||
|
||||
class FigureCanvasTk(FigureCanvasBase):
|
||||
keyvald = {65507: 'control',
|
||||
65505: 'shift',
|
||||
65513: 'alt',
|
||||
65515: 'super',
|
||||
65508: 'control',
|
||||
65506: 'shift',
|
||||
65514: 'alt',
|
||||
65361: 'left',
|
||||
65362: 'up',
|
||||
65363: 'right',
|
||||
65364: 'down',
|
||||
65307: 'escape',
|
||||
65470: 'f1',
|
||||
65471: 'f2',
|
||||
65472: 'f3',
|
||||
65473: 'f4',
|
||||
65474: 'f5',
|
||||
65475: 'f6',
|
||||
65476: 'f7',
|
||||
65477: 'f8',
|
||||
65478: 'f9',
|
||||
65479: 'f10',
|
||||
65480: 'f11',
|
||||
65481: 'f12',
|
||||
65300: 'scroll_lock',
|
||||
65299: 'break',
|
||||
65288: 'backspace',
|
||||
65293: 'enter',
|
||||
65379: 'insert',
|
||||
65535: 'delete',
|
||||
65360: 'home',
|
||||
65367: 'end',
|
||||
65365: 'pageup',
|
||||
65366: 'pagedown',
|
||||
65438: '0',
|
||||
65436: '1',
|
||||
65433: '2',
|
||||
65435: '3',
|
||||
65430: '4',
|
||||
65437: '5',
|
||||
65432: '6',
|
||||
65429: '7',
|
||||
65431: '8',
|
||||
65434: '9',
|
||||
65451: '+',
|
||||
65453: '-',
|
||||
65450: '*',
|
||||
65455: '/',
|
||||
65439: 'dec',
|
||||
65421: 'enter',
|
||||
}
|
||||
|
||||
_keycode_lookup = {
|
||||
262145: 'control',
|
||||
524320: 'alt',
|
||||
524352: 'alt',
|
||||
1048584: 'super',
|
||||
1048592: 'super',
|
||||
131074: 'shift',
|
||||
131076: 'shift',
|
||||
}
|
||||
"""_keycode_lookup is used for badly mapped (i.e. no event.key_sym set)
|
||||
keys on apple keyboards."""
|
||||
|
||||
def __init__(self, figure, master=None, resize_callback=None):
|
||||
super(FigureCanvasTk, self).__init__(figure)
|
||||
self._idle = True
|
||||
self._idle_callback = None
|
||||
t1, t2, w, h = self.figure.bbox.bounds
|
||||
w, h = int(w), int(h)
|
||||
self._tkcanvas = tk.Canvas(
|
||||
master=master, background="white",
|
||||
width=w, height=h, borderwidth=0, highlightthickness=0)
|
||||
self._tkphoto = tk.PhotoImage(
|
||||
master=self._tkcanvas, width=w, height=h)
|
||||
self._tkcanvas.create_image(w//2, h//2, image=self._tkphoto)
|
||||
self._resize_callback = resize_callback
|
||||
self._tkcanvas.bind("<Configure>", self.resize)
|
||||
self._tkcanvas.bind("<Key>", self.key_press)
|
||||
self._tkcanvas.bind("<Motion>", self.motion_notify_event)
|
||||
self._tkcanvas.bind("<Enter>", self.enter_notify_event)
|
||||
self._tkcanvas.bind("<Leave>", self.leave_notify_event)
|
||||
self._tkcanvas.bind("<KeyRelease>", self.key_release)
|
||||
for name in "<Button-1>", "<Button-2>", "<Button-3>":
|
||||
self._tkcanvas.bind(name, self.button_press_event)
|
||||
for name in "<Double-Button-1>", "<Double-Button-2>", "<Double-Button-3>":
|
||||
self._tkcanvas.bind(name, self.button_dblclick_event)
|
||||
for name in "<ButtonRelease-1>", "<ButtonRelease-2>", "<ButtonRelease-3>":
|
||||
self._tkcanvas.bind(name, self.button_release_event)
|
||||
|
||||
# Mouse wheel on Linux generates button 4/5 events
|
||||
for name in "<Button-4>", "<Button-5>":
|
||||
self._tkcanvas.bind(name, self.scroll_event)
|
||||
# Mouse wheel for windows goes to the window with the focus.
|
||||
# Since the canvas won't usually have the focus, bind the
|
||||
# event to the window containing the canvas instead.
|
||||
# See http://wiki.tcl.tk/3893 (mousewheel) for details
|
||||
root = self._tkcanvas.winfo_toplevel()
|
||||
root.bind("<MouseWheel>", self.scroll_event_windows, "+")
|
||||
|
||||
# Can't get destroy events by binding to _tkcanvas. Therefore, bind
|
||||
# to the window and filter.
|
||||
def filter_destroy(evt):
|
||||
if evt.widget is self._tkcanvas:
|
||||
self._master.update_idletasks()
|
||||
self.close_event()
|
||||
root.bind("<Destroy>", filter_destroy, "+")
|
||||
|
||||
self._master = master
|
||||
self._tkcanvas.focus_set()
|
||||
|
||||
def resize(self, event):
|
||||
width, height = event.width, event.height
|
||||
if self._resize_callback is not None:
|
||||
self._resize_callback(event)
|
||||
|
||||
# compute desired figure size in inches
|
||||
dpival = self.figure.dpi
|
||||
winch = width / dpival
|
||||
hinch = height / dpival
|
||||
self.figure.set_size_inches(winch, hinch, forward=False)
|
||||
|
||||
self._tkcanvas.delete(self._tkphoto)
|
||||
self._tkphoto = tk.PhotoImage(
|
||||
master=self._tkcanvas, width=int(width), height=int(height))
|
||||
self._tkcanvas.create_image(
|
||||
int(width / 2), int(height / 2), image=self._tkphoto)
|
||||
self.resize_event()
|
||||
self.draw()
|
||||
|
||||
# a resizing will in general move the pointer position
|
||||
# relative to the canvas, so process it as a motion notify
|
||||
# event. An intended side effect of this call is to allow
|
||||
# window raises (which trigger a resize) to get the cursor
|
||||
# position to the mpl event framework so key presses which are
|
||||
# over the axes will work w/o clicks or explicit motion
|
||||
self._update_pointer_position(event)
|
||||
|
||||
def _update_pointer_position(self, guiEvent=None):
|
||||
"""
|
||||
Figure out if we are inside the canvas or not and update the
|
||||
canvas enter/leave events
|
||||
"""
|
||||
# if the pointer if over the canvas, set the lastx and lasty
|
||||
# attrs of the canvas so it can process event w/o mouse click
|
||||
# or move
|
||||
|
||||
# the window's upper, left coords in screen coords
|
||||
xw = self._tkcanvas.winfo_rootx()
|
||||
yw = self._tkcanvas.winfo_rooty()
|
||||
# the pointer's location in screen coords
|
||||
xp, yp = self._tkcanvas.winfo_pointerxy()
|
||||
|
||||
# not figure out the canvas coordinates of the pointer
|
||||
xc = xp - xw
|
||||
yc = yp - yw
|
||||
|
||||
# flip top/bottom
|
||||
yc = self.figure.bbox.height - yc
|
||||
|
||||
# JDH: this method was written originally to get the pointer
|
||||
# location to the backend lastx and lasty attrs so that events
|
||||
# like KeyEvent can be handled without mouse events. e.g., if
|
||||
# the cursor is already above the axes, then key presses like
|
||||
# 'g' should toggle the grid. In order for this to work in
|
||||
# backend_bases, the canvas needs to know _lastx and _lasty.
|
||||
# There are three ways to get this info the canvas:
|
||||
#
|
||||
# 1) set it explicitly
|
||||
#
|
||||
# 2) call enter/leave events explicitly. The downside of this
|
||||
# in the impl below is that enter could be repeatedly
|
||||
# triggered if the mouse is over the axes and one is
|
||||
# resizing with the keyboard. This is not entirely bad,
|
||||
# because the mouse position relative to the canvas is
|
||||
# changing, but it may be surprising to get repeated entries
|
||||
# without leaves
|
||||
#
|
||||
# 3) process it as a motion notify event. This also has pros
|
||||
# and cons. The mouse is moving relative to the window, but
|
||||
# this may surprise an event handler writer who is getting
|
||||
# motion_notify_events even if the mouse has not moved
|
||||
|
||||
# here are the three scenarios
|
||||
if 1:
|
||||
# just manually set it
|
||||
self._lastx, self._lasty = xc, yc
|
||||
elif 0:
|
||||
# alternate implementation: process it as a motion
|
||||
FigureCanvasBase.motion_notify_event(self, xc, yc, guiEvent)
|
||||
elif 0:
|
||||
# alternate implementation -- process enter/leave events
|
||||
# instead of motion/notify
|
||||
if self.figure.bbox.contains(xc, yc):
|
||||
self.enter_notify_event(guiEvent, xy=(xc, yc))
|
||||
else:
|
||||
self.leave_notify_event(guiEvent)
|
||||
|
||||
def draw_idle(self):
|
||||
# docstring inherited
|
||||
if not self._idle:
|
||||
return
|
||||
|
||||
self._idle = False
|
||||
|
||||
def idle_draw(*args):
|
||||
try:
|
||||
self.draw()
|
||||
finally:
|
||||
self._idle = True
|
||||
|
||||
self._idle_callback = self._tkcanvas.after_idle(idle_draw)
|
||||
|
||||
def get_tk_widget(self):
|
||||
"""Return the Tk widget used to implement FigureCanvasTkAgg.
|
||||
Although the initial implementation uses a Tk canvas, this routine
|
||||
is intended to hide that fact.
|
||||
"""
|
||||
return self._tkcanvas
|
||||
|
||||
def motion_notify_event(self, event):
|
||||
x = event.x
|
||||
# flipy so y=0 is bottom of canvas
|
||||
y = self.figure.bbox.height - event.y
|
||||
FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
|
||||
|
||||
def enter_notify_event(self, event):
|
||||
x = event.x
|
||||
# flipy so y=0 is bottom of canvas
|
||||
y = self.figure.bbox.height - event.y
|
||||
FigureCanvasBase.enter_notify_event(self, guiEvent=event, xy=(x, y))
|
||||
|
||||
def button_press_event(self, event, dblclick=False):
|
||||
x = event.x
|
||||
# flipy so y=0 is bottom of canvas
|
||||
y = self.figure.bbox.height - event.y
|
||||
num = getattr(event, 'num', None)
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
# 2 and 3 were reversed on the OSX platform I tested under tkagg.
|
||||
if num == 2:
|
||||
num = 3
|
||||
elif num == 3:
|
||||
num = 2
|
||||
|
||||
FigureCanvasBase.button_press_event(
|
||||
self, x, y, num, dblclick=dblclick, guiEvent=event)
|
||||
|
||||
def button_dblclick_event(self, event):
|
||||
self.button_press_event(event, dblclick=True)
|
||||
|
||||
def button_release_event(self, event):
|
||||
x = event.x
|
||||
# flipy so y=0 is bottom of canvas
|
||||
y = self.figure.bbox.height - event.y
|
||||
|
||||
num = getattr(event, 'num', None)
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
# 2 and 3 were reversed on the OSX platform I tested under tkagg.
|
||||
if num == 2:
|
||||
num = 3
|
||||
elif num == 3:
|
||||
num = 2
|
||||
|
||||
FigureCanvasBase.button_release_event(self, x, y, num, guiEvent=event)
|
||||
|
||||
def scroll_event(self, event):
|
||||
x = event.x
|
||||
y = self.figure.bbox.height - event.y
|
||||
num = getattr(event, 'num', None)
|
||||
step = 1 if num == 4 else -1 if num == 5 else 0
|
||||
FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
|
||||
|
||||
def scroll_event_windows(self, event):
|
||||
"""MouseWheel event processor"""
|
||||
# need to find the window that contains the mouse
|
||||
w = event.widget.winfo_containing(event.x_root, event.y_root)
|
||||
if w == self._tkcanvas:
|
||||
x = event.x_root - w.winfo_rootx()
|
||||
y = event.y_root - w.winfo_rooty()
|
||||
y = self.figure.bbox.height - y
|
||||
step = event.delta/120.
|
||||
FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
|
||||
|
||||
def _get_key(self, event):
|
||||
val = event.keysym_num
|
||||
if val in self.keyvald:
|
||||
key = self.keyvald[val]
|
||||
elif (val == 0 and sys.platform == 'darwin'
|
||||
and event.keycode in self._keycode_lookup):
|
||||
key = self._keycode_lookup[event.keycode]
|
||||
elif val < 256:
|
||||
key = chr(val)
|
||||
else:
|
||||
key = None
|
||||
|
||||
# add modifier keys to the key string. Bit details originate from
|
||||
# http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
|
||||
# BIT_SHIFT = 0x001; BIT_CAPSLOCK = 0x002; BIT_CONTROL = 0x004;
|
||||
# BIT_LEFT_ALT = 0x008; BIT_NUMLOCK = 0x010; BIT_RIGHT_ALT = 0x080;
|
||||
# BIT_MB_1 = 0x100; BIT_MB_2 = 0x200; BIT_MB_3 = 0x400;
|
||||
# In general, the modifier key is excluded from the modifier flag,
|
||||
# however this is not the case on "darwin", so double check that
|
||||
# we aren't adding repeat modifier flags to a modifier key.
|
||||
if sys.platform == 'win32':
|
||||
modifiers = [(17, 'alt', 'alt'),
|
||||
(2, 'ctrl', 'control'),
|
||||
]
|
||||
elif sys.platform == 'darwin':
|
||||
modifiers = [(3, 'super', 'super'),
|
||||
(4, 'alt', 'alt'),
|
||||
(2, 'ctrl', 'control'),
|
||||
]
|
||||
else:
|
||||
modifiers = [(6, 'super', 'super'),
|
||||
(3, 'alt', 'alt'),
|
||||
(2, 'ctrl', 'control'),
|
||||
]
|
||||
|
||||
if key is not None:
|
||||
# shift is not added to the keys as this is already accounted for
|
||||
for bitmask, prefix, key_name in modifiers:
|
||||
if event.state & (1 << bitmask) and key_name not in key:
|
||||
key = '{0}+{1}'.format(prefix, key)
|
||||
|
||||
return key
|
||||
|
||||
def key_press(self, event):
|
||||
key = self._get_key(event)
|
||||
FigureCanvasBase.key_press_event(self, key, guiEvent=event)
|
||||
|
||||
def key_release(self, event):
|
||||
key = self._get_key(event)
|
||||
FigureCanvasBase.key_release_event(self, key, guiEvent=event)
|
||||
|
||||
def new_timer(self, *args, **kwargs):
|
||||
# docstring inherited
|
||||
return TimerTk(self._tkcanvas, *args, **kwargs)
|
||||
|
||||
def flush_events(self):
|
||||
# docstring inherited
|
||||
self._master.update()
|
||||
|
||||
|
||||
class FigureManagerTk(FigureManagerBase):
|
||||
"""
|
||||
Attributes
|
||||
----------
|
||||
canvas : `FigureCanvas`
|
||||
The FigureCanvas instance
|
||||
num : int or str
|
||||
The Figure number
|
||||
toolbar : tk.Toolbar
|
||||
The tk.Toolbar
|
||||
window : tk.Window
|
||||
The tk.Window
|
||||
|
||||
"""
|
||||
def __init__(self, canvas, num, window):
|
||||
FigureManagerBase.__init__(self, canvas, num)
|
||||
self.window = window
|
||||
self.window.withdraw()
|
||||
self.set_window_title("Figure %d" % num)
|
||||
self.canvas = canvas
|
||||
# If using toolmanager it has to be present when initializing the
|
||||
# toolbar
|
||||
self.toolmanager = self._get_toolmanager()
|
||||
# packing toolbar first, because if space is getting low, last packed
|
||||
# widget is getting shrunk first (-> the canvas)
|
||||
self.toolbar = self._get_toolbar()
|
||||
self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
|
||||
self._num = num
|
||||
|
||||
self.statusbar = None
|
||||
|
||||
if self.toolmanager:
|
||||
backend_tools.add_tools_to_manager(self.toolmanager)
|
||||
if self.toolbar:
|
||||
backend_tools.add_tools_to_container(self.toolbar)
|
||||
self.statusbar = StatusbarTk(self.window, self.toolmanager)
|
||||
|
||||
self._shown = False
|
||||
|
||||
def _get_toolbar(self):
|
||||
if matplotlib.rcParams['toolbar'] == 'toolbar2':
|
||||
toolbar = NavigationToolbar2Tk(self.canvas, self.window)
|
||||
elif matplotlib.rcParams['toolbar'] == 'toolmanager':
|
||||
toolbar = ToolbarTk(self.toolmanager, self.window)
|
||||
else:
|
||||
toolbar = None
|
||||
return toolbar
|
||||
|
||||
def _get_toolmanager(self):
|
||||
if rcParams['toolbar'] == 'toolmanager':
|
||||
toolmanager = ToolManager(self.canvas.figure)
|
||||
else:
|
||||
toolmanager = None
|
||||
return toolmanager
|
||||
|
||||
def resize(self, width, height):
|
||||
self.canvas._tkcanvas.master.geometry("%dx%d" % (width, height))
|
||||
|
||||
if self.toolbar is not None:
|
||||
self.toolbar.configure(width=width)
|
||||
|
||||
def show(self):
|
||||
"""
|
||||
this function doesn't segfault but causes the
|
||||
PyEval_RestoreThread: NULL state bug on win32
|
||||
"""
|
||||
with _restore_foreground_window_at_end():
|
||||
if not self._shown:
|
||||
def destroy(*args):
|
||||
self.window = None
|
||||
Gcf.destroy(self._num)
|
||||
self.canvas._tkcanvas.bind("<Destroy>", destroy)
|
||||
self.window.deiconify()
|
||||
else:
|
||||
self.canvas.draw_idle()
|
||||
# Raise the new window.
|
||||
self.canvas.manager.window.attributes('-topmost', 1)
|
||||
self.canvas.manager.window.attributes('-topmost', 0)
|
||||
self._shown = True
|
||||
|
||||
def destroy(self, *args):
|
||||
if self.window is not None:
|
||||
#self.toolbar.destroy()
|
||||
if self.canvas._idle_callback:
|
||||
self.canvas._tkcanvas.after_cancel(self.canvas._idle_callback)
|
||||
self.window.destroy()
|
||||
if Gcf.get_num_fig_managers() == 0:
|
||||
if self.window is not None:
|
||||
self.window.quit()
|
||||
self.window = None
|
||||
|
||||
def get_window_title(self):
|
||||
return self.window.wm_title()
|
||||
|
||||
def set_window_title(self, title):
|
||||
self.window.wm_title(title)
|
||||
|
||||
def full_screen_toggle(self):
|
||||
is_fullscreen = bool(self.window.attributes('-fullscreen'))
|
||||
self.window.attributes('-fullscreen', not is_fullscreen)
|
||||
|
||||
|
||||
class NavigationToolbar2Tk(NavigationToolbar2, tk.Frame):
|
||||
"""
|
||||
Attributes
|
||||
----------
|
||||
canvas : `FigureCanvas`
|
||||
the figure canvas on which to operate
|
||||
win : tk.Window
|
||||
the tk.Window which owns this toolbar
|
||||
|
||||
"""
|
||||
def __init__(self, canvas, window):
|
||||
self.canvas = canvas
|
||||
# Avoid using self.window (prefer self.canvas.get_tk_widget().master),
|
||||
# so that Tool implementations can reuse the methods.
|
||||
self.window = window
|
||||
NavigationToolbar2.__init__(self, canvas)
|
||||
|
||||
def destroy(self, *args):
|
||||
del self.message
|
||||
tk.Frame.destroy(self, *args)
|
||||
|
||||
def set_message(self, s):
|
||||
self.message.set(s)
|
||||
|
||||
def draw_rubberband(self, event, x0, y0, x1, y1):
|
||||
height = self.canvas.figure.bbox.height
|
||||
y0 = height - y0
|
||||
y1 = height - y1
|
||||
if hasattr(self, "lastrect"):
|
||||
self.canvas._tkcanvas.delete(self.lastrect)
|
||||
self.lastrect = self.canvas._tkcanvas.create_rectangle(x0, y0, x1, y1)
|
||||
|
||||
def release(self, event):
|
||||
if hasattr(self, "lastrect"):
|
||||
self.canvas._tkcanvas.delete(self.lastrect)
|
||||
del self.lastrect
|
||||
|
||||
def set_cursor(self, cursor):
|
||||
window = self.canvas.get_tk_widget().master
|
||||
window.configure(cursor=cursord[cursor])
|
||||
window.update_idletasks()
|
||||
|
||||
def _Button(self, text, file, command, extension='.gif'):
|
||||
img_file = os.path.join(
|
||||
rcParams['datapath'], 'images', file + extension)
|
||||
im = tk.PhotoImage(master=self, file=img_file)
|
||||
b = tk.Button(
|
||||
master=self, text=text, padx=2, pady=2, image=im, command=command)
|
||||
b._ntimage = im
|
||||
b.pack(side=tk.LEFT)
|
||||
return b
|
||||
|
||||
def _Spacer(self):
|
||||
# Buttons are 30px high. Make this 26px tall +2px padding to center it.
|
||||
s = tk.Frame(
|
||||
master=self, height=26, relief=tk.RIDGE, pady=2, bg="DarkGray")
|
||||
s.pack(side=tk.LEFT, padx=5)
|
||||
return s
|
||||
|
||||
def _init_toolbar(self):
|
||||
xmin, xmax = self.canvas.figure.bbox.intervalx
|
||||
height, width = 50, xmax-xmin
|
||||
tk.Frame.__init__(self, master=self.window,
|
||||
width=int(width), height=int(height),
|
||||
borderwidth=2)
|
||||
|
||||
self.update() # Make axes menu
|
||||
|
||||
for text, tooltip_text, image_file, callback in self.toolitems:
|
||||
if text is None:
|
||||
# Add a spacer; return value is unused.
|
||||
self._Spacer()
|
||||
else:
|
||||
button = self._Button(text=text, file=image_file,
|
||||
command=getattr(self, callback))
|
||||
if tooltip_text is not None:
|
||||
ToolTip.createToolTip(button, tooltip_text)
|
||||
|
||||
self.message = tk.StringVar(master=self)
|
||||
self._message_label = tk.Label(master=self, textvariable=self.message)
|
||||
self._message_label.pack(side=tk.RIGHT)
|
||||
self.pack(side=tk.BOTTOM, fill=tk.X)
|
||||
|
||||
def configure_subplots(self):
|
||||
toolfig = Figure(figsize=(6, 3))
|
||||
window = tk.Toplevel()
|
||||
canvas = type(self.canvas)(toolfig, master=window)
|
||||
toolfig.subplots_adjust(top=0.9)
|
||||
canvas.tool = SubplotTool(self.canvas.figure, toolfig)
|
||||
canvas.draw()
|
||||
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
|
||||
window.grab_set()
|
||||
|
||||
def save_figure(self, *args):
|
||||
filetypes = self.canvas.get_supported_filetypes().copy()
|
||||
default_filetype = self.canvas.get_default_filetype()
|
||||
|
||||
# Tk doesn't provide a way to choose a default filetype,
|
||||
# so we just have to put it first
|
||||
default_filetype_name = filetypes.pop(default_filetype)
|
||||
sorted_filetypes = ([(default_filetype, default_filetype_name)]
|
||||
+ sorted(filetypes.items()))
|
||||
tk_filetypes = [(name, '*.%s' % ext) for ext, name in sorted_filetypes]
|
||||
|
||||
# adding a default extension seems to break the
|
||||
# asksaveasfilename dialog when you choose various save types
|
||||
# from the dropdown. Passing in the empty string seems to
|
||||
# work - JDH!
|
||||
#defaultextension = self.canvas.get_default_filetype()
|
||||
defaultextension = ''
|
||||
initialdir = os.path.expanduser(rcParams['savefig.directory'])
|
||||
initialfile = self.canvas.get_default_filename()
|
||||
fname = tkinter.filedialog.asksaveasfilename(
|
||||
master=self.canvas.get_tk_widget().master,
|
||||
title='Save the figure',
|
||||
filetypes=tk_filetypes,
|
||||
defaultextension=defaultextension,
|
||||
initialdir=initialdir,
|
||||
initialfile=initialfile,
|
||||
)
|
||||
|
||||
if fname in ["", ()]:
|
||||
return
|
||||
# Save dir for next time, unless empty str (i.e., use cwd).
|
||||
if initialdir != "":
|
||||
rcParams['savefig.directory'] = (
|
||||
os.path.dirname(str(fname)))
|
||||
try:
|
||||
# This method will handle the delegation to the correct type
|
||||
self.canvas.figure.savefig(fname)
|
||||
except Exception as e:
|
||||
tkinter.messagebox.showerror("Error saving file", str(e))
|
||||
|
||||
def set_active(self, ind):
|
||||
self._ind = ind
|
||||
self._active = [self._axes[i] for i in self._ind]
|
||||
|
||||
def update(self):
|
||||
self._axes = self.canvas.figure.axes
|
||||
with _restore_foreground_window_at_end():
|
||||
NavigationToolbar2.update(self)
|
||||
|
||||
|
||||
class ToolTip(object):
|
||||
"""
|
||||
Tooltip recipe from
|
||||
http://www.voidspace.org.uk/python/weblog/arch_d7_2006_07_01.shtml#e387
|
||||
"""
|
||||
@staticmethod
|
||||
def createToolTip(widget, text):
|
||||
toolTip = ToolTip(widget)
|
||||
def enter(event):
|
||||
toolTip.showtip(text)
|
||||
def leave(event):
|
||||
toolTip.hidetip()
|
||||
widget.bind('<Enter>', enter)
|
||||
widget.bind('<Leave>', leave)
|
||||
|
||||
def __init__(self, widget):
|
||||
self.widget = widget
|
||||
self.tipwindow = None
|
||||
self.id = None
|
||||
self.x = self.y = 0
|
||||
|
||||
def showtip(self, text):
|
||||
"Display text in tooltip window"
|
||||
self.text = text
|
||||
if self.tipwindow or not self.text:
|
||||
return
|
||||
x, y, _, _ = self.widget.bbox("insert")
|
||||
x = x + self.widget.winfo_rootx() + 27
|
||||
y = y + self.widget.winfo_rooty()
|
||||
self.tipwindow = tw = tk.Toplevel(self.widget)
|
||||
tw.wm_overrideredirect(1)
|
||||
tw.wm_geometry("+%d+%d" % (x, y))
|
||||
try:
|
||||
# For Mac OS
|
||||
tw.tk.call("::tk::unsupported::MacWindowStyle",
|
||||
"style", tw._w,
|
||||
"help", "noActivates")
|
||||
except tk.TclError:
|
||||
pass
|
||||
label = tk.Label(tw, text=self.text, justify=tk.LEFT,
|
||||
background="#ffffe0", relief=tk.SOLID, borderwidth=1)
|
||||
label.pack(ipadx=1)
|
||||
|
||||
def hidetip(self):
|
||||
tw = self.tipwindow
|
||||
self.tipwindow = None
|
||||
if tw:
|
||||
tw.destroy()
|
||||
|
||||
|
||||
class RubberbandTk(backend_tools.RubberbandBase):
|
||||
def draw_rubberband(self, x0, y0, x1, y1):
|
||||
height = self.figure.canvas.figure.bbox.height
|
||||
y0 = height - y0
|
||||
y1 = height - y1
|
||||
if hasattr(self, "lastrect"):
|
||||
self.figure.canvas._tkcanvas.delete(self.lastrect)
|
||||
self.lastrect = self.figure.canvas._tkcanvas.create_rectangle(
|
||||
x0, y0, x1, y1)
|
||||
|
||||
def remove_rubberband(self):
|
||||
if hasattr(self, "lastrect"):
|
||||
self.figure.canvas._tkcanvas.delete(self.lastrect)
|
||||
del self.lastrect
|
||||
|
||||
|
||||
class SetCursorTk(backend_tools.SetCursorBase):
|
||||
def set_cursor(self, cursor):
|
||||
NavigationToolbar2Tk.set_cursor(
|
||||
self._make_classic_style_pseudo_toolbar(), cursor)
|
||||
|
||||
|
||||
class ToolbarTk(ToolContainerBase, tk.Frame):
|
||||
_icon_extension = '.gif'
|
||||
|
||||
def __init__(self, toolmanager, window):
|
||||
ToolContainerBase.__init__(self, toolmanager)
|
||||
xmin, xmax = self.toolmanager.canvas.figure.bbox.intervalx
|
||||
height, width = 50, xmax - xmin
|
||||
tk.Frame.__init__(self, master=window,
|
||||
width=int(width), height=int(height),
|
||||
borderwidth=2)
|
||||
self._toolitems = {}
|
||||
self.pack(side=tk.TOP, fill=tk.X)
|
||||
self._groups = {}
|
||||
|
||||
def add_toolitem(
|
||||
self, name, group, position, image_file, description, toggle):
|
||||
frame = self._get_groupframe(group)
|
||||
button = self._Button(name, image_file, toggle, frame)
|
||||
if description is not None:
|
||||
ToolTip.createToolTip(button, description)
|
||||
self._toolitems.setdefault(name, [])
|
||||
self._toolitems[name].append(button)
|
||||
|
||||
def _get_groupframe(self, group):
|
||||
if group not in self._groups:
|
||||
if self._groups:
|
||||
self._add_separator()
|
||||
frame = tk.Frame(master=self, borderwidth=0)
|
||||
frame.pack(side=tk.LEFT, fill=tk.Y)
|
||||
self._groups[group] = frame
|
||||
return self._groups[group]
|
||||
|
||||
def _add_separator(self):
|
||||
separator = tk.Frame(master=self, bd=5, width=1, bg='black')
|
||||
separator.pack(side=tk.LEFT, fill=tk.Y, padx=2)
|
||||
|
||||
def _Button(self, text, image_file, toggle, frame):
|
||||
if image_file is not None:
|
||||
im = tk.PhotoImage(master=self, file=image_file)
|
||||
else:
|
||||
im = None
|
||||
|
||||
if not toggle:
|
||||
b = tk.Button(master=frame, text=text, padx=2, pady=2, image=im,
|
||||
command=lambda: self._button_click(text))
|
||||
else:
|
||||
# There is a bug in tkinter included in some python 3.6 versions
|
||||
# that without this variable, produces a "visual" toggling of
|
||||
# other near checkbuttons
|
||||
# https://bugs.python.org/issue29402
|
||||
# https://bugs.python.org/issue25684
|
||||
var = tk.IntVar()
|
||||
b = tk.Checkbutton(master=frame, text=text, padx=2, pady=2,
|
||||
image=im, indicatoron=False,
|
||||
command=lambda: self._button_click(text),
|
||||
variable=var)
|
||||
b._ntimage = im
|
||||
b.pack(side=tk.LEFT)
|
||||
return b
|
||||
|
||||
def _button_click(self, name):
|
||||
self.trigger_tool(name)
|
||||
|
||||
def toggle_toolitem(self, name, toggled):
|
||||
if name not in self._toolitems:
|
||||
return
|
||||
for toolitem in self._toolitems[name]:
|
||||
if toggled:
|
||||
toolitem.select()
|
||||
else:
|
||||
toolitem.deselect()
|
||||
|
||||
def remove_toolitem(self, name):
|
||||
for toolitem in self._toolitems[name]:
|
||||
toolitem.pack_forget()
|
||||
del self._toolitems[name]
|
||||
|
||||
|
||||
class StatusbarTk(StatusbarBase, tk.Frame):
|
||||
def __init__(self, window, *args, **kwargs):
|
||||
StatusbarBase.__init__(self, *args, **kwargs)
|
||||
xmin, xmax = self.toolmanager.canvas.figure.bbox.intervalx
|
||||
height, width = 50, xmax - xmin
|
||||
tk.Frame.__init__(self, master=window,
|
||||
width=int(width), height=int(height),
|
||||
borderwidth=2)
|
||||
self._message = tk.StringVar(master=self)
|
||||
self._message_label = tk.Label(master=self, textvariable=self._message)
|
||||
self._message_label.pack(side=tk.RIGHT)
|
||||
self.pack(side=tk.TOP, fill=tk.X)
|
||||
|
||||
def set_message(self, s):
|
||||
self._message.set(s)
|
||||
|
||||
|
||||
class SaveFigureTk(backend_tools.SaveFigureBase):
|
||||
def trigger(self, *args):
|
||||
NavigationToolbar2Tk.save_figure(
|
||||
self._make_classic_style_pseudo_toolbar())
|
||||
|
||||
|
||||
class ConfigureSubplotsTk(backend_tools.ConfigureSubplotsBase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
backend_tools.ConfigureSubplotsBase.__init__(self, *args, **kwargs)
|
||||
self.window = None
|
||||
|
||||
def trigger(self, *args):
|
||||
self.init_window()
|
||||
self.window.lift()
|
||||
|
||||
def init_window(self):
|
||||
if self.window:
|
||||
return
|
||||
|
||||
toolfig = Figure(figsize=(6, 3))
|
||||
self.window = tk.Tk()
|
||||
|
||||
canvas = type(self.canvas)(toolfig, master=self.window)
|
||||
toolfig.subplots_adjust(top=0.9)
|
||||
SubplotTool(self.figure, toolfig)
|
||||
canvas.draw()
|
||||
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
|
||||
self.window.protocol("WM_DELETE_WINDOW", self.destroy)
|
||||
|
||||
def destroy(self, *args, **kwargs):
|
||||
if self.window is not None:
|
||||
self.window.destroy()
|
||||
self.window = None
|
||||
|
||||
|
||||
class HelpTk(backend_tools.ToolHelpBase):
|
||||
def trigger(self, *args):
|
||||
dialog = SimpleDialog(
|
||||
self.figure.canvas._tkcanvas, self._get_help_text(), ["OK"])
|
||||
dialog.done = lambda num: dialog.frame.master.withdraw()
|
||||
|
||||
|
||||
backend_tools.ToolSaveFigure = SaveFigureTk
|
||||
backend_tools.ToolConfigureSubplots = ConfigureSubplotsTk
|
||||
backend_tools.ToolSetCursor = SetCursorTk
|
||||
backend_tools.ToolRubberband = RubberbandTk
|
||||
backend_tools.ToolHelp = HelpTk
|
||||
backend_tools.ToolCopyToClipboard = backend_tools.ToolCopyToClipboardBase
|
||||
Toolbar = ToolbarTk
|
||||
|
||||
|
||||
@_Backend.export
|
||||
class _BackendTk(_Backend):
|
||||
required_interactive_framework = "tk"
|
||||
FigureManager = FigureManagerTk
|
||||
|
||||
@classmethod
|
||||
def new_figure_manager_given_figure(cls, num, figure):
|
||||
"""
|
||||
Create a new figure manager instance for the given figure.
|
||||
"""
|
||||
with _restore_foreground_window_at_end():
|
||||
window = tk.Tk(className="matplotlib")
|
||||
window.withdraw()
|
||||
|
||||
# Put a mpl icon on the window rather than the default tk icon.
|
||||
# Tkinter doesn't allow colour icons on linux systems, but tk>=8.5
|
||||
# has a iconphoto command which we call directly. Source:
|
||||
# http://mail.python.org/pipermail/tkinter-discuss/2006-November/000954.html
|
||||
icon_fname = os.path.join(
|
||||
rcParams['datapath'], 'images', 'matplotlib.ppm')
|
||||
icon_img = tk.PhotoImage(file=icon_fname, master=window)
|
||||
try:
|
||||
window.iconphoto(False, icon_img)
|
||||
except Exception as exc:
|
||||
# log the failure (due e.g. to Tk version), but carry on
|
||||
_log.info('Could not load matplotlib icon: %s', exc)
|
||||
|
||||
canvas = cls.FigureCanvas(figure, master=window)
|
||||
manager = cls.FigureManager(canvas, num, window)
|
||||
if matplotlib.is_interactive():
|
||||
manager.show()
|
||||
canvas.draw_idle()
|
||||
return manager
|
||||
|
||||
@staticmethod
|
||||
def trigger_manager_draw(manager):
|
||||
manager.show()
|
||||
|
||||
@staticmethod
|
||||
def mainloop():
|
||||
managers = Gcf.get_all_fig_managers()
|
||||
if managers:
|
||||
managers[0].window.mainloop()
|
||||
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_macosx.cpython-37m-darwin.so
vendored
Executable file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_macosx.cpython-37m-darwin.so
vendored
Executable file
Binary file not shown.
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_tkagg.cpython-37m-darwin.so
vendored
Executable file
BIN
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/_tkagg.cpython-37m-darwin.so
vendored
Executable file
Binary file not shown.
618
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py
vendored
Normal file
618
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py
vendored
Normal file
@@ -0,0 +1,618 @@
|
||||
"""
|
||||
An agg http://antigrain.com/ backend
|
||||
|
||||
Features that are implemented
|
||||
|
||||
* capstyles and join styles
|
||||
* dashes
|
||||
* linewidth
|
||||
* lines, rectangles, ellipses
|
||||
* clipping to a rectangle
|
||||
* output to RGBA and PNG, optionally JPEG and TIFF
|
||||
* alpha blending
|
||||
* DPI scaling properly - everything scales properly (dashes, linewidths, etc)
|
||||
* draw polygon
|
||||
* freetype2 w/ ft2font
|
||||
|
||||
TODO:
|
||||
|
||||
* integrate screen dpi w/ ppi and text
|
||||
|
||||
"""
|
||||
try:
|
||||
import threading
|
||||
except ImportError:
|
||||
import dummy_threading as threading
|
||||
import numpy as np
|
||||
from collections import OrderedDict
|
||||
from math import radians, cos, sin
|
||||
from matplotlib import cbook, rcParams, __version__
|
||||
from matplotlib.backend_bases import (
|
||||
_Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
|
||||
from matplotlib.font_manager import findfont, get_font
|
||||
from matplotlib.ft2font import (LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING,
|
||||
LOAD_DEFAULT, LOAD_NO_AUTOHINT)
|
||||
from matplotlib.mathtext import MathTextParser
|
||||
from matplotlib.path import Path
|
||||
from matplotlib.transforms import Bbox, BboxBase
|
||||
from matplotlib import colors as mcolors
|
||||
|
||||
from matplotlib.backends._backend_agg import RendererAgg as _RendererAgg
|
||||
|
||||
from matplotlib.backend_bases import _has_pil
|
||||
|
||||
if _has_pil:
|
||||
from PIL import Image
|
||||
|
||||
backend_version = 'v2.2'
|
||||
|
||||
def get_hinting_flag():
|
||||
mapping = {
|
||||
True: LOAD_FORCE_AUTOHINT,
|
||||
False: LOAD_NO_HINTING,
|
||||
'either': LOAD_DEFAULT,
|
||||
'native': LOAD_NO_AUTOHINT,
|
||||
'auto': LOAD_FORCE_AUTOHINT,
|
||||
'none': LOAD_NO_HINTING
|
||||
}
|
||||
return mapping[rcParams['text.hinting']]
|
||||
|
||||
|
||||
class RendererAgg(RendererBase):
|
||||
"""
|
||||
The renderer handles all the drawing primitives using a graphics
|
||||
context instance that controls the colors/styles
|
||||
"""
|
||||
|
||||
# we want to cache the fonts at the class level so that when
|
||||
# multiple figures are created we can reuse them. This helps with
|
||||
# a bug on windows where the creation of too many figures leads to
|
||||
# too many open file handles. However, storing them at the class
|
||||
# level is not thread safe. The solution here is to let the
|
||||
# FigureCanvas acquire a lock on the fontd at the start of the
|
||||
# draw, and release it when it is done. This allows multiple
|
||||
# renderers to share the cached fonts, but only one figure can
|
||||
# draw at time and so the font cache is used by only one
|
||||
# renderer at a time.
|
||||
|
||||
lock = threading.RLock()
|
||||
|
||||
def __init__(self, width, height, dpi):
|
||||
RendererBase.__init__(self)
|
||||
|
||||
self.dpi = dpi
|
||||
self.width = width
|
||||
self.height = height
|
||||
self._renderer = _RendererAgg(int(width), int(height), dpi)
|
||||
self._filter_renderers = []
|
||||
|
||||
self._update_methods()
|
||||
self.mathtext_parser = MathTextParser('Agg')
|
||||
|
||||
self.bbox = Bbox.from_bounds(0, 0, self.width, self.height)
|
||||
|
||||
def __getstate__(self):
|
||||
# We only want to preserve the init keywords of the Renderer.
|
||||
# Anything else can be re-created.
|
||||
return {'width': self.width, 'height': self.height, 'dpi': self.dpi}
|
||||
|
||||
def __setstate__(self, state):
|
||||
self.__init__(state['width'], state['height'], state['dpi'])
|
||||
|
||||
def _update_methods(self):
|
||||
self.draw_gouraud_triangle = self._renderer.draw_gouraud_triangle
|
||||
self.draw_gouraud_triangles = self._renderer.draw_gouraud_triangles
|
||||
self.draw_image = self._renderer.draw_image
|
||||
self.draw_markers = self._renderer.draw_markers
|
||||
self.draw_path_collection = self._renderer.draw_path_collection
|
||||
self.draw_quad_mesh = self._renderer.draw_quad_mesh
|
||||
self.copy_from_bbox = self._renderer.copy_from_bbox
|
||||
self.get_content_extents = self._renderer.get_content_extents
|
||||
|
||||
def tostring_rgba_minimized(self):
|
||||
extents = self.get_content_extents()
|
||||
bbox = [[extents[0], self.height - (extents[1] + extents[3])],
|
||||
[extents[0] + extents[2], self.height - extents[1]]]
|
||||
region = self.copy_from_bbox(bbox)
|
||||
return np.array(region), extents
|
||||
|
||||
def draw_path(self, gc, path, transform, rgbFace=None):
|
||||
# docstring inherited
|
||||
nmax = rcParams['agg.path.chunksize'] # here at least for testing
|
||||
npts = path.vertices.shape[0]
|
||||
|
||||
if (nmax > 100 and npts > nmax and path.should_simplify and
|
||||
rgbFace is None and gc.get_hatch() is None):
|
||||
nch = np.ceil(npts / nmax)
|
||||
chsize = int(np.ceil(npts / nch))
|
||||
i0 = np.arange(0, npts, chsize)
|
||||
i1 = np.zeros_like(i0)
|
||||
i1[:-1] = i0[1:] - 1
|
||||
i1[-1] = npts
|
||||
for ii0, ii1 in zip(i0, i1):
|
||||
v = path.vertices[ii0:ii1, :]
|
||||
c = path.codes
|
||||
if c is not None:
|
||||
c = c[ii0:ii1]
|
||||
c[0] = Path.MOVETO # move to end of last chunk
|
||||
p = Path(v, c)
|
||||
try:
|
||||
self._renderer.draw_path(gc, p, transform, rgbFace)
|
||||
except OverflowError:
|
||||
raise OverflowError("Exceeded cell block limit (set "
|
||||
"'agg.path.chunksize' rcparam)")
|
||||
else:
|
||||
try:
|
||||
self._renderer.draw_path(gc, path, transform, rgbFace)
|
||||
except OverflowError:
|
||||
raise OverflowError("Exceeded cell block limit (set "
|
||||
"'agg.path.chunksize' rcparam)")
|
||||
|
||||
def draw_mathtext(self, gc, x, y, s, prop, angle):
|
||||
"""
|
||||
Draw the math text using matplotlib.mathtext
|
||||
"""
|
||||
ox, oy, width, height, descent, font_image, used_characters = \
|
||||
self.mathtext_parser.parse(s, self.dpi, prop)
|
||||
|
||||
xd = descent * sin(radians(angle))
|
||||
yd = descent * cos(radians(angle))
|
||||
x = np.round(x + ox + xd)
|
||||
y = np.round(y - oy + yd)
|
||||
self._renderer.draw_text_image(font_image, x, y + 1, angle, gc)
|
||||
|
||||
def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
|
||||
# docstring inherited
|
||||
|
||||
if ismath:
|
||||
return self.draw_mathtext(gc, x, y, s, prop, angle)
|
||||
|
||||
flags = get_hinting_flag()
|
||||
font = self._get_agg_font(prop)
|
||||
|
||||
if font is None:
|
||||
return None
|
||||
if len(s) == 1 and ord(s) > 127:
|
||||
font.load_char(ord(s), flags=flags)
|
||||
else:
|
||||
# We pass '0' for angle here, since it will be rotated (in raster
|
||||
# space) in the following call to draw_text_image).
|
||||
font.set_text(s, 0, flags=flags)
|
||||
font.draw_glyphs_to_bitmap(antialiased=rcParams['text.antialiased'])
|
||||
d = font.get_descent() / 64.0
|
||||
# The descent needs to be adjusted for the angle.
|
||||
xo, yo = font.get_bitmap_offset()
|
||||
xo /= 64.0
|
||||
yo /= 64.0
|
||||
xd = -d * sin(radians(angle))
|
||||
yd = d * cos(radians(angle))
|
||||
|
||||
self._renderer.draw_text_image(
|
||||
font, np.round(x - xd + xo), np.round(y + yd + yo) + 1, angle, gc)
|
||||
|
||||
def get_text_width_height_descent(self, s, prop, ismath):
|
||||
# docstring inherited
|
||||
|
||||
if ismath in ["TeX", "TeX!"]:
|
||||
# todo: handle props
|
||||
texmanager = self.get_texmanager()
|
||||
fontsize = prop.get_size_in_points()
|
||||
w, h, d = texmanager.get_text_width_height_descent(
|
||||
s, fontsize, renderer=self)
|
||||
return w, h, d
|
||||
|
||||
if ismath:
|
||||
ox, oy, width, height, descent, fonts, used_characters = \
|
||||
self.mathtext_parser.parse(s, self.dpi, prop)
|
||||
return width, height, descent
|
||||
|
||||
flags = get_hinting_flag()
|
||||
font = self._get_agg_font(prop)
|
||||
font.set_text(s, 0.0, flags=flags)
|
||||
w, h = font.get_width_height() # width and height of unrotated string
|
||||
d = font.get_descent()
|
||||
w /= 64.0 # convert from subpixels
|
||||
h /= 64.0
|
||||
d /= 64.0
|
||||
return w, h, d
|
||||
|
||||
def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
|
||||
# docstring inherited
|
||||
# todo, handle props, angle, origins
|
||||
size = prop.get_size_in_points()
|
||||
|
||||
texmanager = self.get_texmanager()
|
||||
|
||||
Z = texmanager.get_grey(s, size, self.dpi)
|
||||
Z = np.array(Z * 255.0, np.uint8)
|
||||
|
||||
w, h, d = self.get_text_width_height_descent(s, prop, ismath)
|
||||
xd = d * sin(radians(angle))
|
||||
yd = d * cos(radians(angle))
|
||||
x = np.round(x + xd)
|
||||
y = np.round(y + yd)
|
||||
|
||||
self._renderer.draw_text_image(Z, x, y, angle, gc)
|
||||
|
||||
def get_canvas_width_height(self):
|
||||
# docstring inherited
|
||||
return self.width, self.height
|
||||
|
||||
def _get_agg_font(self, prop):
|
||||
"""
|
||||
Get the font for text instance t, caching for efficiency
|
||||
"""
|
||||
fname = findfont(prop)
|
||||
font = get_font(fname)
|
||||
|
||||
font.clear()
|
||||
size = prop.get_size_in_points()
|
||||
font.set_size(size, self.dpi)
|
||||
|
||||
return font
|
||||
|
||||
def points_to_pixels(self, points):
|
||||
# docstring inherited
|
||||
return points * self.dpi / 72
|
||||
|
||||
def buffer_rgba(self):
|
||||
return memoryview(self._renderer)
|
||||
|
||||
def tostring_argb(self):
|
||||
return np.asarray(self._renderer).take([3, 0, 1, 2], axis=2).tobytes()
|
||||
|
||||
def tostring_rgb(self):
|
||||
return np.asarray(self._renderer).take([0, 1, 2], axis=2).tobytes()
|
||||
|
||||
def clear(self):
|
||||
self._renderer.clear()
|
||||
|
||||
def option_image_nocomposite(self):
|
||||
# docstring inherited
|
||||
|
||||
# It is generally faster to composite each image directly to
|
||||
# the Figure, and there's no file size benefit to compositing
|
||||
# with the Agg backend
|
||||
return True
|
||||
|
||||
def option_scale_image(self):
|
||||
# docstring inherited
|
||||
return False
|
||||
|
||||
def restore_region(self, region, bbox=None, xy=None):
|
||||
"""
|
||||
Restore the saved region. If bbox (instance of BboxBase, or
|
||||
its extents) is given, only the region specified by the bbox
|
||||
will be restored. *xy* (a pair of floats) optionally
|
||||
specifies the new position (the LLC of the original region,
|
||||
not the LLC of the bbox) where the region will be restored.
|
||||
|
||||
>>> region = renderer.copy_from_bbox()
|
||||
>>> x1, y1, x2, y2 = region.get_extents()
|
||||
>>> renderer.restore_region(region, bbox=(x1+dx, y1, x2, y2),
|
||||
... xy=(x1-dx, y1))
|
||||
|
||||
"""
|
||||
if bbox is not None or xy is not None:
|
||||
if bbox is None:
|
||||
x1, y1, x2, y2 = region.get_extents()
|
||||
elif isinstance(bbox, BboxBase):
|
||||
x1, y1, x2, y2 = bbox.extents
|
||||
else:
|
||||
x1, y1, x2, y2 = bbox
|
||||
|
||||
if xy is None:
|
||||
ox, oy = x1, y1
|
||||
else:
|
||||
ox, oy = xy
|
||||
|
||||
# The incoming data is float, but the _renderer type-checking wants
|
||||
# to see integers.
|
||||
self._renderer.restore_region(region, int(x1), int(y1),
|
||||
int(x2), int(y2), int(ox), int(oy))
|
||||
|
||||
else:
|
||||
self._renderer.restore_region(region)
|
||||
|
||||
def start_filter(self):
|
||||
"""
|
||||
Start filtering. It simply create a new canvas (the old one is saved).
|
||||
"""
|
||||
self._filter_renderers.append(self._renderer)
|
||||
self._renderer = _RendererAgg(int(self.width), int(self.height),
|
||||
self.dpi)
|
||||
self._update_methods()
|
||||
|
||||
def stop_filter(self, post_processing):
|
||||
"""
|
||||
Save the plot in the current canvas as a image and apply
|
||||
the *post_processing* function.
|
||||
|
||||
def post_processing(image, dpi):
|
||||
# ny, nx, depth = image.shape
|
||||
# image (numpy array) has RGBA channels and has a depth of 4.
|
||||
...
|
||||
# create a new_image (numpy array of 4 channels, size can be
|
||||
# different). The resulting image may have offsets from
|
||||
# lower-left corner of the original image
|
||||
return new_image, offset_x, offset_y
|
||||
|
||||
The saved renderer is restored and the returned image from
|
||||
post_processing is plotted (using draw_image) on it.
|
||||
"""
|
||||
|
||||
width, height = int(self.width), int(self.height)
|
||||
|
||||
buffer, (l, b, w, h) = self.tostring_rgba_minimized()
|
||||
|
||||
self._renderer = self._filter_renderers.pop()
|
||||
self._update_methods()
|
||||
|
||||
if w > 0 and h > 0:
|
||||
img = np.frombuffer(buffer, np.uint8)
|
||||
img, ox, oy = post_processing(img.reshape((h, w, 4)) / 255.,
|
||||
self.dpi)
|
||||
gc = self.new_gc()
|
||||
if img.dtype.kind == 'f':
|
||||
img = np.asarray(img * 255., np.uint8)
|
||||
img = img[::-1]
|
||||
self._renderer.draw_image(gc, l + ox, height - b - h + oy, img)
|
||||
|
||||
|
||||
class FigureCanvasAgg(FigureCanvasBase):
|
||||
"""
|
||||
The canvas the figure renders into. Calls the draw and print fig
|
||||
methods, creates the renderers, etc...
|
||||
|
||||
Attributes
|
||||
----------
|
||||
figure : `matplotlib.figure.Figure`
|
||||
A high-level Figure instance
|
||||
|
||||
"""
|
||||
|
||||
def copy_from_bbox(self, bbox):
|
||||
renderer = self.get_renderer()
|
||||
return renderer.copy_from_bbox(bbox)
|
||||
|
||||
def restore_region(self, region, bbox=None, xy=None):
|
||||
renderer = self.get_renderer()
|
||||
return renderer.restore_region(region, bbox, xy)
|
||||
|
||||
def draw(self):
|
||||
"""
|
||||
Draw the figure using the renderer.
|
||||
"""
|
||||
self.renderer = self.get_renderer(cleared=True)
|
||||
with RendererAgg.lock:
|
||||
self.figure.draw(self.renderer)
|
||||
# A GUI class may be need to update a window using this draw, so
|
||||
# don't forget to call the superclass.
|
||||
super().draw()
|
||||
|
||||
def get_renderer(self, cleared=False):
|
||||
l, b, w, h = self.figure.bbox.bounds
|
||||
key = w, h, self.figure.dpi
|
||||
reuse_renderer = (hasattr(self, "renderer")
|
||||
and getattr(self, "_lastKey", None) == key)
|
||||
if not reuse_renderer:
|
||||
self.renderer = RendererAgg(w, h, self.figure.dpi)
|
||||
self._lastKey = key
|
||||
elif cleared:
|
||||
self.renderer.clear()
|
||||
return self.renderer
|
||||
|
||||
def tostring_rgb(self):
|
||||
"""Get the image as an RGB byte string.
|
||||
|
||||
`draw` must be called at least once before this function will work and
|
||||
to update the renderer for any subsequent changes to the Figure.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bytes
|
||||
"""
|
||||
return self.renderer.tostring_rgb()
|
||||
|
||||
def tostring_argb(self):
|
||||
"""Get the image as an ARGB byte string.
|
||||
|
||||
`draw` must be called at least once before this function will work and
|
||||
to update the renderer for any subsequent changes to the Figure.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bytes
|
||||
"""
|
||||
return self.renderer.tostring_argb()
|
||||
|
||||
def buffer_rgba(self):
|
||||
"""Get the image as a memoryview to the renderer's buffer.
|
||||
|
||||
`draw` must be called at least once before this function will work and
|
||||
to update the renderer for any subsequent changes to the Figure.
|
||||
|
||||
Returns
|
||||
-------
|
||||
memoryview
|
||||
"""
|
||||
return self.renderer.buffer_rgba()
|
||||
|
||||
def print_raw(self, filename_or_obj, *args, **kwargs):
|
||||
FigureCanvasAgg.draw(self)
|
||||
renderer = self.get_renderer()
|
||||
with cbook._setattr_cm(renderer, dpi=self.figure.dpi), \
|
||||
cbook.open_file_cm(filename_or_obj, "wb") as fh:
|
||||
fh.write(renderer._renderer.buffer_rgba())
|
||||
|
||||
print_rgba = print_raw
|
||||
|
||||
def print_png(self, filename_or_obj, *args,
|
||||
metadata=None, pil_kwargs=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Write the figure to a PNG file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename_or_obj : str or PathLike or file-like object
|
||||
The file to write to.
|
||||
|
||||
metadata : dict, optional
|
||||
Metadata in the PNG file as key-value pairs of bytes or latin-1
|
||||
encodable strings.
|
||||
According to the PNG specification, keys must be shorter than 79
|
||||
chars.
|
||||
|
||||
The `PNG specification`_ defines some common keywords that may be
|
||||
used as appropriate:
|
||||
|
||||
- Title: Short (one line) title or caption for image.
|
||||
- Author: Name of image's creator.
|
||||
- Description: Description of image (possibly long).
|
||||
- Copyright: Copyright notice.
|
||||
- Creation Time: Time of original image creation
|
||||
(usually RFC 1123 format).
|
||||
- Software: Software used to create the image.
|
||||
- Disclaimer: Legal disclaimer.
|
||||
- Warning: Warning of nature of content.
|
||||
- Source: Device used to create the image.
|
||||
- Comment: Miscellaneous comment;
|
||||
conversion from other image format.
|
||||
|
||||
Other keywords may be invented for other purposes.
|
||||
|
||||
If 'Software' is not given, an autogenerated value for matplotlib
|
||||
will be used.
|
||||
|
||||
For more details see the `PNG specification`_.
|
||||
|
||||
.. _PNG specification: \
|
||||
https://www.w3.org/TR/2003/REC-PNG-20031110/#11keywords
|
||||
|
||||
pil_kwargs : dict, optional
|
||||
If set to a non-None value, use Pillow to save the figure instead
|
||||
of Matplotlib's builtin PNG support, and pass these keyword
|
||||
arguments to `PIL.Image.save`.
|
||||
|
||||
If the 'pnginfo' key is present, it completely overrides
|
||||
*metadata*, including the default 'Software' key.
|
||||
"""
|
||||
from matplotlib import _png
|
||||
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
metadata = {
|
||||
"Software":
|
||||
f"matplotlib version{__version__}, http://matplotlib.org/",
|
||||
**metadata,
|
||||
}
|
||||
|
||||
if pil_kwargs is not None:
|
||||
from PIL import Image
|
||||
from PIL.PngImagePlugin import PngInfo
|
||||
buf, size = self.print_to_buffer()
|
||||
# Only use the metadata kwarg if pnginfo is not set, because the
|
||||
# semantics of duplicate keys in pnginfo is unclear.
|
||||
if "pnginfo" not in pil_kwargs:
|
||||
pnginfo = PngInfo()
|
||||
for k, v in metadata.items():
|
||||
pnginfo.add_text(k, v)
|
||||
pil_kwargs["pnginfo"] = pnginfo
|
||||
pil_kwargs.setdefault("dpi", (self.figure.dpi, self.figure.dpi))
|
||||
(Image.frombuffer("RGBA", size, buf, "raw", "RGBA", 0, 1)
|
||||
.save(filename_or_obj, format="png", **pil_kwargs))
|
||||
|
||||
else:
|
||||
FigureCanvasAgg.draw(self)
|
||||
renderer = self.get_renderer()
|
||||
with cbook._setattr_cm(renderer, dpi=self.figure.dpi), \
|
||||
cbook.open_file_cm(filename_or_obj, "wb") as fh:
|
||||
_png.write_png(renderer._renderer, fh,
|
||||
self.figure.dpi, metadata=metadata)
|
||||
|
||||
def print_to_buffer(self):
|
||||
FigureCanvasAgg.draw(self)
|
||||
renderer = self.get_renderer()
|
||||
with cbook._setattr_cm(renderer, dpi=self.figure.dpi):
|
||||
return (renderer._renderer.buffer_rgba(),
|
||||
(int(renderer.width), int(renderer.height)))
|
||||
|
||||
if _has_pil:
|
||||
|
||||
# Note that these methods should typically be called via savefig() and
|
||||
# print_figure(), and the latter ensures that `self.figure.dpi` already
|
||||
# matches the dpi kwarg (if any).
|
||||
|
||||
def print_jpg(self, filename_or_obj, *args, dryrun=False,
|
||||
pil_kwargs=None, **kwargs):
|
||||
"""
|
||||
Write the figure to a JPEG file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename_or_obj : str or PathLike or file-like object
|
||||
The file to write to.
|
||||
|
||||
Other Parameters
|
||||
----------------
|
||||
quality : int
|
||||
The image quality, on a scale from 1 (worst) to 100 (best).
|
||||
The default is :rc:`savefig.jpeg_quality`. Values above
|
||||
95 should be avoided; 100 completely disables the JPEG
|
||||
quantization stage.
|
||||
|
||||
optimize : bool
|
||||
If present, indicates that the encoder should
|
||||
make an extra pass over the image in order to select
|
||||
optimal encoder settings.
|
||||
|
||||
progressive : bool
|
||||
If present, indicates that this image
|
||||
should be stored as a progressive JPEG file.
|
||||
|
||||
pil_kwargs : dict, optional
|
||||
Additional keyword arguments that are passed to
|
||||
`PIL.Image.save` when saving the figure. These take precedence
|
||||
over *quality*, *optimize* and *progressive*.
|
||||
"""
|
||||
buf, size = self.print_to_buffer()
|
||||
if dryrun:
|
||||
return
|
||||
# The image is "pasted" onto a white background image to safely
|
||||
# handle any transparency
|
||||
image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
|
||||
rgba = mcolors.to_rgba(rcParams['savefig.facecolor'])
|
||||
color = tuple([int(x * 255) for x in rgba[:3]])
|
||||
background = Image.new('RGB', size, color)
|
||||
background.paste(image, image)
|
||||
if pil_kwargs is None:
|
||||
pil_kwargs = {}
|
||||
for k in ["quality", "optimize", "progressive"]:
|
||||
if k in kwargs:
|
||||
pil_kwargs.setdefault(k, kwargs[k])
|
||||
pil_kwargs.setdefault("quality", rcParams["savefig.jpeg_quality"])
|
||||
pil_kwargs.setdefault("dpi", (self.figure.dpi, self.figure.dpi))
|
||||
return background.save(
|
||||
filename_or_obj, format='jpeg', **pil_kwargs)
|
||||
|
||||
print_jpeg = print_jpg
|
||||
|
||||
def print_tif(self, filename_or_obj, *args, dryrun=False,
|
||||
pil_kwargs=None, **kwargs):
|
||||
buf, size = self.print_to_buffer()
|
||||
if dryrun:
|
||||
return
|
||||
image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
|
||||
if pil_kwargs is None:
|
||||
pil_kwargs = {}
|
||||
pil_kwargs.setdefault("dpi", (self.figure.dpi, self.figure.dpi))
|
||||
return image.save(filename_or_obj, format='tiff', **pil_kwargs)
|
||||
|
||||
print_tiff = print_tif
|
||||
|
||||
|
||||
@_Backend.export
|
||||
class _BackendAgg(_Backend):
|
||||
FigureCanvas = FigureCanvasAgg
|
||||
FigureManager = FigureManagerBase
|
||||
511
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_cairo.py
vendored
Normal file
511
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_cairo.py
vendored
Normal file
@@ -0,0 +1,511 @@
|
||||
"""
|
||||
A Cairo backend for matplotlib
|
||||
==============================
|
||||
:Author: Steve Chaplin and others
|
||||
|
||||
This backend depends on cairocffi or pycairo.
|
||||
"""
|
||||
|
||||
import gzip
|
||||
|
||||
import numpy as np
|
||||
|
||||
try:
|
||||
import cairo
|
||||
if cairo.version_info < (1, 11, 0):
|
||||
# Introduced create_for_data for Py3.
|
||||
raise ImportError
|
||||
except ImportError:
|
||||
try:
|
||||
import cairocffi as cairo
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"cairo backend requires that pycairo>=1.11.0 or cairocffi"
|
||||
"is installed")
|
||||
|
||||
backend_version = cairo.version
|
||||
|
||||
from .. import cbook
|
||||
from matplotlib.backend_bases import (
|
||||
_Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
|
||||
RendererBase)
|
||||
from matplotlib.font_manager import ttfFontProperty
|
||||
from matplotlib.mathtext import MathTextParser
|
||||
from matplotlib.path import Path
|
||||
from matplotlib.transforms import Affine2D
|
||||
|
||||
|
||||
if cairo.__name__ == "cairocffi":
|
||||
# Convert a pycairo context to a cairocffi one.
|
||||
def _to_context(ctx):
|
||||
if not isinstance(ctx, cairo.Context):
|
||||
ctx = cairo.Context._from_pointer(
|
||||
cairo.ffi.cast(
|
||||
'cairo_t **',
|
||||
id(ctx) + object.__basicsize__)[0],
|
||||
incref=True)
|
||||
return ctx
|
||||
else:
|
||||
# Pass-through a pycairo context.
|
||||
def _to_context(ctx):
|
||||
return ctx
|
||||
|
||||
|
||||
@cbook.deprecated("3.0")
|
||||
class ArrayWrapper:
|
||||
"""Thin wrapper around numpy ndarray to expose the interface
|
||||
expected by cairocffi. Basically replicates the
|
||||
array.array interface.
|
||||
"""
|
||||
def __init__(self, myarray):
|
||||
self.__array = myarray
|
||||
self.__data = myarray.ctypes.data
|
||||
self.__size = len(myarray.flatten())
|
||||
self.itemsize = myarray.itemsize
|
||||
|
||||
def buffer_info(self):
|
||||
return (self.__data, self.__size)
|
||||
|
||||
|
||||
def _append_path(ctx, path, transform, clip=None):
|
||||
for points, code in path.iter_segments(
|
||||
transform, remove_nans=True, clip=clip):
|
||||
if code == Path.MOVETO:
|
||||
ctx.move_to(*points)
|
||||
elif code == Path.CLOSEPOLY:
|
||||
ctx.close_path()
|
||||
elif code == Path.LINETO:
|
||||
ctx.line_to(*points)
|
||||
elif code == Path.CURVE3:
|
||||
cur = np.asarray(ctx.get_current_point())
|
||||
a = points[:2]
|
||||
b = points[-2:]
|
||||
ctx.curve_to(*(cur / 3 + a * 2 / 3), *(a * 2 / 3 + b / 3), *b)
|
||||
elif code == Path.CURVE4:
|
||||
ctx.curve_to(*points)
|
||||
|
||||
|
||||
class RendererCairo(RendererBase):
|
||||
fontweights = {
|
||||
100 : cairo.FONT_WEIGHT_NORMAL,
|
||||
200 : cairo.FONT_WEIGHT_NORMAL,
|
||||
300 : cairo.FONT_WEIGHT_NORMAL,
|
||||
400 : cairo.FONT_WEIGHT_NORMAL,
|
||||
500 : cairo.FONT_WEIGHT_NORMAL,
|
||||
600 : cairo.FONT_WEIGHT_BOLD,
|
||||
700 : cairo.FONT_WEIGHT_BOLD,
|
||||
800 : cairo.FONT_WEIGHT_BOLD,
|
||||
900 : cairo.FONT_WEIGHT_BOLD,
|
||||
'ultralight' : cairo.FONT_WEIGHT_NORMAL,
|
||||
'light' : cairo.FONT_WEIGHT_NORMAL,
|
||||
'normal' : cairo.FONT_WEIGHT_NORMAL,
|
||||
'medium' : cairo.FONT_WEIGHT_NORMAL,
|
||||
'regular' : cairo.FONT_WEIGHT_NORMAL,
|
||||
'semibold' : cairo.FONT_WEIGHT_BOLD,
|
||||
'bold' : cairo.FONT_WEIGHT_BOLD,
|
||||
'heavy' : cairo.FONT_WEIGHT_BOLD,
|
||||
'ultrabold' : cairo.FONT_WEIGHT_BOLD,
|
||||
'black' : cairo.FONT_WEIGHT_BOLD,
|
||||
}
|
||||
fontangles = {
|
||||
'italic' : cairo.FONT_SLANT_ITALIC,
|
||||
'normal' : cairo.FONT_SLANT_NORMAL,
|
||||
'oblique' : cairo.FONT_SLANT_OBLIQUE,
|
||||
}
|
||||
|
||||
def __init__(self, dpi):
|
||||
self.dpi = dpi
|
||||
self.gc = GraphicsContextCairo(renderer=self)
|
||||
self.text_ctx = cairo.Context(
|
||||
cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1))
|
||||
self.mathtext_parser = MathTextParser('Cairo')
|
||||
RendererBase.__init__(self)
|
||||
|
||||
def set_ctx_from_surface(self, surface):
|
||||
self.gc.ctx = cairo.Context(surface)
|
||||
# Although it may appear natural to automatically call
|
||||
# `self.set_width_height(surface.get_width(), surface.get_height())`
|
||||
# here (instead of having the caller do so separately), this would fail
|
||||
# for PDF/PS/SVG surfaces, which have no way to report their extents.
|
||||
|
||||
def set_width_height(self, width, height):
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
def _fill_and_stroke(self, ctx, fill_c, alpha, alpha_overrides):
|
||||
if fill_c is not None:
|
||||
ctx.save()
|
||||
if len(fill_c) == 3 or alpha_overrides:
|
||||
ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], alpha)
|
||||
else:
|
||||
ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], fill_c[3])
|
||||
ctx.fill_preserve()
|
||||
ctx.restore()
|
||||
ctx.stroke()
|
||||
|
||||
@staticmethod
|
||||
@cbook.deprecated("3.0")
|
||||
def convert_path(ctx, path, transform, clip=None):
|
||||
_append_path(ctx, path, transform, clip)
|
||||
|
||||
def draw_path(self, gc, path, transform, rgbFace=None):
|
||||
# docstring inherited
|
||||
ctx = gc.ctx
|
||||
# Clip the path to the actual rendering extents if it isn't filled.
|
||||
clip = (ctx.clip_extents()
|
||||
if rgbFace is None and gc.get_hatch() is None
|
||||
else None)
|
||||
transform = (transform
|
||||
+ Affine2D().scale(1, -1).translate(0, self.height))
|
||||
ctx.new_path()
|
||||
_append_path(ctx, path, transform, clip)
|
||||
self._fill_and_stroke(
|
||||
ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
|
||||
|
||||
def draw_markers(self, gc, marker_path, marker_trans, path, transform,
|
||||
rgbFace=None):
|
||||
# docstring inherited
|
||||
|
||||
ctx = gc.ctx
|
||||
ctx.new_path()
|
||||
# Create the path for the marker; it needs to be flipped here already!
|
||||
_append_path(ctx, marker_path, marker_trans + Affine2D().scale(1, -1))
|
||||
marker_path = ctx.copy_path_flat()
|
||||
|
||||
# Figure out whether the path has a fill
|
||||
x1, y1, x2, y2 = ctx.fill_extents()
|
||||
if x1 == 0 and y1 == 0 and x2 == 0 and y2 == 0:
|
||||
filled = False
|
||||
# No fill, just unset this (so we don't try to fill it later on)
|
||||
rgbFace = None
|
||||
else:
|
||||
filled = True
|
||||
|
||||
transform = (transform
|
||||
+ Affine2D().scale(1, -1).translate(0, self.height))
|
||||
|
||||
ctx.new_path()
|
||||
for i, (vertices, codes) in enumerate(
|
||||
path.iter_segments(transform, simplify=False)):
|
||||
if len(vertices):
|
||||
x, y = vertices[-2:]
|
||||
ctx.save()
|
||||
|
||||
# Translate and apply path
|
||||
ctx.translate(x, y)
|
||||
ctx.append_path(marker_path)
|
||||
|
||||
ctx.restore()
|
||||
|
||||
# Slower code path if there is a fill; we need to draw
|
||||
# the fill and stroke for each marker at the same time.
|
||||
# Also flush out the drawing every once in a while to
|
||||
# prevent the paths from getting way too long.
|
||||
if filled or i % 1000 == 0:
|
||||
self._fill_and_stroke(
|
||||
ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
|
||||
|
||||
# Fast path, if there is no fill, draw everything in one step
|
||||
if not filled:
|
||||
self._fill_and_stroke(
|
||||
ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
|
||||
|
||||
def draw_image(self, gc, x, y, im):
|
||||
im = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(im[::-1])
|
||||
surface = cairo.ImageSurface.create_for_data(
|
||||
im.ravel().data, cairo.FORMAT_ARGB32,
|
||||
im.shape[1], im.shape[0], im.shape[1] * 4)
|
||||
ctx = gc.ctx
|
||||
y = self.height - y - im.shape[0]
|
||||
|
||||
ctx.save()
|
||||
ctx.set_source_surface(surface, float(x), float(y))
|
||||
ctx.paint()
|
||||
ctx.restore()
|
||||
|
||||
def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
|
||||
# docstring inherited
|
||||
|
||||
# Note: x,y are device/display coords, not user-coords, unlike other
|
||||
# draw_* methods
|
||||
if ismath:
|
||||
self._draw_mathtext(gc, x, y, s, prop, angle)
|
||||
|
||||
else:
|
||||
ctx = gc.ctx
|
||||
ctx.new_path()
|
||||
ctx.move_to(x, y)
|
||||
ctx.select_font_face(prop.get_name(),
|
||||
self.fontangles[prop.get_style()],
|
||||
self.fontweights[prop.get_weight()])
|
||||
|
||||
size = prop.get_size_in_points() * self.dpi / 72.0
|
||||
|
||||
ctx.save()
|
||||
if angle:
|
||||
ctx.rotate(np.deg2rad(-angle))
|
||||
ctx.set_font_size(size)
|
||||
|
||||
ctx.show_text(s)
|
||||
ctx.restore()
|
||||
|
||||
def _draw_mathtext(self, gc, x, y, s, prop, angle):
|
||||
ctx = gc.ctx
|
||||
width, height, descent, glyphs, rects = self.mathtext_parser.parse(
|
||||
s, self.dpi, prop)
|
||||
|
||||
ctx.save()
|
||||
ctx.translate(x, y)
|
||||
if angle:
|
||||
ctx.rotate(np.deg2rad(-angle))
|
||||
|
||||
for font, fontsize, s, ox, oy in glyphs:
|
||||
ctx.new_path()
|
||||
ctx.move_to(ox, oy)
|
||||
|
||||
fontProp = ttfFontProperty(font)
|
||||
ctx.select_font_face(fontProp.name,
|
||||
self.fontangles[fontProp.style],
|
||||
self.fontweights[fontProp.weight])
|
||||
|
||||
size = fontsize * self.dpi / 72.0
|
||||
ctx.set_font_size(size)
|
||||
ctx.show_text(s)
|
||||
|
||||
for ox, oy, w, h in rects:
|
||||
ctx.new_path()
|
||||
ctx.rectangle(ox, oy, w, h)
|
||||
ctx.set_source_rgb(0, 0, 0)
|
||||
ctx.fill_preserve()
|
||||
|
||||
ctx.restore()
|
||||
|
||||
def get_canvas_width_height(self):
|
||||
# docstring inherited
|
||||
return self.width, self.height
|
||||
|
||||
def get_text_width_height_descent(self, s, prop, ismath):
|
||||
# docstring inherited
|
||||
|
||||
if ismath:
|
||||
width, height, descent, fonts, used_characters = \
|
||||
self.mathtext_parser.parse(s, self.dpi, prop)
|
||||
return width, height, descent
|
||||
|
||||
ctx = self.text_ctx
|
||||
ctx.save()
|
||||
ctx.select_font_face(prop.get_name(),
|
||||
self.fontangles[prop.get_style()],
|
||||
self.fontweights[prop.get_weight()])
|
||||
|
||||
# Cairo (says it) uses 1/96 inch user space units, ref: cairo_gstate.c
|
||||
# but if /96.0 is used the font is too small
|
||||
size = prop.get_size_in_points() * self.dpi / 72
|
||||
|
||||
# problem - scale remembers last setting and font can become
|
||||
# enormous causing program to crash
|
||||
# save/restore prevents the problem
|
||||
ctx.set_font_size(size)
|
||||
|
||||
y_bearing, w, h = ctx.text_extents(s)[1:4]
|
||||
ctx.restore()
|
||||
|
||||
return w, h, h + y_bearing
|
||||
|
||||
def new_gc(self):
|
||||
# docstring inherited
|
||||
self.gc.ctx.save()
|
||||
self.gc._alpha = 1
|
||||
self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
|
||||
return self.gc
|
||||
|
||||
def points_to_pixels(self, points):
|
||||
# docstring inherited
|
||||
return points / 72 * self.dpi
|
||||
|
||||
|
||||
class GraphicsContextCairo(GraphicsContextBase):
|
||||
_joind = {
|
||||
'bevel' : cairo.LINE_JOIN_BEVEL,
|
||||
'miter' : cairo.LINE_JOIN_MITER,
|
||||
'round' : cairo.LINE_JOIN_ROUND,
|
||||
}
|
||||
|
||||
_capd = {
|
||||
'butt' : cairo.LINE_CAP_BUTT,
|
||||
'projecting' : cairo.LINE_CAP_SQUARE,
|
||||
'round' : cairo.LINE_CAP_ROUND,
|
||||
}
|
||||
|
||||
def __init__(self, renderer):
|
||||
GraphicsContextBase.__init__(self)
|
||||
self.renderer = renderer
|
||||
|
||||
def restore(self):
|
||||
self.ctx.restore()
|
||||
|
||||
def set_alpha(self, alpha):
|
||||
GraphicsContextBase.set_alpha(self, alpha)
|
||||
_alpha = self.get_alpha()
|
||||
rgb = self._rgb
|
||||
if self.get_forced_alpha():
|
||||
self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], _alpha)
|
||||
else:
|
||||
self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], rgb[3])
|
||||
|
||||
# def set_antialiased(self, b):
|
||||
# cairo has many antialiasing modes, we need to pick one for True and
|
||||
# one for False.
|
||||
|
||||
def set_capstyle(self, cs):
|
||||
if cs in ('butt', 'round', 'projecting'):
|
||||
self._capstyle = cs
|
||||
self.ctx.set_line_cap(self._capd[cs])
|
||||
else:
|
||||
raise ValueError('Unrecognized cap style. Found %s' % cs)
|
||||
|
||||
def set_clip_rectangle(self, rectangle):
|
||||
if not rectangle:
|
||||
return
|
||||
x, y, w, h = np.round(rectangle.bounds)
|
||||
ctx = self.ctx
|
||||
ctx.new_path()
|
||||
ctx.rectangle(x, self.renderer.height - h - y, w, h)
|
||||
ctx.clip()
|
||||
|
||||
def set_clip_path(self, path):
|
||||
if not path:
|
||||
return
|
||||
tpath, affine = path.get_transformed_path_and_affine()
|
||||
ctx = self.ctx
|
||||
ctx.new_path()
|
||||
affine = (affine
|
||||
+ Affine2D().scale(1, -1).translate(0, self.renderer.height))
|
||||
_append_path(ctx, tpath, affine)
|
||||
ctx.clip()
|
||||
|
||||
def set_dashes(self, offset, dashes):
|
||||
self._dashes = offset, dashes
|
||||
if dashes is None:
|
||||
self.ctx.set_dash([], 0) # switch dashes off
|
||||
else:
|
||||
self.ctx.set_dash(
|
||||
list(self.renderer.points_to_pixels(np.asarray(dashes))),
|
||||
offset)
|
||||
|
||||
def set_foreground(self, fg, isRGBA=None):
|
||||
GraphicsContextBase.set_foreground(self, fg, isRGBA)
|
||||
if len(self._rgb) == 3:
|
||||
self.ctx.set_source_rgb(*self._rgb)
|
||||
else:
|
||||
self.ctx.set_source_rgba(*self._rgb)
|
||||
|
||||
def get_rgb(self):
|
||||
return self.ctx.get_source().get_rgba()[:3]
|
||||
|
||||
def set_joinstyle(self, js):
|
||||
if js in ('miter', 'round', 'bevel'):
|
||||
self._joinstyle = js
|
||||
self.ctx.set_line_join(self._joind[js])
|
||||
else:
|
||||
raise ValueError('Unrecognized join style. Found %s' % js)
|
||||
|
||||
def set_linewidth(self, w):
|
||||
self._linewidth = float(w)
|
||||
self.ctx.set_line_width(self.renderer.points_to_pixels(w))
|
||||
|
||||
|
||||
class FigureCanvasCairo(FigureCanvasBase):
|
||||
supports_blit = False
|
||||
|
||||
def print_png(self, fobj, *args, **kwargs):
|
||||
self._get_printed_image_surface().write_to_png(fobj)
|
||||
|
||||
def print_rgba(self, fobj, *args, **kwargs):
|
||||
width, height = self.get_width_height()
|
||||
buf = self._get_printed_image_surface().get_data()
|
||||
fobj.write(cbook._premultiplied_argb32_to_unmultiplied_rgba8888(
|
||||
np.asarray(buf).reshape((width, height, 4))))
|
||||
|
||||
print_raw = print_rgba
|
||||
|
||||
def _get_printed_image_surface(self):
|
||||
width, height = self.get_width_height()
|
||||
renderer = RendererCairo(self.figure.dpi)
|
||||
renderer.set_width_height(width, height)
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
||||
renderer.set_ctx_from_surface(surface)
|
||||
self.figure.draw(renderer)
|
||||
return surface
|
||||
|
||||
def print_pdf(self, fobj, *args, **kwargs):
|
||||
return self._save(fobj, 'pdf', *args, **kwargs)
|
||||
|
||||
def print_ps(self, fobj, *args, **kwargs):
|
||||
return self._save(fobj, 'ps', *args, **kwargs)
|
||||
|
||||
def print_svg(self, fobj, *args, **kwargs):
|
||||
return self._save(fobj, 'svg', *args, **kwargs)
|
||||
|
||||
def print_svgz(self, fobj, *args, **kwargs):
|
||||
return self._save(fobj, 'svgz', *args, **kwargs)
|
||||
|
||||
def _save(self, fo, fmt, **kwargs):
|
||||
# save PDF/PS/SVG
|
||||
orientation = kwargs.get('orientation', 'portrait')
|
||||
|
||||
dpi = 72
|
||||
self.figure.dpi = dpi
|
||||
w_in, h_in = self.figure.get_size_inches()
|
||||
width_in_points, height_in_points = w_in * dpi, h_in * dpi
|
||||
|
||||
if orientation == 'landscape':
|
||||
width_in_points, height_in_points = (
|
||||
height_in_points, width_in_points)
|
||||
|
||||
if fmt == 'ps':
|
||||
if not hasattr(cairo, 'PSSurface'):
|
||||
raise RuntimeError('cairo has not been compiled with PS '
|
||||
'support enabled')
|
||||
surface = cairo.PSSurface(fo, width_in_points, height_in_points)
|
||||
elif fmt == 'pdf':
|
||||
if not hasattr(cairo, 'PDFSurface'):
|
||||
raise RuntimeError('cairo has not been compiled with PDF '
|
||||
'support enabled')
|
||||
surface = cairo.PDFSurface(fo, width_in_points, height_in_points)
|
||||
elif fmt in ('svg', 'svgz'):
|
||||
if not hasattr(cairo, 'SVGSurface'):
|
||||
raise RuntimeError('cairo has not been compiled with SVG '
|
||||
'support enabled')
|
||||
if fmt == 'svgz':
|
||||
if isinstance(fo, str):
|
||||
fo = gzip.GzipFile(fo, 'wb')
|
||||
else:
|
||||
fo = gzip.GzipFile(None, 'wb', fileobj=fo)
|
||||
surface = cairo.SVGSurface(fo, width_in_points, height_in_points)
|
||||
else:
|
||||
raise ValueError("Unknown format: {!r}".format(fmt))
|
||||
|
||||
# surface.set_dpi() can be used
|
||||
renderer = RendererCairo(self.figure.dpi)
|
||||
renderer.set_width_height(width_in_points, height_in_points)
|
||||
renderer.set_ctx_from_surface(surface)
|
||||
ctx = renderer.gc.ctx
|
||||
|
||||
if orientation == 'landscape':
|
||||
ctx.rotate(np.pi / 2)
|
||||
ctx.translate(0, -height_in_points)
|
||||
# Perhaps add an '%%Orientation: Landscape' comment?
|
||||
|
||||
self.figure.draw(renderer)
|
||||
|
||||
ctx.show_page()
|
||||
surface.finish()
|
||||
if fmt == 'svgz':
|
||||
fo.close()
|
||||
|
||||
|
||||
@_Backend.export
|
||||
class _BackendCairo(_Backend):
|
||||
FigureCanvas = FigureCanvasCairo
|
||||
FigureManager = FigureManagerBase
|
||||
1005
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_gtk3.py
vendored
Normal file
1005
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_gtk3.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
92
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_gtk3agg.py
vendored
Normal file
92
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_gtk3agg.py
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import numpy as np
|
||||
|
||||
from .. import cbook
|
||||
from . import backend_agg, backend_cairo, backend_gtk3
|
||||
from .backend_cairo import cairo
|
||||
from .backend_gtk3 import Gtk, _BackendGTK3
|
||||
from matplotlib import transforms
|
||||
|
||||
|
||||
class FigureCanvasGTK3Agg(backend_gtk3.FigureCanvasGTK3,
|
||||
backend_agg.FigureCanvasAgg):
|
||||
def __init__(self, figure):
|
||||
backend_gtk3.FigureCanvasGTK3.__init__(self, figure)
|
||||
self._bbox_queue = []
|
||||
|
||||
def _renderer_init(self):
|
||||
pass
|
||||
|
||||
def _render_figure(self, width, height):
|
||||
backend_agg.FigureCanvasAgg.draw(self)
|
||||
|
||||
def on_draw_event(self, widget, ctx):
|
||||
"""GtkDrawable draw event, like expose_event in GTK 2.X.
|
||||
"""
|
||||
allocation = self.get_allocation()
|
||||
w, h = allocation.width, allocation.height
|
||||
|
||||
if not len(self._bbox_queue):
|
||||
Gtk.render_background(
|
||||
self.get_style_context(), ctx,
|
||||
allocation.x, allocation.y,
|
||||
allocation.width, allocation.height)
|
||||
bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
|
||||
else:
|
||||
bbox_queue = self._bbox_queue
|
||||
|
||||
ctx = backend_cairo._to_context(ctx)
|
||||
|
||||
for bbox in bbox_queue:
|
||||
x = int(bbox.x0)
|
||||
y = h - int(bbox.y1)
|
||||
width = int(bbox.x1) - int(bbox.x0)
|
||||
height = int(bbox.y1) - int(bbox.y0)
|
||||
|
||||
buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
|
||||
np.asarray(self.copy_from_bbox(bbox)))
|
||||
image = cairo.ImageSurface.create_for_data(
|
||||
buf.ravel().data, cairo.FORMAT_ARGB32, width, height)
|
||||
ctx.set_source_surface(image, x, y)
|
||||
ctx.paint()
|
||||
|
||||
if len(self._bbox_queue):
|
||||
self._bbox_queue = []
|
||||
|
||||
return False
|
||||
|
||||
def blit(self, bbox=None):
|
||||
# If bbox is None, blit the entire canvas to gtk. Otherwise
|
||||
# blit only the area defined by the bbox.
|
||||
if bbox is None:
|
||||
bbox = self.figure.bbox
|
||||
|
||||
allocation = self.get_allocation()
|
||||
w, h = allocation.width, allocation.height
|
||||
x = int(bbox.x0)
|
||||
y = h - int(bbox.y1)
|
||||
width = int(bbox.x1) - int(bbox.x0)
|
||||
height = int(bbox.y1) - int(bbox.y0)
|
||||
|
||||
self._bbox_queue.append(bbox)
|
||||
self.queue_draw_area(x, y, width, height)
|
||||
|
||||
def draw(self):
|
||||
if self.get_visible() and self.get_mapped():
|
||||
allocation = self.get_allocation()
|
||||
self._render_figure(allocation.width, allocation.height)
|
||||
super().draw()
|
||||
|
||||
def print_png(self, filename, *args, **kwargs):
|
||||
# Do this so we can save the resolution of figure in the PNG file
|
||||
agg = self.switch_backends(backend_agg.FigureCanvasAgg)
|
||||
return agg.print_png(filename, *args, **kwargs)
|
||||
|
||||
|
||||
class FigureManagerGTK3Agg(backend_gtk3.FigureManagerGTK3):
|
||||
pass
|
||||
|
||||
|
||||
@_BackendGTK3.export
|
||||
class _BackendGTK3Cairo(_BackendGTK3):
|
||||
FigureCanvas = FigureCanvasGTK3Agg
|
||||
FigureManager = FigureManagerGTK3Agg
|
||||
46
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_gtk3cairo.py
vendored
Normal file
46
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_gtk3cairo.py
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
from . import backend_cairo, backend_gtk3
|
||||
from .backend_gtk3 import Gtk, _BackendGTK3
|
||||
from matplotlib import cbook
|
||||
from matplotlib.backend_bases import cursors
|
||||
|
||||
|
||||
class RendererGTK3Cairo(backend_cairo.RendererCairo):
|
||||
def set_context(self, ctx):
|
||||
self.gc.ctx = backend_cairo._to_context(ctx)
|
||||
|
||||
|
||||
class FigureCanvasGTK3Cairo(backend_gtk3.FigureCanvasGTK3,
|
||||
backend_cairo.FigureCanvasCairo):
|
||||
|
||||
def _renderer_init(self):
|
||||
"""Use cairo renderer."""
|
||||
self._renderer = RendererGTK3Cairo(self.figure.dpi)
|
||||
|
||||
def _render_figure(self, width, height):
|
||||
self._renderer.set_width_height(width, height)
|
||||
self.figure.draw(self._renderer)
|
||||
|
||||
def on_draw_event(self, widget, ctx):
|
||||
"""GtkDrawable draw event."""
|
||||
# toolbar = self.toolbar
|
||||
# if toolbar:
|
||||
# toolbar.set_cursor(cursors.WAIT)
|
||||
self._renderer.set_context(ctx)
|
||||
allocation = self.get_allocation()
|
||||
Gtk.render_background(
|
||||
self.get_style_context(), ctx,
|
||||
allocation.x, allocation.y, allocation.width, allocation.height)
|
||||
self._render_figure(allocation.width, allocation.height)
|
||||
# if toolbar:
|
||||
# toolbar.set_cursor(toolbar._lastCursor)
|
||||
return False # finish event propagation?
|
||||
|
||||
|
||||
@cbook.deprecated("3.1", alternative="backend_gtk3.FigureManagerGTK3")
|
||||
class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3):
|
||||
pass
|
||||
|
||||
|
||||
@_BackendGTK3.export
|
||||
class _BackendGTK3Cairo(_BackendGTK3):
|
||||
FigureCanvas = FigureCanvasGTK3Cairo
|
||||
193
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_macosx.py
vendored
Normal file
193
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_macosx.py
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
import os
|
||||
|
||||
from matplotlib._pylab_helpers import Gcf
|
||||
from matplotlib.backend_bases import (
|
||||
_Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
|
||||
TimerBase)
|
||||
|
||||
from matplotlib.figure import Figure
|
||||
from matplotlib import rcParams
|
||||
|
||||
from matplotlib.widgets import SubplotTool
|
||||
|
||||
import matplotlib
|
||||
from matplotlib.backends import _macosx
|
||||
|
||||
from .backend_agg import FigureCanvasAgg
|
||||
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# The following functions and classes are for pylab and implement
|
||||
# window/figure managers, etc...
|
||||
#
|
||||
########################################################################
|
||||
|
||||
|
||||
class TimerMac(_macosx.Timer, TimerBase):
|
||||
'''
|
||||
Subclass of :class:`backend_bases.TimerBase` that uses CoreFoundation
|
||||
run loops for timer events.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
interval : int
|
||||
The time between timer events in milliseconds. Default is 1000 ms.
|
||||
single_shot : bool
|
||||
Boolean flag indicating whether this timer should operate as single
|
||||
shot (run once and then stop). Defaults to False.
|
||||
callbacks : list
|
||||
Stores list of (func, args) tuples that will be called upon timer
|
||||
events. This list can be manipulated directly, or the functions
|
||||
`add_callback` and `remove_callback` can be used.
|
||||
|
||||
'''
|
||||
# completely implemented at the C-level (in _macosx.Timer)
|
||||
|
||||
|
||||
class FigureCanvasMac(_macosx.FigureCanvas, FigureCanvasAgg):
|
||||
"""
|
||||
The canvas the figure renders into. Calls the draw and print fig
|
||||
methods, creates the renderers, etc...
|
||||
|
||||
Events such as button presses, mouse movements, and key presses
|
||||
are handled in the C code and the base class methods
|
||||
button_press_event, button_release_event, motion_notify_event,
|
||||
key_press_event, and key_release_event are called from there.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
figure : `matplotlib.figure.Figure`
|
||||
A high-level Figure instance
|
||||
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
def _draw(self):
|
||||
renderer = self.get_renderer(cleared=self.figure.stale)
|
||||
|
||||
if self.figure.stale:
|
||||
self.figure.draw(renderer)
|
||||
|
||||
return renderer
|
||||
|
||||
def draw(self):
|
||||
# docstring inherited
|
||||
self.invalidate()
|
||||
self.flush_events()
|
||||
|
||||
def draw_idle(self, *args, **kwargs):
|
||||
# docstring inherited
|
||||
self.invalidate()
|
||||
|
||||
def blit(self, bbox=None):
|
||||
self.invalidate()
|
||||
|
||||
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,
|
||||
forward=False)
|
||||
FigureCanvasBase.resize_event(self)
|
||||
self.draw_idle()
|
||||
|
||||
def new_timer(self, *args, **kwargs):
|
||||
# docstring inherited
|
||||
return TimerMac(*args, **kwargs)
|
||||
|
||||
|
||||
class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
|
||||
"""
|
||||
Wrap everything up into a window for the pylab interface
|
||||
"""
|
||||
def __init__(self, canvas, num):
|
||||
FigureManagerBase.__init__(self, canvas, num)
|
||||
title = "Figure %d" % num
|
||||
_macosx.FigureManager.__init__(self, canvas, title)
|
||||
if rcParams['toolbar'] == 'toolbar2':
|
||||
self.toolbar = NavigationToolbar2Mac(canvas)
|
||||
else:
|
||||
self.toolbar = None
|
||||
if self.toolbar is not None:
|
||||
self.toolbar.update()
|
||||
|
||||
if matplotlib.is_interactive():
|
||||
self.show()
|
||||
self.canvas.draw_idle()
|
||||
|
||||
def close(self):
|
||||
Gcf.destroy(self.num)
|
||||
|
||||
|
||||
class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2):
|
||||
|
||||
def __init__(self, canvas):
|
||||
NavigationToolbar2.__init__(self, canvas)
|
||||
|
||||
def _init_toolbar(self):
|
||||
basedir = os.path.join(rcParams['datapath'], "images")
|
||||
_macosx.NavigationToolbar2.__init__(self, basedir)
|
||||
|
||||
def draw_rubberband(self, event, x0, y0, x1, y1):
|
||||
self.canvas.set_rubberband(int(x0), int(y0), int(x1), int(y1))
|
||||
|
||||
def release(self, event):
|
||||
self.canvas.remove_rubberband()
|
||||
|
||||
def set_cursor(self, cursor):
|
||||
_macosx.set_cursor(cursor)
|
||||
|
||||
def save_figure(self, *args):
|
||||
filename = _macosx.choose_save_file('Save the figure',
|
||||
self.canvas.get_default_filename())
|
||||
if filename is None: # Cancel
|
||||
return
|
||||
self.canvas.figure.savefig(filename)
|
||||
|
||||
def prepare_configure_subplots(self):
|
||||
toolfig = Figure(figsize=(6, 3))
|
||||
canvas = FigureCanvasMac(toolfig)
|
||||
toolfig.subplots_adjust(top=0.9)
|
||||
tool = SubplotTool(self.canvas.figure, toolfig)
|
||||
return canvas
|
||||
|
||||
def set_message(self, message):
|
||||
_macosx.NavigationToolbar2.set_message(self, message.encode('utf-8'))
|
||||
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Now just provide the standard names that backend.__init__ is expecting
|
||||
#
|
||||
########################################################################
|
||||
|
||||
@_Backend.export
|
||||
class _BackendMac(_Backend):
|
||||
required_interactive_framework = "macosx"
|
||||
FigureCanvas = FigureCanvasMac
|
||||
FigureManager = FigureManagerMac
|
||||
|
||||
@staticmethod
|
||||
def trigger_manager_draw(manager):
|
||||
# For performance reasons, we don't want to redraw the figure after
|
||||
# each draw command. Instead, we mark the figure as invalid, so that it
|
||||
# will be redrawn as soon as the event loop resumes via PyOS_InputHook.
|
||||
# This function should be called after each draw event, even if
|
||||
# matplotlib is not running interactively.
|
||||
manager.canvas.invalidate()
|
||||
|
||||
@staticmethod
|
||||
def mainloop():
|
||||
_macosx.show()
|
||||
139
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_mixed.py
vendored
Normal file
139
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_mixed.py
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
import numpy as np
|
||||
|
||||
from matplotlib.backends.backend_agg import RendererAgg
|
||||
from matplotlib.tight_bbox import process_figure_for_rasterizing
|
||||
|
||||
|
||||
class MixedModeRenderer(object):
|
||||
"""
|
||||
A helper class to implement a renderer that switches between
|
||||
vector and raster drawing. An example may be a PDF writer, where
|
||||
most things are drawn with PDF vector commands, but some very
|
||||
complex objects, such as quad meshes, are rasterised and then
|
||||
output as images.
|
||||
"""
|
||||
def __init__(self, figure, width, height, dpi, vector_renderer,
|
||||
raster_renderer_class=None,
|
||||
bbox_inches_restore=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
figure : `matplotlib.figure.Figure`
|
||||
The figure instance.
|
||||
|
||||
width : scalar
|
||||
The width of the canvas in logical units
|
||||
|
||||
height : scalar
|
||||
The height of the canvas in logical units
|
||||
|
||||
dpi : scalar
|
||||
The dpi of the canvas
|
||||
|
||||
vector_renderer : `matplotlib.backend_bases.RendererBase`
|
||||
An instance of a subclass of
|
||||
`~matplotlib.backend_bases.RendererBase` that will be used for the
|
||||
vector drawing.
|
||||
|
||||
raster_renderer_class : `matplotlib.backend_bases.RendererBase`
|
||||
The renderer class to use for the raster drawing. If not provided,
|
||||
this will use the Agg backend (which is currently the only viable
|
||||
option anyway.)
|
||||
|
||||
"""
|
||||
if raster_renderer_class is None:
|
||||
raster_renderer_class = RendererAgg
|
||||
|
||||
self._raster_renderer_class = raster_renderer_class
|
||||
self._width = width
|
||||
self._height = height
|
||||
self.dpi = dpi
|
||||
|
||||
self._vector_renderer = vector_renderer
|
||||
|
||||
self._raster_renderer = None
|
||||
self._rasterizing = 0
|
||||
|
||||
# A reference to the figure is needed as we need to change
|
||||
# the figure dpi before and after the rasterization. Although
|
||||
# this looks ugly, I couldn't find a better solution. -JJL
|
||||
self.figure = figure
|
||||
self._figdpi = figure.get_dpi()
|
||||
|
||||
self._bbox_inches_restore = bbox_inches_restore
|
||||
|
||||
self._renderer = vector_renderer
|
||||
|
||||
def __getattr__(self, attr):
|
||||
# Proxy everything that hasn't been overridden to the base
|
||||
# renderer. Things that *are* overridden can call methods
|
||||
# on self._renderer directly, but must not cache/store
|
||||
# methods (because things like RendererAgg change their
|
||||
# methods on the fly in order to optimise proxying down
|
||||
# to the underlying C implementation).
|
||||
return getattr(self._renderer, attr)
|
||||
|
||||
def start_rasterizing(self):
|
||||
"""
|
||||
Enter "raster" mode. All subsequent drawing commands (until
|
||||
stop_rasterizing is called) will be drawn with the raster
|
||||
backend.
|
||||
|
||||
If start_rasterizing is called multiple times before
|
||||
stop_rasterizing is called, this method has no effect.
|
||||
"""
|
||||
|
||||
# change the dpi of the figure temporarily.
|
||||
self.figure.set_dpi(self.dpi)
|
||||
|
||||
if self._bbox_inches_restore: # when tight bbox is used
|
||||
r = process_figure_for_rasterizing(self.figure,
|
||||
self._bbox_inches_restore)
|
||||
self._bbox_inches_restore = r
|
||||
|
||||
if self._rasterizing == 0:
|
||||
self._raster_renderer = self._raster_renderer_class(
|
||||
self._width*self.dpi, self._height*self.dpi, self.dpi)
|
||||
self._renderer = self._raster_renderer
|
||||
self._rasterizing += 1
|
||||
|
||||
def stop_rasterizing(self):
|
||||
"""
|
||||
Exit "raster" mode. All of the drawing that was done since
|
||||
the last start_rasterizing command will be copied to the
|
||||
vector backend by calling draw_image.
|
||||
|
||||
If stop_rasterizing is called multiple times before
|
||||
start_rasterizing is called, this method has no effect.
|
||||
"""
|
||||
self._rasterizing -= 1
|
||||
if self._rasterizing == 0:
|
||||
self._renderer = self._vector_renderer
|
||||
|
||||
height = self._height * self.dpi
|
||||
buffer, bounds = self._raster_renderer.tostring_rgba_minimized()
|
||||
l, b, w, h = bounds
|
||||
if w > 0 and h > 0:
|
||||
image = np.frombuffer(buffer, dtype=np.uint8)
|
||||
image = image.reshape((h, w, 4))
|
||||
image = image[::-1]
|
||||
gc = self._renderer.new_gc()
|
||||
# TODO: If the mixedmode resolution differs from the figure's
|
||||
# dpi, the image must be scaled (dpi->_figdpi). Not all
|
||||
# backends support this.
|
||||
self._renderer.draw_image(
|
||||
gc,
|
||||
l * self._figdpi / self.dpi,
|
||||
(height-b-h) * self._figdpi / self.dpi,
|
||||
image)
|
||||
self._raster_renderer = None
|
||||
self._rasterizing = False
|
||||
|
||||
# restore the figure dpi.
|
||||
self.figure.set_dpi(self._figdpi)
|
||||
|
||||
if self._bbox_inches_restore: # when tight bbox is used
|
||||
r = process_figure_for_rasterizing(self.figure,
|
||||
self._bbox_inches_restore,
|
||||
self._figdpi)
|
||||
self._bbox_inches_restore = r
|
||||
271
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py
vendored
Normal file
271
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
"""Interactive figures in the IPython notebook"""
|
||||
# Note: There is a notebook in
|
||||
# lib/matplotlib/backends/web_backend/nbagg_uat.ipynb to help verify
|
||||
# that changes made maintain expected behaviour.
|
||||
|
||||
from base64 import b64encode
|
||||
import io
|
||||
import json
|
||||
import pathlib
|
||||
import uuid
|
||||
|
||||
from IPython.display import display, Javascript, HTML
|
||||
try:
|
||||
# Jupyter/IPython 4.x or later
|
||||
from ipykernel.comm import Comm
|
||||
except ImportError:
|
||||
# Jupyter/IPython 3.x or earlier
|
||||
from IPython.kernel.comm import Comm
|
||||
|
||||
from matplotlib import cbook, is_interactive
|
||||
from matplotlib._pylab_helpers import Gcf
|
||||
from matplotlib.backend_bases import (
|
||||
_Backend, FigureCanvasBase, NavigationToolbar2)
|
||||
from matplotlib.backends.backend_webagg_core import (
|
||||
FigureCanvasWebAggCore, FigureManagerWebAgg, NavigationToolbar2WebAgg,
|
||||
TimerTornado)
|
||||
|
||||
|
||||
def connection_info():
|
||||
"""
|
||||
Return a string showing the figure and connection status for the backend.
|
||||
|
||||
This is intended as a diagnostic tool, and not for general use.
|
||||
"""
|
||||
result = [
|
||||
'{fig} - {socket}'.format(
|
||||
fig=(manager.canvas.figure.get_label()
|
||||
or "Figure {}".format(manager.num)),
|
||||
socket=manager.web_sockets)
|
||||
for manager in Gcf.get_all_fig_managers()
|
||||
]
|
||||
if not is_interactive():
|
||||
result.append('Figures pending show: {}'.format(len(Gcf._activeQue)))
|
||||
return '\n'.join(result)
|
||||
|
||||
|
||||
# Note: Version 3.2 and 4.x icons
|
||||
# http://fontawesome.io/3.2.1/icons/
|
||||
# http://fontawesome.io/
|
||||
# the `fa fa-xxx` part targets font-awesome 4, (IPython 3.x)
|
||||
# the icon-xxx targets font awesome 3.21 (IPython 2.x)
|
||||
_FONT_AWESOME_CLASSES = {
|
||||
'home': 'fa fa-home icon-home',
|
||||
'back': 'fa fa-arrow-left icon-arrow-left',
|
||||
'forward': 'fa fa-arrow-right icon-arrow-right',
|
||||
'zoom_to_rect': 'fa fa-square-o icon-check-empty',
|
||||
'move': 'fa fa-arrows icon-move',
|
||||
'download': 'fa fa-floppy-o icon-save',
|
||||
None: None
|
||||
}
|
||||
|
||||
|
||||
class NavigationIPy(NavigationToolbar2WebAgg):
|
||||
|
||||
# Use the standard toolbar items + download button
|
||||
toolitems = [(text, tooltip_text,
|
||||
_FONT_AWESOME_CLASSES[image_file], name_of_method)
|
||||
for text, tooltip_text, image_file, name_of_method
|
||||
in (NavigationToolbar2.toolitems +
|
||||
(('Download', 'Download plot', 'download', 'download'),))
|
||||
if image_file in _FONT_AWESOME_CLASSES]
|
||||
|
||||
|
||||
class FigureManagerNbAgg(FigureManagerWebAgg):
|
||||
ToolbarCls = NavigationIPy
|
||||
|
||||
def __init__(self, canvas, num):
|
||||
self._shown = False
|
||||
FigureManagerWebAgg.__init__(self, canvas, num)
|
||||
|
||||
def display_js(self):
|
||||
# XXX How to do this just once? It has to deal with multiple
|
||||
# browser instances using the same kernel (require.js - but the
|
||||
# file isn't static?).
|
||||
display(Javascript(FigureManagerNbAgg.get_javascript()))
|
||||
|
||||
def show(self):
|
||||
if not self._shown:
|
||||
self.display_js()
|
||||
self._create_comm()
|
||||
else:
|
||||
self.canvas.draw_idle()
|
||||
self._shown = True
|
||||
|
||||
def reshow(self):
|
||||
"""
|
||||
A special method to re-show the figure in the notebook.
|
||||
|
||||
"""
|
||||
self._shown = False
|
||||
self.show()
|
||||
|
||||
@property
|
||||
def connected(self):
|
||||
return bool(self.web_sockets)
|
||||
|
||||
@classmethod
|
||||
def get_javascript(cls, stream=None):
|
||||
if stream is None:
|
||||
output = io.StringIO()
|
||||
else:
|
||||
output = stream
|
||||
super().get_javascript(stream=output)
|
||||
output.write((pathlib.Path(__file__).parent
|
||||
/ "web_backend/js/nbagg_mpl.js")
|
||||
.read_text(encoding="utf-8"))
|
||||
if stream is None:
|
||||
return output.getvalue()
|
||||
|
||||
def _create_comm(self):
|
||||
comm = CommSocket(self)
|
||||
self.add_web_socket(comm)
|
||||
return comm
|
||||
|
||||
def destroy(self):
|
||||
self._send_event('close')
|
||||
# need to copy comms as callbacks will modify this list
|
||||
for comm in list(self.web_sockets):
|
||||
comm.on_close()
|
||||
self.clearup_closed()
|
||||
|
||||
def clearup_closed(self):
|
||||
"""Clear up any closed Comms."""
|
||||
self.web_sockets = {socket for socket in self.web_sockets
|
||||
if socket.is_open()}
|
||||
|
||||
if len(self.web_sockets) == 0:
|
||||
self.canvas.close_event()
|
||||
|
||||
def remove_comm(self, comm_id):
|
||||
self.web_sockets = {socket for socket in self.web_sockets
|
||||
if not socket.comm.comm_id == comm_id}
|
||||
|
||||
|
||||
class FigureCanvasNbAgg(FigureCanvasWebAggCore):
|
||||
def new_timer(self, *args, **kwargs):
|
||||
# docstring inherited
|
||||
return TimerTornado(*args, **kwargs)
|
||||
|
||||
|
||||
class CommSocket(object):
|
||||
"""
|
||||
Manages the Comm connection between IPython and the browser (client).
|
||||
|
||||
Comms are 2 way, with the CommSocket being able to publish a message
|
||||
via the send_json method, and handle a message with on_message. On the
|
||||
JS side figure.send_message and figure.ws.onmessage do the sending and
|
||||
receiving respectively.
|
||||
|
||||
"""
|
||||
def __init__(self, manager):
|
||||
self.supports_binary = None
|
||||
self.manager = manager
|
||||
self.uuid = str(uuid.uuid4())
|
||||
# Publish an output area with a unique ID. The javascript can then
|
||||
# hook into this area.
|
||||
display(HTML("<div id=%r></div>" % self.uuid))
|
||||
try:
|
||||
self.comm = Comm('matplotlib', data={'id': self.uuid})
|
||||
except AttributeError:
|
||||
raise RuntimeError('Unable to create an IPython notebook Comm '
|
||||
'instance. Are you in the IPython notebook?')
|
||||
self.comm.on_msg(self.on_message)
|
||||
|
||||
manager = self.manager
|
||||
self._ext_close = False
|
||||
|
||||
def _on_close(close_message):
|
||||
self._ext_close = True
|
||||
manager.remove_comm(close_message['content']['comm_id'])
|
||||
manager.clearup_closed()
|
||||
|
||||
self.comm.on_close(_on_close)
|
||||
|
||||
def is_open(self):
|
||||
return not (self._ext_close or self.comm._closed)
|
||||
|
||||
def on_close(self):
|
||||
# When the socket is closed, deregister the websocket with
|
||||
# the FigureManager.
|
||||
if self.is_open():
|
||||
try:
|
||||
self.comm.close()
|
||||
except KeyError:
|
||||
# apparently already cleaned it up?
|
||||
pass
|
||||
|
||||
def send_json(self, content):
|
||||
self.comm.send({'data': json.dumps(content)})
|
||||
|
||||
def send_binary(self, blob):
|
||||
# The comm is ascii, so we always send the image in base64
|
||||
# encoded data URL form.
|
||||
data = b64encode(blob).decode('ascii')
|
||||
data_uri = "data:image/png;base64,{0}".format(data)
|
||||
self.comm.send({'data': data_uri})
|
||||
|
||||
def on_message(self, message):
|
||||
# The 'supports_binary' message is relevant to the
|
||||
# websocket itself. The other messages get passed along
|
||||
# to matplotlib as-is.
|
||||
|
||||
# Every message has a "type" and a "figure_id".
|
||||
message = json.loads(message['content']['data'])
|
||||
if message['type'] == 'closing':
|
||||
self.on_close()
|
||||
self.manager.clearup_closed()
|
||||
elif message['type'] == 'supports_binary':
|
||||
self.supports_binary = message['value']
|
||||
else:
|
||||
self.manager.handle_json(message)
|
||||
|
||||
|
||||
@_Backend.export
|
||||
class _BackendNbAgg(_Backend):
|
||||
FigureCanvas = FigureCanvasNbAgg
|
||||
FigureManager = FigureManagerNbAgg
|
||||
|
||||
@staticmethod
|
||||
def new_figure_manager_given_figure(num, figure):
|
||||
canvas = FigureCanvasNbAgg(figure)
|
||||
manager = FigureManagerNbAgg(canvas, num)
|
||||
if is_interactive():
|
||||
manager.show()
|
||||
figure.canvas.draw_idle()
|
||||
canvas.mpl_connect('close_event', lambda event: Gcf.destroy(num))
|
||||
return manager
|
||||
|
||||
@staticmethod
|
||||
def trigger_manager_draw(manager):
|
||||
manager.show()
|
||||
|
||||
@staticmethod
|
||||
def show(*args, block=None, **kwargs):
|
||||
if args or kwargs:
|
||||
cbook.warn_deprecated(
|
||||
"3.1", message="Passing arguments to show(), other than "
|
||||
"passing 'block' by keyword, is deprecated %(since)s, and "
|
||||
"support for it will be removed %(removal)s.")
|
||||
|
||||
## TODO: something to do when keyword block==False ?
|
||||
from matplotlib._pylab_helpers import Gcf
|
||||
|
||||
managers = Gcf.get_all_fig_managers()
|
||||
if not managers:
|
||||
return
|
||||
|
||||
interactive = is_interactive()
|
||||
|
||||
for manager in managers:
|
||||
manager.show()
|
||||
|
||||
# plt.figure adds an event which puts the figure in focus
|
||||
# in the activeQue. Disable this behaviour, as it results in
|
||||
# figures being put as the active figure after they have been
|
||||
# shown, even in non-interactive mode.
|
||||
if hasattr(manager, '_cidgcf'):
|
||||
manager.canvas.mpl_disconnect(manager._cidgcf)
|
||||
|
||||
if not interactive and manager in Gcf._activeQue:
|
||||
Gcf._activeQue.remove(manager)
|
||||
2519
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_pdf.py
vendored
Normal file
2519
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_pdf.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1148
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_pgf.py
vendored
Normal file
1148
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_pgf.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1605
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_ps.py
vendored
Normal file
1605
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_ps.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt4.py
vendored
Normal file
10
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt4.py
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
from .backend_qt5 import (
|
||||
backend_version, SPECIAL_KEYS, SUPER, ALT, CTRL, SHIFT, MODIFIER_KEYS,
|
||||
cursord, _create_qApp, _BackendQT5, TimerQT, MainWindow, FigureManagerQT,
|
||||
NavigationToolbar2QT, SubplotToolQt, error_msg_qt, exception_handler)
|
||||
from .backend_qt5 import FigureCanvasQT as FigureCanvasQT5
|
||||
|
||||
|
||||
@_BackendQT5.export
|
||||
class _BackendQT4(_BackendQT5):
|
||||
required_interactive_framework = "qt4"
|
||||
11
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt4agg.py
vendored
Normal file
11
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt4agg.py
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
"""
|
||||
Render to qt from agg
|
||||
"""
|
||||
|
||||
from .backend_qt5agg import (
|
||||
_BackendQT5Agg, FigureCanvasQTAgg, FigureManagerQT, NavigationToolbar2QT)
|
||||
|
||||
|
||||
@_BackendQT5Agg.export
|
||||
class _BackendQT4Agg(_BackendQT5Agg):
|
||||
required_interactive_framework = "qt4"
|
||||
6
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt4cairo.py
vendored
Normal file
6
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt4cairo.py
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
from .backend_qt5cairo import _BackendQT5Cairo
|
||||
|
||||
|
||||
@_BackendQT5Cairo.export
|
||||
class _BackendQT4Cairo(_BackendQT5Cairo):
|
||||
required_interactive_framework = "qt4"
|
||||
1103
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt5.py
vendored
Normal file
1103
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt5.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
100
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt5agg.py
vendored
Normal file
100
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt5agg.py
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
"""
|
||||
Render to qt from agg.
|
||||
"""
|
||||
|
||||
import ctypes
|
||||
|
||||
from matplotlib.transforms import Bbox
|
||||
|
||||
from .. import cbook
|
||||
from .backend_agg import FigureCanvasAgg
|
||||
from .backend_qt5 import (
|
||||
QtCore, QtGui, QtWidgets, _BackendQT5, FigureCanvasQT, FigureManagerQT,
|
||||
NavigationToolbar2QT, backend_version)
|
||||
from .qt_compat import QT_API
|
||||
|
||||
|
||||
class FigureCanvasQTAgg(FigureCanvasAgg, FigureCanvasQT):
|
||||
|
||||
def __init__(self, figure):
|
||||
# Must pass 'figure' as kwarg to Qt base class.
|
||||
super().__init__(figure=figure)
|
||||
|
||||
def paintEvent(self, event):
|
||||
"""Copy the image from the Agg canvas to the qt.drawable.
|
||||
|
||||
In Qt, all drawing should be done inside of here when a widget is
|
||||
shown onscreen.
|
||||
"""
|
||||
if self._update_dpi():
|
||||
# The dpi update triggered its own paintEvent.
|
||||
return
|
||||
self._draw_idle() # Only does something if a draw is pending.
|
||||
|
||||
# If the canvas does not have a renderer, then give up and wait for
|
||||
# FigureCanvasAgg.draw(self) to be called.
|
||||
if not hasattr(self, 'renderer'):
|
||||
return
|
||||
|
||||
painter = QtGui.QPainter(self)
|
||||
|
||||
# See documentation of QRect: bottom() and right() are off by 1, so use
|
||||
# left() + width() and top() + height().
|
||||
rect = event.rect()
|
||||
# scale rect dimensions using the screen dpi ratio to get
|
||||
# correct values for the Figure coordinates (rather than QT5's coords)
|
||||
width = rect.width() * self._dpi_ratio
|
||||
height = rect.height() * self._dpi_ratio
|
||||
left, top = self.mouseEventCoords(rect.topLeft())
|
||||
# shift the "top" by the height of the image to get the
|
||||
# correct corner for our coordinate system
|
||||
bottom = top - height
|
||||
# same with the right side of the image
|
||||
right = left + width
|
||||
# create a buffer using the image bounding box
|
||||
bbox = Bbox([[left, bottom], [right, top]])
|
||||
reg = self.copy_from_bbox(bbox)
|
||||
buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
|
||||
memoryview(reg))
|
||||
|
||||
# clear the widget canvas
|
||||
painter.eraseRect(rect)
|
||||
|
||||
qimage = QtGui.QImage(buf, buf.shape[1], buf.shape[0],
|
||||
QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||
if hasattr(qimage, 'setDevicePixelRatio'):
|
||||
# Not available on Qt4 or some older Qt5.
|
||||
qimage.setDevicePixelRatio(self._dpi_ratio)
|
||||
# set origin using original QT coordinates
|
||||
origin = QtCore.QPoint(rect.left(), rect.top())
|
||||
painter.drawImage(origin, qimage)
|
||||
# Adjust the buf reference count to work around a memory
|
||||
# leak bug in QImage under PySide on Python 3.
|
||||
if QT_API in ('PySide', 'PySide2'):
|
||||
ctypes.c_long.from_address(id(buf)).value = 1
|
||||
|
||||
self._draw_rect_callback(painter)
|
||||
|
||||
painter.end()
|
||||
|
||||
def blit(self, bbox=None):
|
||||
"""Blit the region in bbox.
|
||||
"""
|
||||
# If bbox is None, blit the entire canvas. Otherwise
|
||||
# blit only the area defined by the bbox.
|
||||
if bbox is None and self.figure:
|
||||
bbox = self.figure.bbox
|
||||
|
||||
# repaint uses logical pixels, not physical pixels like the renderer.
|
||||
l, b, w, h = [pt / self._dpi_ratio for pt in bbox.bounds]
|
||||
t = b + h
|
||||
self.repaint(l, self.renderer.height / self._dpi_ratio - t, w, h)
|
||||
|
||||
def print_figure(self, *args, **kwargs):
|
||||
super().print_figure(*args, **kwargs)
|
||||
self.draw()
|
||||
|
||||
|
||||
@_BackendQT5.export
|
||||
class _BackendQT5Agg(_BackendQT5):
|
||||
FigureCanvas = FigureCanvasQTAgg
|
||||
48
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt5cairo.py
vendored
Normal file
48
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_qt5cairo.py
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import ctypes
|
||||
|
||||
from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo
|
||||
from .backend_qt5 import QtCore, QtGui, _BackendQT5, FigureCanvasQT
|
||||
from .qt_compat import QT_API
|
||||
|
||||
|
||||
class FigureCanvasQTCairo(FigureCanvasQT, FigureCanvasCairo):
|
||||
def __init__(self, figure):
|
||||
super().__init__(figure=figure)
|
||||
self._renderer = RendererCairo(self.figure.dpi)
|
||||
self._renderer.set_width_height(-1, -1) # Invalid values.
|
||||
|
||||
def draw(self):
|
||||
if hasattr(self._renderer.gc, "ctx"):
|
||||
self.figure.draw(self._renderer)
|
||||
super().draw()
|
||||
|
||||
def paintEvent(self, event):
|
||||
self._update_dpi()
|
||||
dpi_ratio = self._dpi_ratio
|
||||
width = dpi_ratio * self.width()
|
||||
height = dpi_ratio * self.height()
|
||||
if (width, height) != self._renderer.get_canvas_width_height():
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
||||
self._renderer.set_ctx_from_surface(surface)
|
||||
self._renderer.set_width_height(width, height)
|
||||
self.figure.draw(self._renderer)
|
||||
buf = self._renderer.gc.ctx.get_target().get_data()
|
||||
qimage = QtGui.QImage(buf, width, height,
|
||||
QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||
# Adjust the buf reference count to work around a memory leak bug in
|
||||
# QImage under PySide on Python 3.
|
||||
if QT_API == 'PySide':
|
||||
ctypes.c_long.from_address(id(buf)).value = 1
|
||||
if hasattr(qimage, 'setDevicePixelRatio'):
|
||||
# Not available on Qt4 or some older Qt5.
|
||||
qimage.setDevicePixelRatio(dpi_ratio)
|
||||
painter = QtGui.QPainter(self)
|
||||
painter.eraseRect(event.rect())
|
||||
painter.drawImage(0, 0, qimage)
|
||||
self._draw_rect_callback(painter)
|
||||
painter.end()
|
||||
|
||||
|
||||
@_BackendQT5.export
|
||||
class _BackendQT5Cairo(_BackendQT5):
|
||||
FigureCanvas = FigureCanvasQTCairo
|
||||
1247
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_svg.py
vendored
Normal file
1247
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_svg.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
269
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_template.py
vendored
Normal file
269
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_template.py
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
"""
|
||||
This is a fully functional do nothing backend to provide a template to
|
||||
backend writers. It is fully functional in that you can select it as
|
||||
a backend with
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('Template')
|
||||
|
||||
and your matplotlib scripts will (should!) run without error, though
|
||||
no output is produced. This provides a nice starting point for
|
||||
backend writers because you can selectively implement methods
|
||||
(draw_rectangle, draw_lines, etc...) and slowly see your figure come
|
||||
to life w/o having to have a full blown implementation before getting
|
||||
any results.
|
||||
|
||||
Copy this to backend_xxx.py and replace all instances of 'template'
|
||||
with 'xxx'. Then implement the class methods and functions below, and
|
||||
add 'xxx' to the switchyard in matplotlib/backends/__init__.py and
|
||||
'xxx' to the backends list in the validate_backend method in
|
||||
matplotlib/__init__.py and you're off. You can use your backend with::
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('xxx')
|
||||
import matplotlib.pyplot as plt
|
||||
plt.plot([1,2,3])
|
||||
plt.show()
|
||||
|
||||
matplotlib also supports external backends, so you can place you can
|
||||
use any module in your PYTHONPATH with the syntax::
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('module://my_backend')
|
||||
|
||||
where my_backend.py is your module name. This syntax is also
|
||||
recognized in the rc file and in the -d argument in pylab, e.g.,::
|
||||
|
||||
python simple_plot.py -dmodule://my_backend
|
||||
|
||||
If your backend implements support for saving figures (i.e. has a print_xyz()
|
||||
method) you can register it as the default handler for a given file type
|
||||
|
||||
from matplotlib.backend_bases import register_backend
|
||||
register_backend('xyz', 'my_backend', 'XYZ File Format')
|
||||
...
|
||||
plt.savefig("figure.xyz")
|
||||
|
||||
The files that are most relevant to backend_writers are
|
||||
|
||||
matplotlib/backends/backend_your_backend.py
|
||||
matplotlib/backend_bases.py
|
||||
matplotlib/backends/__init__.py
|
||||
matplotlib/__init__.py
|
||||
matplotlib/_pylab_helpers.py
|
||||
|
||||
Naming Conventions
|
||||
|
||||
* classes Upper or MixedUpperCase
|
||||
|
||||
* variables lower or lowerUpper
|
||||
|
||||
* functions lower or underscore_separated
|
||||
|
||||
"""
|
||||
|
||||
from matplotlib._pylab_helpers import Gcf
|
||||
from matplotlib.backend_bases import (
|
||||
FigureCanvasBase, FigureManagerBase, GraphicsContextBase, RendererBase)
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
|
||||
class RendererTemplate(RendererBase):
|
||||
"""
|
||||
The renderer handles drawing/rendering operations.
|
||||
|
||||
This is a minimal do-nothing class that can be used to get started when
|
||||
writing a new backend. Refer to backend_bases.RendererBase for
|
||||
documentation of the classes methods.
|
||||
"""
|
||||
def __init__(self, dpi):
|
||||
self.dpi = dpi
|
||||
|
||||
def draw_path(self, gc, path, transform, rgbFace=None):
|
||||
pass
|
||||
|
||||
# draw_markers is optional, and we get more correct relative
|
||||
# timings by leaving it out. backend implementers concerned with
|
||||
# performance will probably want to implement it
|
||||
# def draw_markers(self, gc, marker_path, marker_trans, path, trans,
|
||||
# rgbFace=None):
|
||||
# pass
|
||||
|
||||
# draw_path_collection is optional, and we get more correct
|
||||
# relative timings by leaving it out. backend implementers concerned with
|
||||
# performance will probably want to implement it
|
||||
# def draw_path_collection(self, gc, master_transform, paths,
|
||||
# all_transforms, offsets, offsetTrans,
|
||||
# facecolors, edgecolors, linewidths, linestyles,
|
||||
# antialiaseds):
|
||||
# pass
|
||||
|
||||
# draw_quad_mesh is optional, and we get more correct
|
||||
# relative timings by leaving it out. backend implementers concerned with
|
||||
# performance will probably want to implement it
|
||||
# def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
|
||||
# coordinates, offsets, offsetTrans, facecolors,
|
||||
# antialiased, edgecolors):
|
||||
# pass
|
||||
|
||||
def draw_image(self, gc, x, y, im):
|
||||
pass
|
||||
|
||||
def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
|
||||
pass
|
||||
|
||||
def flipy(self):
|
||||
# docstring inherited
|
||||
return True
|
||||
|
||||
def get_canvas_width_height(self):
|
||||
# docstring inherited
|
||||
return 100, 100
|
||||
|
||||
def get_text_width_height_descent(self, s, prop, ismath):
|
||||
return 1, 1, 1
|
||||
|
||||
def new_gc(self):
|
||||
# docstring inherited
|
||||
return GraphicsContextTemplate()
|
||||
|
||||
def points_to_pixels(self, points):
|
||||
# if backend doesn't have dpi, e.g., postscript or svg
|
||||
return points
|
||||
# elif backend assumes a value for pixels_per_inch
|
||||
#return points/72.0 * self.dpi.get() * pixels_per_inch/72.0
|
||||
# else
|
||||
#return points/72.0 * self.dpi.get()
|
||||
|
||||
|
||||
class GraphicsContextTemplate(GraphicsContextBase):
|
||||
"""
|
||||
The graphics context provides the color, line styles, etc... See the cairo
|
||||
and postscript backends for examples of mapping the graphics context
|
||||
attributes (cap styles, join styles, line widths, colors) to a particular
|
||||
backend. In cairo this is done by wrapping a cairo.Context object and
|
||||
forwarding the appropriate calls to it using a dictionary mapping styles
|
||||
to gdk constants. In Postscript, all the work is done by the renderer,
|
||||
mapping line styles to postscript calls.
|
||||
|
||||
If it's more appropriate to do the mapping at the renderer level (as in
|
||||
the postscript backend), you don't need to override any of the GC methods.
|
||||
If it's more appropriate to wrap an instance (as in the cairo backend) and
|
||||
do the mapping here, you'll need to override several of the setter
|
||||
methods.
|
||||
|
||||
The base GraphicsContext stores colors as a RGB tuple on the unit
|
||||
interval, e.g., (0.5, 0.0, 1.0). You may need to map this to colors
|
||||
appropriate for your backend.
|
||||
"""
|
||||
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# The following functions and classes are for pylab and implement
|
||||
# window/figure managers, etc...
|
||||
#
|
||||
########################################################################
|
||||
|
||||
def draw_if_interactive():
|
||||
"""
|
||||
For image backends - is not required.
|
||||
For GUI backends - this should be overridden if drawing should be done in
|
||||
interactive python mode.
|
||||
"""
|
||||
|
||||
|
||||
def show(*, block=None):
|
||||
"""
|
||||
For image backends - is not required.
|
||||
For GUI backends - show() is usually the last line of a pyplot script and
|
||||
tells the backend that it is time to draw. In interactive mode, this
|
||||
should do nothing.
|
||||
"""
|
||||
for manager in Gcf.get_all_fig_managers():
|
||||
# do something to display the GUI
|
||||
pass
|
||||
|
||||
|
||||
def new_figure_manager(num, *args, FigureClass=Figure, **kwargs):
|
||||
"""
|
||||
Create a new figure manager instance
|
||||
"""
|
||||
# If a main-level app must be created, this (and
|
||||
# new_figure_manager_given_figure) is the usual place to do it -- see
|
||||
# backend_wx, backend_wxagg and backend_tkagg for examples. Not all GUIs
|
||||
# require explicit instantiation of a main-level app (e.g., backend_gtk3)
|
||||
# for pylab.
|
||||
thisFig = FigureClass(*args, **kwargs)
|
||||
return new_figure_manager_given_figure(num, thisFig)
|
||||
|
||||
|
||||
def new_figure_manager_given_figure(num, figure):
|
||||
"""
|
||||
Create a new figure manager instance for the given figure.
|
||||
"""
|
||||
canvas = FigureCanvasTemplate(figure)
|
||||
manager = FigureManagerTemplate(canvas, num)
|
||||
return manager
|
||||
|
||||
|
||||
class FigureCanvasTemplate(FigureCanvasBase):
|
||||
"""
|
||||
The canvas the figure renders into. Calls the draw and print fig
|
||||
methods, creates the renderers, etc.
|
||||
|
||||
Note: GUI templates will want to connect events for button presses,
|
||||
mouse movements and key presses to functions that call the base
|
||||
class methods button_press_event, button_release_event,
|
||||
motion_notify_event, key_press_event, and key_release_event. See the
|
||||
implementations of the interactive backends for examples.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
figure : `matplotlib.figure.Figure`
|
||||
A high-level Figure instance
|
||||
"""
|
||||
|
||||
def draw(self):
|
||||
"""
|
||||
Draw the figure using the renderer
|
||||
"""
|
||||
renderer = RendererTemplate(self.figure.dpi)
|
||||
self.figure.draw(renderer)
|
||||
|
||||
# You should provide a print_xxx function for every file format
|
||||
# you can write.
|
||||
|
||||
# If the file type is not in the base set of filetypes,
|
||||
# you should add it to the class-scope filetypes dictionary as follows:
|
||||
filetypes = FigureCanvasBase.filetypes.copy()
|
||||
filetypes['foo'] = 'My magic Foo format'
|
||||
|
||||
def print_foo(self, filename, *args, **kwargs):
|
||||
"""
|
||||
Write out format foo. The dpi, facecolor and edgecolor are restored
|
||||
to their original values after this call, so you don't need to
|
||||
save and restore them.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_default_filetype(self):
|
||||
return 'foo'
|
||||
|
||||
|
||||
class FigureManagerTemplate(FigureManagerBase):
|
||||
"""
|
||||
Wrap everything up into a window for the pylab interface
|
||||
|
||||
For non interactive backends, the base class does all the work
|
||||
"""
|
||||
pass
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Now just provide the standard names that backend.__init__ is expecting
|
||||
#
|
||||
########################################################################
|
||||
|
||||
FigureCanvas = FigureCanvasTemplate
|
||||
FigureManager = FigureManagerTemplate
|
||||
21
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_tkagg.py
vendored
Normal file
21
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_tkagg.py
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
from . import _backend_tk
|
||||
from .backend_agg import FigureCanvasAgg
|
||||
from ._backend_tk import (
|
||||
_BackendTk, FigureCanvasTk, FigureManagerTk, NavigationToolbar2Tk)
|
||||
|
||||
|
||||
class FigureCanvasTkAgg(FigureCanvasAgg, FigureCanvasTk):
|
||||
def draw(self):
|
||||
super(FigureCanvasTkAgg, self).draw()
|
||||
_backend_tk.blit(self._tkphoto, self.renderer._renderer, (0, 1, 2, 3))
|
||||
self._master.update_idletasks()
|
||||
|
||||
def blit(self, bbox=None):
|
||||
_backend_tk.blit(
|
||||
self._tkphoto, self.renderer._renderer, (0, 1, 2, 3), bbox=bbox)
|
||||
self._master.update_idletasks()
|
||||
|
||||
|
||||
@_BackendTk.export
|
||||
class _BackendTkAgg(_BackendTk):
|
||||
FigureCanvas = FigureCanvasTkAgg
|
||||
31
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_tkcairo.py
vendored
Normal file
31
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_tkcairo.py
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
from . import _backend_tk
|
||||
from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo
|
||||
from ._backend_tk import _BackendTk, FigureCanvasTk
|
||||
|
||||
|
||||
class FigureCanvasTkCairo(FigureCanvasCairo, FigureCanvasTk):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FigureCanvasTkCairo, self).__init__(*args, **kwargs)
|
||||
self._renderer = RendererCairo(self.figure.dpi)
|
||||
|
||||
def draw(self):
|
||||
width = int(self.figure.bbox.width)
|
||||
height = int(self.figure.bbox.height)
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
||||
self._renderer.set_ctx_from_surface(surface)
|
||||
self._renderer.set_width_height(width, height)
|
||||
self.figure.draw(self._renderer)
|
||||
buf = np.reshape(surface.get_data(), (height, width, 4))
|
||||
_backend_tk.blit(
|
||||
self._tkphoto, buf,
|
||||
(2, 1, 0, 3) if sys.byteorder == "little" else (1, 2, 3, 0))
|
||||
self._master.update_idletasks()
|
||||
|
||||
|
||||
@_BackendTk.export
|
||||
class _BackendTkCairo(_BackendTk):
|
||||
FigureCanvas = FigureCanvasTkCairo
|
||||
336
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_webagg.py
vendored
Normal file
336
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_webagg.py
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
"""
|
||||
Displays Agg images in the browser, with interactivity
|
||||
"""
|
||||
|
||||
# The WebAgg backend is divided into two modules:
|
||||
#
|
||||
# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
|
||||
# plot inside of a web application, and communicate in an abstract
|
||||
# way over a web socket.
|
||||
#
|
||||
# - `backend_webagg.py` contains a concrete implementation of a basic
|
||||
# application, implemented with tornado.
|
||||
|
||||
from contextlib import contextmanager
|
||||
import errno
|
||||
from io import BytesIO
|
||||
import json
|
||||
from pathlib import Path
|
||||
import random
|
||||
import sys
|
||||
import signal
|
||||
import socket
|
||||
import threading
|
||||
|
||||
try:
|
||||
import tornado
|
||||
except ImportError:
|
||||
raise RuntimeError("The WebAgg backend requires Tornado.")
|
||||
|
||||
import tornado.web
|
||||
import tornado.ioloop
|
||||
import tornado.websocket
|
||||
|
||||
from matplotlib import rcParams
|
||||
from matplotlib.backend_bases import _Backend
|
||||
from matplotlib._pylab_helpers import Gcf
|
||||
from . import backend_webagg_core as core
|
||||
from .backend_webagg_core import TimerTornado
|
||||
|
||||
|
||||
class ServerThread(threading.Thread):
|
||||
def run(self):
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
|
||||
|
||||
webagg_server_thread = ServerThread()
|
||||
|
||||
|
||||
class FigureCanvasWebAgg(core.FigureCanvasWebAggCore):
|
||||
def show(self):
|
||||
# show the figure window
|
||||
global show # placates pyflakes: created by @_Backend.export below
|
||||
show()
|
||||
|
||||
def new_timer(self, *args, **kwargs):
|
||||
# docstring inherited
|
||||
return TimerTornado(*args, **kwargs)
|
||||
|
||||
|
||||
class WebAggApplication(tornado.web.Application):
|
||||
initialized = False
|
||||
started = False
|
||||
|
||||
class FavIcon(tornado.web.RequestHandler):
|
||||
def get(self):
|
||||
self.set_header('Content-Type', 'image/png')
|
||||
image_path = Path(rcParams["datapath"], "images", "matplotlib.png")
|
||||
self.write(image_path.read_bytes())
|
||||
|
||||
class SingleFigurePage(tornado.web.RequestHandler):
|
||||
def __init__(self, application, request, *, url_prefix='', **kwargs):
|
||||
self.url_prefix = url_prefix
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def get(self, fignum):
|
||||
fignum = int(fignum)
|
||||
manager = Gcf.get_fig_manager(fignum)
|
||||
|
||||
ws_uri = 'ws://{req.host}{prefix}/'.format(req=self.request,
|
||||
prefix=self.url_prefix)
|
||||
self.render(
|
||||
"single_figure.html",
|
||||
prefix=self.url_prefix,
|
||||
ws_uri=ws_uri,
|
||||
fig_id=fignum,
|
||||
toolitems=core.NavigationToolbar2WebAgg.toolitems,
|
||||
canvas=manager.canvas)
|
||||
|
||||
class AllFiguresPage(tornado.web.RequestHandler):
|
||||
def __init__(self, application, request, *, url_prefix='', **kwargs):
|
||||
self.url_prefix = url_prefix
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def get(self):
|
||||
ws_uri = 'ws://{req.host}{prefix}/'.format(req=self.request,
|
||||
prefix=self.url_prefix)
|
||||
self.render(
|
||||
"all_figures.html",
|
||||
prefix=self.url_prefix,
|
||||
ws_uri=ws_uri,
|
||||
figures=sorted(Gcf.figs.items()),
|
||||
toolitems=core.NavigationToolbar2WebAgg.toolitems)
|
||||
|
||||
class MplJs(tornado.web.RequestHandler):
|
||||
def get(self):
|
||||
self.set_header('Content-Type', 'application/javascript')
|
||||
|
||||
js_content = core.FigureManagerWebAgg.get_javascript()
|
||||
|
||||
self.write(js_content)
|
||||
|
||||
class Download(tornado.web.RequestHandler):
|
||||
def get(self, fignum, fmt):
|
||||
fignum = int(fignum)
|
||||
manager = Gcf.get_fig_manager(fignum)
|
||||
|
||||
# TODO: Move this to a central location
|
||||
mimetypes = {
|
||||
'ps': 'application/postscript',
|
||||
'eps': 'application/postscript',
|
||||
'pdf': 'application/pdf',
|
||||
'svg': 'image/svg+xml',
|
||||
'png': 'image/png',
|
||||
'jpeg': 'image/jpeg',
|
||||
'tif': 'image/tiff',
|
||||
'emf': 'application/emf'
|
||||
}
|
||||
|
||||
self.set_header('Content-Type', mimetypes.get(fmt, 'binary'))
|
||||
|
||||
buff = BytesIO()
|
||||
manager.canvas.figure.savefig(buff, format=fmt)
|
||||
self.write(buff.getvalue())
|
||||
|
||||
class WebSocket(tornado.websocket.WebSocketHandler):
|
||||
supports_binary = True
|
||||
|
||||
def open(self, fignum):
|
||||
self.fignum = int(fignum)
|
||||
self.manager = Gcf.get_fig_manager(self.fignum)
|
||||
self.manager.add_web_socket(self)
|
||||
if hasattr(self, 'set_nodelay'):
|
||||
self.set_nodelay(True)
|
||||
|
||||
def on_close(self):
|
||||
self.manager.remove_web_socket(self)
|
||||
|
||||
def on_message(self, message):
|
||||
message = json.loads(message)
|
||||
# The 'supports_binary' message is on a client-by-client
|
||||
# basis. The others affect the (shared) canvas as a
|
||||
# whole.
|
||||
if message['type'] == 'supports_binary':
|
||||
self.supports_binary = message['value']
|
||||
else:
|
||||
manager = Gcf.get_fig_manager(self.fignum)
|
||||
# It is possible for a figure to be closed,
|
||||
# but a stale figure UI is still sending messages
|
||||
# from the browser.
|
||||
if manager is not None:
|
||||
manager.handle_json(message)
|
||||
|
||||
def send_json(self, content):
|
||||
self.write_message(json.dumps(content))
|
||||
|
||||
def send_binary(self, blob):
|
||||
if self.supports_binary:
|
||||
self.write_message(blob, binary=True)
|
||||
else:
|
||||
data_uri = "data:image/png;base64,{0}".format(
|
||||
blob.encode('base64').replace('\n', ''))
|
||||
self.write_message(data_uri)
|
||||
|
||||
def __init__(self, url_prefix=''):
|
||||
if url_prefix:
|
||||
assert url_prefix[0] == '/' and url_prefix[-1] != '/', \
|
||||
'url_prefix must start with a "/" and not end with one.'
|
||||
|
||||
super().__init__(
|
||||
[
|
||||
# Static files for the CSS and JS
|
||||
(url_prefix + r'/_static/(.*)',
|
||||
tornado.web.StaticFileHandler,
|
||||
{'path': core.FigureManagerWebAgg.get_static_file_path()}),
|
||||
|
||||
# An MPL favicon
|
||||
(url_prefix + r'/favicon.ico', self.FavIcon),
|
||||
|
||||
# The page that contains all of the pieces
|
||||
(url_prefix + r'/([0-9]+)', self.SingleFigurePage,
|
||||
{'url_prefix': url_prefix}),
|
||||
|
||||
# The page that contains all of the figures
|
||||
(url_prefix + r'/?', self.AllFiguresPage,
|
||||
{'url_prefix': url_prefix}),
|
||||
|
||||
(url_prefix + r'/js/mpl.js', self.MplJs),
|
||||
|
||||
# Sends images and events to the browser, and receives
|
||||
# events from the browser
|
||||
(url_prefix + r'/([0-9]+)/ws', self.WebSocket),
|
||||
|
||||
# Handles the downloading (i.e., saving) of static images
|
||||
(url_prefix + r'/([0-9]+)/download.([a-z0-9.]+)',
|
||||
self.Download),
|
||||
],
|
||||
template_path=core.FigureManagerWebAgg.get_static_file_path())
|
||||
|
||||
@classmethod
|
||||
def initialize(cls, url_prefix='', port=None, address=None):
|
||||
if cls.initialized:
|
||||
return
|
||||
|
||||
# Create the class instance
|
||||
app = cls(url_prefix=url_prefix)
|
||||
|
||||
cls.url_prefix = url_prefix
|
||||
|
||||
# This port selection algorithm is borrowed, more or less
|
||||
# verbatim, from IPython.
|
||||
def random_ports(port, n):
|
||||
"""
|
||||
Generate a list of n random ports near the given port.
|
||||
|
||||
The first 5 ports will be sequential, and the remaining n-5 will be
|
||||
randomly selected in the range [port-2*n, port+2*n].
|
||||
"""
|
||||
for i in range(min(5, n)):
|
||||
yield port + i
|
||||
for i in range(n - 5):
|
||||
yield port + random.randint(-2 * n, 2 * n)
|
||||
|
||||
if address is None:
|
||||
cls.address = rcParams['webagg.address']
|
||||
else:
|
||||
cls.address = address
|
||||
cls.port = rcParams['webagg.port']
|
||||
for port in random_ports(cls.port, rcParams['webagg.port_retries']):
|
||||
try:
|
||||
app.listen(port, cls.address)
|
||||
except socket.error as e:
|
||||
if e.errno != errno.EADDRINUSE:
|
||||
raise
|
||||
else:
|
||||
cls.port = port
|
||||
break
|
||||
else:
|
||||
raise SystemExit(
|
||||
"The webagg server could not be started because an available "
|
||||
"port could not be found")
|
||||
|
||||
cls.initialized = True
|
||||
|
||||
@classmethod
|
||||
def start(cls):
|
||||
if cls.started:
|
||||
return
|
||||
|
||||
"""
|
||||
IOLoop.running() was removed as of Tornado 2.4; see for example
|
||||
https://groups.google.com/forum/#!topic/python-tornado/QLMzkpQBGOY
|
||||
Thus there is no correct way to check if the loop has already been
|
||||
launched. We may end up with two concurrently running loops in that
|
||||
unlucky case with all the expected consequences.
|
||||
"""
|
||||
ioloop = tornado.ioloop.IOLoop.instance()
|
||||
|
||||
def shutdown():
|
||||
ioloop.stop()
|
||||
print("Server is stopped")
|
||||
sys.stdout.flush()
|
||||
cls.started = False
|
||||
|
||||
@contextmanager
|
||||
def catch_sigint():
|
||||
old_handler = signal.signal(
|
||||
signal.SIGINT,
|
||||
lambda sig, frame: ioloop.add_callback_from_signal(shutdown))
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
signal.signal(signal.SIGINT, old_handler)
|
||||
|
||||
# Set the flag to True *before* blocking on ioloop.start()
|
||||
cls.started = True
|
||||
|
||||
print("Press Ctrl+C to stop WebAgg server")
|
||||
sys.stdout.flush()
|
||||
with catch_sigint():
|
||||
ioloop.start()
|
||||
|
||||
|
||||
def ipython_inline_display(figure):
|
||||
import tornado.template
|
||||
|
||||
WebAggApplication.initialize()
|
||||
if not webagg_server_thread.is_alive():
|
||||
webagg_server_thread.start()
|
||||
|
||||
fignum = figure.number
|
||||
tpl = Path(core.FigureManagerWebAgg.get_static_file_path(),
|
||||
"ipython_inline_figure.html").read_text()
|
||||
t = tornado.template.Template(tpl)
|
||||
return t.generate(
|
||||
prefix=WebAggApplication.url_prefix,
|
||||
fig_id=fignum,
|
||||
toolitems=core.NavigationToolbar2WebAgg.toolitems,
|
||||
canvas=figure.canvas,
|
||||
port=WebAggApplication.port).decode('utf-8')
|
||||
|
||||
|
||||
@_Backend.export
|
||||
class _BackendWebAgg(_Backend):
|
||||
FigureCanvas = FigureCanvasWebAgg
|
||||
FigureManager = core.FigureManagerWebAgg
|
||||
|
||||
@staticmethod
|
||||
def trigger_manager_draw(manager):
|
||||
manager.canvas.draw_idle()
|
||||
|
||||
@staticmethod
|
||||
def show():
|
||||
WebAggApplication.initialize()
|
||||
|
||||
url = "http://{address}:{port}{prefix}".format(
|
||||
address=WebAggApplication.address,
|
||||
port=WebAggApplication.port,
|
||||
prefix=WebAggApplication.url_prefix)
|
||||
|
||||
if rcParams['webagg.open_in_browser']:
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
else:
|
||||
print("To view figure, visit {0}".format(url))
|
||||
|
||||
WebAggApplication.start()
|
||||
527
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py
vendored
Normal file
527
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
"""
|
||||
Displays Agg images in the browser, with interactivity
|
||||
"""
|
||||
# The WebAgg backend is divided into two modules:
|
||||
#
|
||||
# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
|
||||
# plot inside of a web application, and communicate in an abstract
|
||||
# way over a web socket.
|
||||
#
|
||||
# - `backend_webagg.py` contains a concrete implementation of a basic
|
||||
# application, implemented with tornado.
|
||||
|
||||
import datetime
|
||||
from io import StringIO
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
import tornado
|
||||
|
||||
from matplotlib import backend_bases, cbook, _png
|
||||
from matplotlib.backends import backend_agg
|
||||
from matplotlib.backend_bases import _Backend
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
# http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
|
||||
_SHIFT_LUT = {59: ':',
|
||||
61: '+',
|
||||
173: '_',
|
||||
186: ':',
|
||||
187: '+',
|
||||
188: '<',
|
||||
189: '_',
|
||||
190: '>',
|
||||
191: '?',
|
||||
192: '~',
|
||||
219: '{',
|
||||
220: '|',
|
||||
221: '}',
|
||||
222: '"'}
|
||||
|
||||
_LUT = {8: 'backspace',
|
||||
9: 'tab',
|
||||
13: 'enter',
|
||||
16: 'shift',
|
||||
17: 'control',
|
||||
18: 'alt',
|
||||
19: 'pause',
|
||||
20: 'caps',
|
||||
27: 'escape',
|
||||
32: ' ',
|
||||
33: 'pageup',
|
||||
34: 'pagedown',
|
||||
35: 'end',
|
||||
36: 'home',
|
||||
37: 'left',
|
||||
38: 'up',
|
||||
39: 'right',
|
||||
40: 'down',
|
||||
45: 'insert',
|
||||
46: 'delete',
|
||||
91: 'super',
|
||||
92: 'super',
|
||||
93: 'select',
|
||||
106: '*',
|
||||
107: '+',
|
||||
109: '-',
|
||||
110: '.',
|
||||
111: '/',
|
||||
144: 'num_lock',
|
||||
145: 'scroll_lock',
|
||||
186: ':',
|
||||
187: '=',
|
||||
188: ',',
|
||||
189: '-',
|
||||
190: '.',
|
||||
191: '/',
|
||||
192: '`',
|
||||
219: '[',
|
||||
220: '\\',
|
||||
221: ']',
|
||||
222: "'"}
|
||||
|
||||
|
||||
def _handle_key(key):
|
||||
"""Handle key codes"""
|
||||
code = int(key[key.index('k') + 1:])
|
||||
value = chr(code)
|
||||
# letter keys
|
||||
if 65 <= code <= 90:
|
||||
if 'shift+' in key:
|
||||
key = key.replace('shift+', '')
|
||||
else:
|
||||
value = value.lower()
|
||||
# number keys
|
||||
elif 48 <= code <= 57:
|
||||
if 'shift+' in key:
|
||||
value = ')!@#$%^&*('[int(value)]
|
||||
key = key.replace('shift+', '')
|
||||
# function keys
|
||||
elif 112 <= code <= 123:
|
||||
value = 'f%s' % (code - 111)
|
||||
# number pad keys
|
||||
elif 96 <= code <= 105:
|
||||
value = '%s' % (code - 96)
|
||||
# keys with shift alternatives
|
||||
elif code in _SHIFT_LUT and 'shift+' in key:
|
||||
key = key.replace('shift+', '')
|
||||
value = _SHIFT_LUT[code]
|
||||
elif code in _LUT:
|
||||
value = _LUT[code]
|
||||
key = key[:key.index('k')] + value
|
||||
return key
|
||||
|
||||
|
||||
class FigureCanvasWebAggCore(backend_agg.FigureCanvasAgg):
|
||||
supports_blit = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
backend_agg.FigureCanvasAgg.__init__(self, *args, **kwargs)
|
||||
|
||||
# Set to True when the renderer contains data that is newer
|
||||
# than the PNG buffer.
|
||||
self._png_is_old = True
|
||||
|
||||
# Set to True by the `refresh` message so that the next frame
|
||||
# sent to the clients will be a full frame.
|
||||
self._force_full = True
|
||||
|
||||
# Store the current image mode so that at any point, clients can
|
||||
# request the information. This should be changed by calling
|
||||
# self.set_image_mode(mode) so that the notification can be given
|
||||
# to the connected clients.
|
||||
self._current_image_mode = 'full'
|
||||
|
||||
# Store the DPI ratio of the browser. This is the scaling that
|
||||
# occurs automatically for all images on a HiDPI display.
|
||||
self._dpi_ratio = 1
|
||||
|
||||
def show(self):
|
||||
# show the figure window
|
||||
from matplotlib.pyplot import show
|
||||
show()
|
||||
|
||||
def draw(self):
|
||||
self._png_is_old = True
|
||||
try:
|
||||
super().draw()
|
||||
finally:
|
||||
self.manager.refresh_all() # Swap the frames.
|
||||
|
||||
def draw_idle(self):
|
||||
self.send_event("draw")
|
||||
|
||||
def set_image_mode(self, mode):
|
||||
"""
|
||||
Set the image mode for any subsequent images which will be sent
|
||||
to the clients. The modes may currently be either 'full' or 'diff'.
|
||||
|
||||
Note: diff images may not contain transparency, therefore upon
|
||||
draw this mode may be changed if the resulting image has any
|
||||
transparent component.
|
||||
"""
|
||||
cbook._check_in_list(['full', 'diff'], mode=mode)
|
||||
if self._current_image_mode != mode:
|
||||
self._current_image_mode = mode
|
||||
self.handle_send_image_mode(None)
|
||||
|
||||
def get_diff_image(self):
|
||||
if self._png_is_old:
|
||||
renderer = self.get_renderer()
|
||||
|
||||
# The buffer is created as type uint32 so that entire
|
||||
# pixels can be compared in one numpy call, rather than
|
||||
# needing to compare each plane separately.
|
||||
buff = (np.frombuffer(renderer.buffer_rgba(), dtype=np.uint32)
|
||||
.reshape((renderer.height, renderer.width)))
|
||||
|
||||
# If any pixels have transparency, we need to force a full
|
||||
# draw as we cannot overlay new on top of old.
|
||||
pixels = buff.view(dtype=np.uint8).reshape(buff.shape + (4,))
|
||||
|
||||
if self._force_full or np.any(pixels[:, :, 3] != 255):
|
||||
self.set_image_mode('full')
|
||||
output = buff
|
||||
else:
|
||||
self.set_image_mode('diff')
|
||||
last_buffer = (np.frombuffer(self._last_renderer.buffer_rgba(),
|
||||
dtype=np.uint32)
|
||||
.reshape((renderer.height, renderer.width)))
|
||||
diff = buff != last_buffer
|
||||
output = np.where(diff, buff, 0)
|
||||
|
||||
# TODO: We should write a new version of write_png that
|
||||
# handles the differencing inline
|
||||
buff = _png.write_png(
|
||||
output.view(dtype=np.uint8).reshape(output.shape + (4,)),
|
||||
None, compression=6, filter=_png.PNG_FILTER_NONE)
|
||||
|
||||
# Swap the renderer frames
|
||||
self._renderer, self._last_renderer = (
|
||||
self._last_renderer, renderer)
|
||||
self._force_full = False
|
||||
self._png_is_old = False
|
||||
return buff
|
||||
|
||||
def get_renderer(self, cleared=None):
|
||||
# Mirrors super.get_renderer, but caches the old one
|
||||
# so that we can do things such as produce a diff image
|
||||
# in get_diff_image
|
||||
_, _, w, h = self.figure.bbox.bounds
|
||||
w, h = int(w), int(h)
|
||||
key = w, h, self.figure.dpi
|
||||
try:
|
||||
self._lastKey, self._renderer
|
||||
except AttributeError:
|
||||
need_new_renderer = True
|
||||
else:
|
||||
need_new_renderer = (self._lastKey != key)
|
||||
|
||||
if need_new_renderer:
|
||||
self._renderer = backend_agg.RendererAgg(
|
||||
w, h, self.figure.dpi)
|
||||
self._last_renderer = backend_agg.RendererAgg(
|
||||
w, h, self.figure.dpi)
|
||||
self._lastKey = key
|
||||
|
||||
elif cleared:
|
||||
self._renderer.clear()
|
||||
|
||||
return self._renderer
|
||||
|
||||
def handle_event(self, event):
|
||||
e_type = event['type']
|
||||
handler = getattr(self, 'handle_{0}'.format(e_type),
|
||||
self.handle_unknown_event)
|
||||
return handler(event)
|
||||
|
||||
def handle_unknown_event(self, event):
|
||||
_log.warning('Unhandled message type {0}. {1}'.format(
|
||||
event['type'], event))
|
||||
|
||||
def handle_ack(self, event):
|
||||
# Network latency tends to decrease if traffic is flowing
|
||||
# in both directions. Therefore, the browser sends back
|
||||
# an "ack" message after each image frame is received.
|
||||
# This could also be used as a simple sanity check in the
|
||||
# future, but for now the performance increase is enough
|
||||
# to justify it, even if the server does nothing with it.
|
||||
pass
|
||||
|
||||
def handle_draw(self, event):
|
||||
self.draw()
|
||||
|
||||
def _handle_mouse(self, event):
|
||||
x = event['x']
|
||||
y = event['y']
|
||||
y = self.get_renderer().height - y
|
||||
|
||||
# Javascript button numbers and matplotlib button numbers are
|
||||
# off by 1
|
||||
button = event['button'] + 1
|
||||
|
||||
# The right mouse button pops up a context menu, which
|
||||
# doesn't work very well, so use the middle mouse button
|
||||
# instead. It doesn't seem that it's possible to disable
|
||||
# the context menu in recent versions of Chrome. If this
|
||||
# is resolved, please also adjust the docstring in MouseEvent.
|
||||
if button == 2:
|
||||
button = 3
|
||||
|
||||
e_type = event['type']
|
||||
guiEvent = event.get('guiEvent', None)
|
||||
if e_type == 'button_press':
|
||||
self.button_press_event(x, y, button, guiEvent=guiEvent)
|
||||
elif e_type == 'button_release':
|
||||
self.button_release_event(x, y, button, guiEvent=guiEvent)
|
||||
elif e_type == 'motion_notify':
|
||||
self.motion_notify_event(x, y, guiEvent=guiEvent)
|
||||
elif e_type == 'figure_enter':
|
||||
self.enter_notify_event(xy=(x, y), guiEvent=guiEvent)
|
||||
elif e_type == 'figure_leave':
|
||||
self.leave_notify_event()
|
||||
elif e_type == 'scroll':
|
||||
self.scroll_event(x, y, event['step'], guiEvent=guiEvent)
|
||||
handle_button_press = handle_button_release = handle_motion_notify = \
|
||||
handle_figure_enter = handle_figure_leave = handle_scroll = \
|
||||
_handle_mouse
|
||||
|
||||
def _handle_key(self, event):
|
||||
key = _handle_key(event['key'])
|
||||
e_type = event['type']
|
||||
guiEvent = event.get('guiEvent', None)
|
||||
if e_type == 'key_press':
|
||||
self.key_press_event(key, guiEvent=guiEvent)
|
||||
elif e_type == 'key_release':
|
||||
self.key_release_event(key, guiEvent=guiEvent)
|
||||
handle_key_press = handle_key_release = _handle_key
|
||||
|
||||
def handle_toolbar_button(self, event):
|
||||
# TODO: Be more suspicious of the input
|
||||
getattr(self.toolbar, event['name'])()
|
||||
|
||||
def handle_refresh(self, event):
|
||||
figure_label = self.figure.get_label()
|
||||
if not figure_label:
|
||||
figure_label = "Figure {0}".format(self.manager.num)
|
||||
self.send_event('figure_label', label=figure_label)
|
||||
self._force_full = True
|
||||
self.draw_idle()
|
||||
|
||||
def handle_resize(self, event):
|
||||
x, y = event.get('width', 800), event.get('height', 800)
|
||||
x, y = int(x) * self._dpi_ratio, int(y) * self._dpi_ratio
|
||||
fig = self.figure
|
||||
# An attempt at approximating the figure size in pixels.
|
||||
fig.set_size_inches(x / fig.dpi, y / fig.dpi, forward=False)
|
||||
|
||||
_, _, w, h = self.figure.bbox.bounds
|
||||
# Acknowledge the resize, and force the viewer to update the
|
||||
# canvas size to the figure's new size (which is hopefully
|
||||
# identical or within a pixel or so).
|
||||
self._png_is_old = True
|
||||
self.manager.resize(w, h)
|
||||
self.resize_event()
|
||||
|
||||
def handle_send_image_mode(self, event):
|
||||
# The client requests notification of what the current image mode is.
|
||||
self.send_event('image_mode', mode=self._current_image_mode)
|
||||
|
||||
def handle_set_dpi_ratio(self, event):
|
||||
dpi_ratio = event.get('dpi_ratio', 1)
|
||||
if dpi_ratio != self._dpi_ratio:
|
||||
# We don't want to scale up the figure dpi more than once.
|
||||
if not hasattr(self.figure, '_original_dpi'):
|
||||
self.figure._original_dpi = self.figure.dpi
|
||||
self.figure.dpi = dpi_ratio * self.figure._original_dpi
|
||||
self._dpi_ratio = dpi_ratio
|
||||
self._force_full = True
|
||||
self.draw_idle()
|
||||
|
||||
def send_event(self, event_type, **kwargs):
|
||||
self.manager._send_event(event_type, **kwargs)
|
||||
|
||||
|
||||
_JQUERY_ICON_CLASSES = {
|
||||
'home': 'ui-icon ui-icon-home',
|
||||
'back': 'ui-icon ui-icon-circle-arrow-w',
|
||||
'forward': 'ui-icon ui-icon-circle-arrow-e',
|
||||
'zoom_to_rect': 'ui-icon ui-icon-search',
|
||||
'move': 'ui-icon ui-icon-arrow-4',
|
||||
'download': 'ui-icon ui-icon-disk',
|
||||
None: None,
|
||||
}
|
||||
|
||||
|
||||
class NavigationToolbar2WebAgg(backend_bases.NavigationToolbar2):
|
||||
|
||||
# Use the standard toolbar items + download button
|
||||
toolitems = [(text, tooltip_text, _JQUERY_ICON_CLASSES[image_file],
|
||||
name_of_method)
|
||||
for text, tooltip_text, image_file, name_of_method
|
||||
in (backend_bases.NavigationToolbar2.toolitems +
|
||||
(('Download', 'Download plot', 'download', 'download'),))
|
||||
if image_file in _JQUERY_ICON_CLASSES]
|
||||
|
||||
def _init_toolbar(self):
|
||||
self.message = ''
|
||||
self.cursor = 0
|
||||
|
||||
def set_message(self, message):
|
||||
if message != self.message:
|
||||
self.canvas.send_event("message", message=message)
|
||||
self.message = message
|
||||
|
||||
def set_cursor(self, cursor):
|
||||
if cursor != self.cursor:
|
||||
self.canvas.send_event("cursor", cursor=cursor)
|
||||
self.cursor = cursor
|
||||
|
||||
def draw_rubberband(self, event, x0, y0, x1, y1):
|
||||
self.canvas.send_event(
|
||||
"rubberband", x0=x0, y0=y0, x1=x1, y1=y1)
|
||||
|
||||
def release_zoom(self, event):
|
||||
backend_bases.NavigationToolbar2.release_zoom(self, event)
|
||||
self.canvas.send_event(
|
||||
"rubberband", x0=-1, y0=-1, x1=-1, y1=-1)
|
||||
|
||||
def save_figure(self, *args):
|
||||
"""Save the current figure"""
|
||||
self.canvas.send_event('save')
|
||||
|
||||
|
||||
class FigureManagerWebAgg(backend_bases.FigureManagerBase):
|
||||
ToolbarCls = NavigationToolbar2WebAgg
|
||||
|
||||
def __init__(self, canvas, num):
|
||||
backend_bases.FigureManagerBase.__init__(self, canvas, num)
|
||||
|
||||
self.web_sockets = set()
|
||||
|
||||
self.toolbar = self._get_toolbar(canvas)
|
||||
|
||||
def show(self):
|
||||
pass
|
||||
|
||||
def _get_toolbar(self, canvas):
|
||||
toolbar = self.ToolbarCls(canvas)
|
||||
return toolbar
|
||||
|
||||
def resize(self, w, h):
|
||||
self._send_event(
|
||||
'resize',
|
||||
size=(w / self.canvas._dpi_ratio, h / self.canvas._dpi_ratio))
|
||||
|
||||
def set_window_title(self, title):
|
||||
self._send_event('figure_label', label=title)
|
||||
|
||||
# The following methods are specific to FigureManagerWebAgg
|
||||
|
||||
def add_web_socket(self, web_socket):
|
||||
assert hasattr(web_socket, 'send_binary')
|
||||
assert hasattr(web_socket, 'send_json')
|
||||
|
||||
self.web_sockets.add(web_socket)
|
||||
|
||||
_, _, w, h = self.canvas.figure.bbox.bounds
|
||||
self.resize(w, h)
|
||||
self._send_event('refresh')
|
||||
|
||||
def remove_web_socket(self, web_socket):
|
||||
self.web_sockets.remove(web_socket)
|
||||
|
||||
def handle_json(self, content):
|
||||
self.canvas.handle_event(content)
|
||||
|
||||
def refresh_all(self):
|
||||
if self.web_sockets:
|
||||
diff = self.canvas.get_diff_image()
|
||||
if diff is not None:
|
||||
for s in self.web_sockets:
|
||||
s.send_binary(diff)
|
||||
|
||||
@classmethod
|
||||
def get_javascript(cls, stream=None):
|
||||
if stream is None:
|
||||
output = StringIO()
|
||||
else:
|
||||
output = stream
|
||||
|
||||
output.write((Path(__file__).parent / "web_backend/js/mpl.js")
|
||||
.read_text(encoding="utf-8"))
|
||||
|
||||
toolitems = []
|
||||
for name, tooltip, image, method in cls.ToolbarCls.toolitems:
|
||||
if name is None:
|
||||
toolitems.append(['', '', '', ''])
|
||||
else:
|
||||
toolitems.append([name, tooltip, image, method])
|
||||
output.write("mpl.toolbar_items = {0};\n\n".format(
|
||||
json.dumps(toolitems)))
|
||||
|
||||
extensions = []
|
||||
for filetype, ext in sorted(FigureCanvasWebAggCore.
|
||||
get_supported_filetypes_grouped().
|
||||
items()):
|
||||
if not ext[0] == 'pgf': # pgf does not support BytesIO
|
||||
extensions.append(ext[0])
|
||||
output.write("mpl.extensions = {0};\n\n".format(
|
||||
json.dumps(extensions)))
|
||||
|
||||
output.write("mpl.default_extension = {0};".format(
|
||||
json.dumps(FigureCanvasWebAggCore.get_default_filetype())))
|
||||
|
||||
if stream is None:
|
||||
return output.getvalue()
|
||||
|
||||
@classmethod
|
||||
def get_static_file_path(cls):
|
||||
return os.path.join(os.path.dirname(__file__), 'web_backend')
|
||||
|
||||
def _send_event(self, event_type, **kwargs):
|
||||
payload = {'type': event_type, **kwargs}
|
||||
for s in self.web_sockets:
|
||||
s.send_json(payload)
|
||||
|
||||
|
||||
class TimerTornado(backend_bases.TimerBase):
|
||||
def _timer_start(self):
|
||||
self._timer_stop()
|
||||
if self._single:
|
||||
ioloop = tornado.ioloop.IOLoop.instance()
|
||||
self._timer = ioloop.add_timeout(
|
||||
datetime.timedelta(milliseconds=self.interval),
|
||||
self._on_timer)
|
||||
else:
|
||||
self._timer = tornado.ioloop.PeriodicCallback(
|
||||
self._on_timer,
|
||||
self.interval)
|
||||
self._timer.start()
|
||||
|
||||
def _timer_stop(self):
|
||||
if self._timer is None:
|
||||
return
|
||||
elif self._single:
|
||||
ioloop = tornado.ioloop.IOLoop.instance()
|
||||
ioloop.remove_timeout(self._timer)
|
||||
else:
|
||||
self._timer.stop()
|
||||
|
||||
self._timer = None
|
||||
|
||||
def _timer_set_interval(self):
|
||||
# Only stop and restart it if the timer has already been started
|
||||
if self._timer is not None:
|
||||
self._timer_stop()
|
||||
self._timer_start()
|
||||
|
||||
|
||||
@_Backend.export
|
||||
class _BackendWebAggCoreAgg(_Backend):
|
||||
FigureCanvas = FigureCanvasWebAggCore
|
||||
FigureManager = FigureManagerWebAgg
|
||||
1985
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_wx.py
vendored
Normal file
1985
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_wx.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_wxagg.py
vendored
Normal file
103
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_wxagg.py
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
import wx
|
||||
|
||||
from .backend_agg import FigureCanvasAgg
|
||||
from .backend_wx import (
|
||||
_BackendWx, _FigureCanvasWxBase, FigureFrameWx,
|
||||
NavigationToolbar2Wx as NavigationToolbar2WxAgg)
|
||||
|
||||
|
||||
class FigureFrameWxAgg(FigureFrameWx):
|
||||
def get_canvas(self, fig):
|
||||
return FigureCanvasWxAgg(self, -1, fig)
|
||||
|
||||
|
||||
class FigureCanvasWxAgg(FigureCanvasAgg, _FigureCanvasWxBase):
|
||||
"""
|
||||
The FigureCanvas contains the figure and does event handling.
|
||||
|
||||
In the wxPython backend, it is derived from wxPanel, and (usually)
|
||||
lives inside a frame instantiated by a FigureManagerWx. The parent
|
||||
window probably implements a wxSizer to control the displayed
|
||||
control size - but we give a hint as to our preferred minimum
|
||||
size.
|
||||
"""
|
||||
|
||||
def draw(self, drawDC=None):
|
||||
"""
|
||||
Render the figure using agg.
|
||||
"""
|
||||
FigureCanvasAgg.draw(self)
|
||||
|
||||
self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
|
||||
self._isDrawn = True
|
||||
self.gui_repaint(drawDC=drawDC, origin='WXAgg')
|
||||
|
||||
def blit(self, bbox=None):
|
||||
"""
|
||||
Transfer the region of the agg buffer defined by bbox to the display.
|
||||
If bbox is None, the entire buffer is transferred.
|
||||
"""
|
||||
if bbox is None:
|
||||
self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
|
||||
self.gui_repaint()
|
||||
return
|
||||
|
||||
l, b, w, h = bbox.bounds
|
||||
r = l + w
|
||||
t = b + h
|
||||
x = int(l)
|
||||
y = int(self.bitmap.GetHeight() - t)
|
||||
|
||||
srcBmp = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
|
||||
srcDC = wx.MemoryDC()
|
||||
srcDC.SelectObject(srcBmp)
|
||||
|
||||
destDC = wx.MemoryDC()
|
||||
destDC.SelectObject(self.bitmap)
|
||||
|
||||
destDC.Blit(x, y, int(w), int(h), srcDC, x, y)
|
||||
|
||||
destDC.SelectObject(wx.NullBitmap)
|
||||
srcDC.SelectObject(wx.NullBitmap)
|
||||
self.gui_repaint()
|
||||
|
||||
|
||||
def _convert_agg_to_wx_bitmap(agg, bbox):
|
||||
"""
|
||||
Convert the region of the agg buffer bounded by bbox to a wx.Bitmap. If
|
||||
bbox is None, the entire buffer is converted.
|
||||
Note: agg must be a backend_agg.RendererAgg instance.
|
||||
"""
|
||||
if bbox is None:
|
||||
# agg => rgba buffer -> bitmap
|
||||
return wx.Bitmap.FromBufferRGBA(int(agg.width), int(agg.height),
|
||||
agg.buffer_rgba())
|
||||
else:
|
||||
# agg => rgba buffer -> bitmap => clipped bitmap
|
||||
l, b, width, height = bbox.bounds
|
||||
r = l + width
|
||||
t = b + height
|
||||
|
||||
srcBmp = wx.Bitmap.FromBufferRGBA(int(agg.width), int(agg.height),
|
||||
agg.buffer_rgba())
|
||||
srcDC = wx.MemoryDC()
|
||||
srcDC.SelectObject(srcBmp)
|
||||
|
||||
destBmp = wx.Bitmap(int(width), int(height))
|
||||
destDC = wx.MemoryDC()
|
||||
destDC.SelectObject(destBmp)
|
||||
|
||||
x = int(l)
|
||||
y = int(int(agg.height) - t)
|
||||
destDC.Blit(0, 0, int(width), int(height), srcDC, x, y)
|
||||
|
||||
srcDC.SelectObject(wx.NullBitmap)
|
||||
destDC.SelectObject(wx.NullBitmap)
|
||||
|
||||
return destBmp
|
||||
|
||||
|
||||
@_BackendWx.export
|
||||
class _BackendWxAgg(_BackendWx):
|
||||
FigureCanvas = FigureCanvasWxAgg
|
||||
_frame_class = FigureFrameWxAgg
|
||||
48
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_wxcairo.py
vendored
Normal file
48
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/backend_wxcairo.py
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import wx
|
||||
|
||||
from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo
|
||||
from .backend_wx import (
|
||||
_BackendWx, _FigureCanvasWxBase, FigureFrameWx,
|
||||
NavigationToolbar2Wx as NavigationToolbar2WxCairo)
|
||||
import wx.lib.wxcairo as wxcairo
|
||||
|
||||
|
||||
class FigureFrameWxCairo(FigureFrameWx):
|
||||
def get_canvas(self, fig):
|
||||
return FigureCanvasWxCairo(self, -1, fig)
|
||||
|
||||
|
||||
class FigureCanvasWxCairo(_FigureCanvasWxBase, FigureCanvasCairo):
|
||||
"""
|
||||
The FigureCanvas contains the figure and does event handling.
|
||||
|
||||
In the wxPython backend, it is derived from wxPanel, and (usually) lives
|
||||
inside a frame instantiated by a FigureManagerWx. The parent window
|
||||
probably implements a wxSizer to control the displayed control size - but
|
||||
we give a hint as to our preferred minimum size.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, id, figure):
|
||||
# _FigureCanvasWxBase should be fixed to have the same signature as
|
||||
# every other FigureCanvas and use cooperative inheritance, but in the
|
||||
# meantime the following will make do.
|
||||
_FigureCanvasWxBase.__init__(self, parent, id, figure)
|
||||
FigureCanvasCairo.__init__(self, figure)
|
||||
self._renderer = RendererCairo(self.figure.dpi)
|
||||
|
||||
def draw(self, drawDC=None):
|
||||
width = int(self.figure.bbox.width)
|
||||
height = int(self.figure.bbox.height)
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
||||
self._renderer.set_ctx_from_surface(surface)
|
||||
self._renderer.set_width_height(width, height)
|
||||
self.figure.draw(self._renderer)
|
||||
self.bitmap = wxcairo.BitmapFromImageSurface(surface)
|
||||
self._isDrawn = True
|
||||
self.gui_repaint(drawDC=drawDC, origin='WXCairo')
|
||||
|
||||
|
||||
@_BackendWx.export
|
||||
class _BackendWxCairo(_BackendWx):
|
||||
FigureCanvas = FigureCanvasWxCairo
|
||||
_frame_class = FigureFrameWxCairo
|
||||
166
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_compat.py
vendored
Normal file
166
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_compat.py
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
"""
|
||||
Qt binding and backend selector.
|
||||
|
||||
The selection logic is as follows:
|
||||
- if any of PyQt5, PySide2, PyQt4 or PySide have already been imported
|
||||
(checked in that order), use it;
|
||||
- otherwise, if the QT_API environment variable (used by Enthought) is set, use
|
||||
it to determine which binding to use (but do not change the backend based on
|
||||
it; i.e. if the Qt5Agg backend is requested but QT_API is set to "pyqt4",
|
||||
then actually use Qt5 with PyQt5 or PySide2 (whichever can be imported);
|
||||
- otherwise, use whatever the rcParams indicate.
|
||||
"""
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
import os
|
||||
import sys
|
||||
|
||||
from matplotlib import rcParams
|
||||
|
||||
|
||||
QT_API_PYQT5 = "PyQt5"
|
||||
QT_API_PYSIDE2 = "PySide2"
|
||||
QT_API_PYQTv2 = "PyQt4v2"
|
||||
QT_API_PYSIDE = "PySide"
|
||||
QT_API_PYQT = "PyQt4" # Use the old sip v1 API (Py3 defaults to v2).
|
||||
QT_API_ENV = os.environ.get("QT_API")
|
||||
# Mapping of QT_API_ENV to requested binding. ETS does not support PyQt4v1.
|
||||
# (https://github.com/enthought/pyface/blob/master/pyface/qt/__init__.py)
|
||||
_ETS = {"pyqt5": QT_API_PYQT5, "pyside2": QT_API_PYSIDE2,
|
||||
"pyqt": QT_API_PYQTv2, "pyside": QT_API_PYSIDE,
|
||||
None: None}
|
||||
# First, check if anything is already imported.
|
||||
if "PyQt5.QtCore" in sys.modules:
|
||||
QT_API = QT_API_PYQT5
|
||||
elif "PySide2.QtCore" in sys.modules:
|
||||
QT_API = QT_API_PYSIDE2
|
||||
elif "PyQt4.QtCore" in sys.modules:
|
||||
QT_API = QT_API_PYQTv2
|
||||
elif "PySide.QtCore" in sys.modules:
|
||||
QT_API = QT_API_PYSIDE
|
||||
# Otherwise, check the QT_API environment variable (from Enthought). This can
|
||||
# only override the binding, not the backend (in other words, we check that the
|
||||
# requested backend actually matches).
|
||||
elif rcParams["backend"] in ["Qt5Agg", "Qt5Cairo"]:
|
||||
if QT_API_ENV in ["pyqt5", "pyside2"]:
|
||||
QT_API = _ETS[QT_API_ENV]
|
||||
else:
|
||||
QT_API = None
|
||||
elif rcParams["backend"] in ["Qt4Agg", "Qt4Cairo"]:
|
||||
if QT_API_ENV in ["pyqt4", "pyside"]:
|
||||
QT_API = _ETS[QT_API_ENV]
|
||||
else:
|
||||
QT_API = None
|
||||
# A non-Qt backend was selected but we still got there (possible, e.g., when
|
||||
# fully manually embedding Matplotlib in a Qt app without using pyplot).
|
||||
else:
|
||||
try:
|
||||
QT_API = _ETS[QT_API_ENV]
|
||||
except KeyError:
|
||||
raise RuntimeError(
|
||||
"The environment variable QT_API has the unrecognized value {!r};"
|
||||
"valid values are 'pyqt5', 'pyside2', 'pyqt', and 'pyside'")
|
||||
|
||||
|
||||
def _setup_pyqt5():
|
||||
global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName
|
||||
|
||||
if QT_API == QT_API_PYQT5:
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
__version__ = QtCore.PYQT_VERSION_STR
|
||||
QtCore.Signal = QtCore.pyqtSignal
|
||||
QtCore.Slot = QtCore.pyqtSlot
|
||||
QtCore.Property = QtCore.pyqtProperty
|
||||
elif QT_API == QT_API_PYSIDE2:
|
||||
from PySide2 import QtCore, QtGui, QtWidgets, __version__
|
||||
else:
|
||||
raise ValueError("Unexpected value for the 'backend.qt5' rcparam")
|
||||
_getSaveFileName = QtWidgets.QFileDialog.getSaveFileName
|
||||
|
||||
def is_pyqt5():
|
||||
return True
|
||||
|
||||
|
||||
def _setup_pyqt4():
|
||||
global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName
|
||||
|
||||
def _setup_pyqt4_internal(api):
|
||||
global QtCore, QtGui, QtWidgets, \
|
||||
__version__, is_pyqt5, _getSaveFileName
|
||||
# List of incompatible APIs:
|
||||
# http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
|
||||
_sip_apis = ["QDate", "QDateTime", "QString", "QTextStream", "QTime",
|
||||
"QUrl", "QVariant"]
|
||||
try:
|
||||
import sip
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
for _sip_api in _sip_apis:
|
||||
try:
|
||||
sip.setapi(_sip_api, api)
|
||||
except ValueError:
|
||||
pass
|
||||
from PyQt4 import QtCore, QtGui
|
||||
__version__ = QtCore.PYQT_VERSION_STR
|
||||
# PyQt 4.6 introduced getSaveFileNameAndFilter:
|
||||
# https://riverbankcomputing.com/news/pyqt-46
|
||||
if __version__ < LooseVersion("4.6"):
|
||||
raise ImportError("PyQt<4.6 is not supported")
|
||||
QtCore.Signal = QtCore.pyqtSignal
|
||||
QtCore.Slot = QtCore.pyqtSlot
|
||||
QtCore.Property = QtCore.pyqtProperty
|
||||
_getSaveFileName = QtGui.QFileDialog.getSaveFileNameAndFilter
|
||||
|
||||
if QT_API == QT_API_PYQTv2:
|
||||
_setup_pyqt4_internal(api=2)
|
||||
elif QT_API == QT_API_PYSIDE:
|
||||
from PySide import QtCore, QtGui, __version__, __version_info__
|
||||
# PySide 1.0.3 fixed the following:
|
||||
# https://srinikom.github.io/pyside-bz-archive/809.html
|
||||
if __version_info__ < (1, 0, 3):
|
||||
raise ImportError("PySide<1.0.3 is not supported")
|
||||
_getSaveFileName = QtGui.QFileDialog.getSaveFileName
|
||||
elif QT_API == QT_API_PYQT:
|
||||
_setup_pyqt4_internal(api=1)
|
||||
else:
|
||||
raise ValueError("Unexpected value for the 'backend.qt4' rcparam")
|
||||
QtWidgets = QtGui
|
||||
|
||||
def is_pyqt5():
|
||||
return False
|
||||
|
||||
|
||||
if QT_API in [QT_API_PYQT5, QT_API_PYSIDE2]:
|
||||
_setup_pyqt5()
|
||||
elif QT_API in [QT_API_PYQTv2, QT_API_PYSIDE, QT_API_PYQT]:
|
||||
_setup_pyqt4()
|
||||
elif QT_API is None:
|
||||
if rcParams["backend"] == "Qt4Agg":
|
||||
_candidates = [(_setup_pyqt4, QT_API_PYQTv2),
|
||||
(_setup_pyqt4, QT_API_PYSIDE),
|
||||
(_setup_pyqt4, QT_API_PYQT),
|
||||
(_setup_pyqt5, QT_API_PYQT5),
|
||||
(_setup_pyqt5, QT_API_PYSIDE2)]
|
||||
else:
|
||||
_candidates = [(_setup_pyqt5, QT_API_PYQT5),
|
||||
(_setup_pyqt5, QT_API_PYSIDE2),
|
||||
(_setup_pyqt4, QT_API_PYQTv2),
|
||||
(_setup_pyqt4, QT_API_PYSIDE),
|
||||
(_setup_pyqt4, QT_API_PYQT)]
|
||||
for _setup, QT_API in _candidates:
|
||||
try:
|
||||
_setup()
|
||||
except ImportError:
|
||||
continue
|
||||
break
|
||||
else:
|
||||
raise ImportError("Failed to import any qt binding")
|
||||
else: # We should not get there.
|
||||
raise AssertionError("Unexpected QT_API: {}".format(QT_API))
|
||||
|
||||
|
||||
# These globals are only defined for backcompatibility purposes.
|
||||
ETS = dict(pyqt=(QT_API_PYQTv2, 4), pyside=(QT_API_PYSIDE, 4),
|
||||
pyqt5=(QT_API_PYQT5, 5), pyside2=(QT_API_PYSIDE2, 5))
|
||||
QT_RC_MAJOR_VERSION = 5 if is_pyqt5() else 4
|
||||
0
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/__init__.py
vendored
Normal file
0
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/__init__.py
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
568
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/_formlayout.py
vendored
Normal file
568
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/_formlayout.py
vendored
Normal file
@@ -0,0 +1,568 @@
|
||||
"""
|
||||
formlayout
|
||||
==========
|
||||
|
||||
Module creating Qt form dialogs/layouts to edit various type of parameters
|
||||
|
||||
|
||||
formlayout License Agreement (MIT License)
|
||||
------------------------------------------
|
||||
|
||||
Copyright (c) 2009 Pierre Raybaut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
# History:
|
||||
# 1.0.10: added float validator (disable "Ok" and "Apply" button when not valid)
|
||||
# 1.0.7: added support for "Apply" button
|
||||
# 1.0.6: code cleaning
|
||||
|
||||
__version__ = '1.0.10'
|
||||
__license__ = __doc__
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
import logging
|
||||
from numbers import Integral, Real
|
||||
|
||||
from matplotlib import cbook, colors as mcolors
|
||||
from matplotlib.backends.qt_compat import QtGui, QtWidgets, QtCore
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
BLACKLIST = {"title", "label"}
|
||||
|
||||
|
||||
class ColorButton(QtWidgets.QPushButton):
|
||||
"""
|
||||
Color choosing push button
|
||||
"""
|
||||
colorChanged = QtCore.Signal(QtGui.QColor)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QtWidgets.QPushButton.__init__(self, parent)
|
||||
self.setFixedSize(20, 20)
|
||||
self.setIconSize(QtCore.QSize(12, 12))
|
||||
self.clicked.connect(self.choose_color)
|
||||
self._color = QtGui.QColor()
|
||||
|
||||
def choose_color(self):
|
||||
color = QtWidgets.QColorDialog.getColor(
|
||||
self._color, self.parentWidget(), "",
|
||||
QtWidgets.QColorDialog.ShowAlphaChannel)
|
||||
if color.isValid():
|
||||
self.set_color(color)
|
||||
|
||||
def get_color(self):
|
||||
return self._color
|
||||
|
||||
@QtCore.Slot(QtGui.QColor)
|
||||
def set_color(self, color):
|
||||
if color != self._color:
|
||||
self._color = color
|
||||
self.colorChanged.emit(self._color)
|
||||
pixmap = QtGui.QPixmap(self.iconSize())
|
||||
pixmap.fill(color)
|
||||
self.setIcon(QtGui.QIcon(pixmap))
|
||||
|
||||
color = QtCore.Property(QtGui.QColor, get_color, set_color)
|
||||
|
||||
|
||||
def to_qcolor(color):
|
||||
"""Create a QColor from a matplotlib color"""
|
||||
qcolor = QtGui.QColor()
|
||||
try:
|
||||
rgba = mcolors.to_rgba(color)
|
||||
except ValueError:
|
||||
cbook._warn_external('Ignoring invalid color %r' % color)
|
||||
return qcolor # return invalid QColor
|
||||
qcolor.setRgbF(*rgba)
|
||||
return qcolor
|
||||
|
||||
|
||||
class ColorLayout(QtWidgets.QHBoxLayout):
|
||||
"""Color-specialized QLineEdit layout"""
|
||||
def __init__(self, color, parent=None):
|
||||
QtWidgets.QHBoxLayout.__init__(self)
|
||||
assert isinstance(color, QtGui.QColor)
|
||||
self.lineedit = QtWidgets.QLineEdit(
|
||||
mcolors.to_hex(color.getRgbF(), keep_alpha=True), parent)
|
||||
self.lineedit.editingFinished.connect(self.update_color)
|
||||
self.addWidget(self.lineedit)
|
||||
self.colorbtn = ColorButton(parent)
|
||||
self.colorbtn.color = color
|
||||
self.colorbtn.colorChanged.connect(self.update_text)
|
||||
self.addWidget(self.colorbtn)
|
||||
|
||||
def update_color(self):
|
||||
color = self.text()
|
||||
qcolor = to_qcolor(color)
|
||||
self.colorbtn.color = qcolor # defaults to black if not qcolor.isValid()
|
||||
|
||||
def update_text(self, color):
|
||||
self.lineedit.setText(mcolors.to_hex(color.getRgbF(), keep_alpha=True))
|
||||
|
||||
def text(self):
|
||||
return self.lineedit.text()
|
||||
|
||||
|
||||
def font_is_installed(font):
|
||||
"""Check if font is installed"""
|
||||
return [fam for fam in QtGui.QFontDatabase().families()
|
||||
if str(fam) == font]
|
||||
|
||||
|
||||
def tuple_to_qfont(tup):
|
||||
"""
|
||||
Create a QFont from tuple:
|
||||
(family [string], size [int], italic [bool], bold [bool])
|
||||
"""
|
||||
if not (isinstance(tup, tuple) and len(tup) == 4
|
||||
and font_is_installed(tup[0])
|
||||
and isinstance(tup[1], Integral)
|
||||
and isinstance(tup[2], bool)
|
||||
and isinstance(tup[3], bool)):
|
||||
return None
|
||||
font = QtGui.QFont()
|
||||
family, size, italic, bold = tup
|
||||
font.setFamily(family)
|
||||
font.setPointSize(size)
|
||||
font.setItalic(italic)
|
||||
font.setBold(bold)
|
||||
return font
|
||||
|
||||
|
||||
def qfont_to_tuple(font):
|
||||
return (str(font.family()), int(font.pointSize()),
|
||||
font.italic(), font.bold())
|
||||
|
||||
|
||||
class FontLayout(QtWidgets.QGridLayout):
|
||||
"""Font selection"""
|
||||
def __init__(self, value, parent=None):
|
||||
QtWidgets.QGridLayout.__init__(self)
|
||||
font = tuple_to_qfont(value)
|
||||
assert font is not None
|
||||
|
||||
# Font family
|
||||
self.family = QtWidgets.QFontComboBox(parent)
|
||||
self.family.setCurrentFont(font)
|
||||
self.addWidget(self.family, 0, 0, 1, -1)
|
||||
|
||||
# Font size
|
||||
self.size = QtWidgets.QComboBox(parent)
|
||||
self.size.setEditable(True)
|
||||
sizelist = [*range(6, 12), *range(12, 30, 2), 36, 48, 72]
|
||||
size = font.pointSize()
|
||||
if size not in sizelist:
|
||||
sizelist.append(size)
|
||||
sizelist.sort()
|
||||
self.size.addItems([str(s) for s in sizelist])
|
||||
self.size.setCurrentIndex(sizelist.index(size))
|
||||
self.addWidget(self.size, 1, 0)
|
||||
|
||||
# Italic or not
|
||||
self.italic = QtWidgets.QCheckBox(self.tr("Italic"), parent)
|
||||
self.italic.setChecked(font.italic())
|
||||
self.addWidget(self.italic, 1, 1)
|
||||
|
||||
# Bold or not
|
||||
self.bold = QtWidgets.QCheckBox(self.tr("Bold"), parent)
|
||||
self.bold.setChecked(font.bold())
|
||||
self.addWidget(self.bold, 1, 2)
|
||||
|
||||
def get_font(self):
|
||||
font = self.family.currentFont()
|
||||
font.setItalic(self.italic.isChecked())
|
||||
font.setBold(self.bold.isChecked())
|
||||
font.setPointSize(int(self.size.currentText()))
|
||||
return qfont_to_tuple(font)
|
||||
|
||||
|
||||
def is_edit_valid(edit):
|
||||
text = edit.text()
|
||||
state = edit.validator().validate(text, 0)[0]
|
||||
|
||||
return state == QtGui.QDoubleValidator.Acceptable
|
||||
|
||||
|
||||
class FormWidget(QtWidgets.QWidget):
|
||||
update_buttons = QtCore.Signal()
|
||||
|
||||
def __init__(self, data, comment="", with_margin=False, parent=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
data : list of (label, value) pairs
|
||||
The data to be edited in the form.
|
||||
comment : str, optional
|
||||
|
||||
with_margin : bool, optional, default: False
|
||||
If False, the form elements reach to the border of the widget.
|
||||
This is the desired behavior if the FormWidget is used as a widget
|
||||
alongside with other widgets such as a QComboBox, which also do
|
||||
not have a margin around them.
|
||||
However, a margin can be desired if the FormWidget is the only
|
||||
widget within a container, e.g. a tab in a QTabWidget.
|
||||
parent : QWidget or None
|
||||
The parent widget.
|
||||
"""
|
||||
QtWidgets.QWidget.__init__(self, parent)
|
||||
self.data = copy.deepcopy(data)
|
||||
self.widgets = []
|
||||
self.formlayout = QtWidgets.QFormLayout(self)
|
||||
if not with_margin:
|
||||
self.formlayout.setContentsMargins(0, 0, 0, 0)
|
||||
if comment:
|
||||
self.formlayout.addRow(QtWidgets.QLabel(comment))
|
||||
self.formlayout.addRow(QtWidgets.QLabel(" "))
|
||||
|
||||
def get_dialog(self):
|
||||
"""Return FormDialog instance"""
|
||||
dialog = self.parent()
|
||||
while not isinstance(dialog, QtWidgets.QDialog):
|
||||
dialog = dialog.parent()
|
||||
return dialog
|
||||
|
||||
def setup(self):
|
||||
for label, value in self.data:
|
||||
if label is None and value is None:
|
||||
# Separator: (None, None)
|
||||
self.formlayout.addRow(QtWidgets.QLabel(" "),
|
||||
QtWidgets.QLabel(" "))
|
||||
self.widgets.append(None)
|
||||
continue
|
||||
elif label is None:
|
||||
# Comment
|
||||
self.formlayout.addRow(QtWidgets.QLabel(value))
|
||||
self.widgets.append(None)
|
||||
continue
|
||||
elif tuple_to_qfont(value) is not None:
|
||||
field = FontLayout(value, self)
|
||||
elif (label.lower() not in BLACKLIST
|
||||
and mcolors.is_color_like(value)):
|
||||
field = ColorLayout(to_qcolor(value), self)
|
||||
elif isinstance(value, str):
|
||||
field = QtWidgets.QLineEdit(value, self)
|
||||
elif isinstance(value, (list, tuple)):
|
||||
if isinstance(value, tuple):
|
||||
value = list(value)
|
||||
# Note: get() below checks the type of value[0] in self.data so
|
||||
# it is essential that value gets modified in-place.
|
||||
# This means that the code is actually broken in the case where
|
||||
# value is a tuple, but fortunately we always pass a list...
|
||||
selindex = value.pop(0)
|
||||
field = QtWidgets.QComboBox(self)
|
||||
if isinstance(value[0], (list, tuple)):
|
||||
keys = [key for key, _val in value]
|
||||
value = [val for _key, val in value]
|
||||
else:
|
||||
keys = value
|
||||
field.addItems(value)
|
||||
if selindex in value:
|
||||
selindex = value.index(selindex)
|
||||
elif selindex in keys:
|
||||
selindex = keys.index(selindex)
|
||||
elif not isinstance(selindex, Integral):
|
||||
_log.warning(
|
||||
"index '%s' is invalid (label: %s, value: %s)",
|
||||
selindex, label, value)
|
||||
selindex = 0
|
||||
field.setCurrentIndex(selindex)
|
||||
elif isinstance(value, bool):
|
||||
field = QtWidgets.QCheckBox(self)
|
||||
if value:
|
||||
field.setCheckState(QtCore.Qt.Checked)
|
||||
else:
|
||||
field.setCheckState(QtCore.Qt.Unchecked)
|
||||
elif isinstance(value, Integral):
|
||||
field = QtWidgets.QSpinBox(self)
|
||||
field.setRange(-1e9, 1e9)
|
||||
field.setValue(value)
|
||||
elif isinstance(value, Real):
|
||||
field = QtWidgets.QLineEdit(repr(value), self)
|
||||
field.setCursorPosition(0)
|
||||
field.setValidator(QtGui.QDoubleValidator(field))
|
||||
field.validator().setLocale(QtCore.QLocale("C"))
|
||||
dialog = self.get_dialog()
|
||||
dialog.register_float_field(field)
|
||||
field.textChanged.connect(lambda text: dialog.update_buttons())
|
||||
elif isinstance(value, datetime.datetime):
|
||||
field = QtWidgets.QDateTimeEdit(self)
|
||||
field.setDateTime(value)
|
||||
elif isinstance(value, datetime.date):
|
||||
field = QtWidgets.QDateEdit(self)
|
||||
field.setDate(value)
|
||||
else:
|
||||
field = QtWidgets.QLineEdit(repr(value), self)
|
||||
self.formlayout.addRow(label, field)
|
||||
self.widgets.append(field)
|
||||
|
||||
def get(self):
|
||||
valuelist = []
|
||||
for index, (label, value) in enumerate(self.data):
|
||||
field = self.widgets[index]
|
||||
if label is None:
|
||||
# Separator / Comment
|
||||
continue
|
||||
elif tuple_to_qfont(value) is not None:
|
||||
value = field.get_font()
|
||||
elif isinstance(value, str) or mcolors.is_color_like(value):
|
||||
value = str(field.text())
|
||||
elif isinstance(value, (list, tuple)):
|
||||
index = int(field.currentIndex())
|
||||
if isinstance(value[0], (list, tuple)):
|
||||
value = value[index][0]
|
||||
else:
|
||||
value = value[index]
|
||||
elif isinstance(value, bool):
|
||||
value = field.checkState() == QtCore.Qt.Checked
|
||||
elif isinstance(value, Integral):
|
||||
value = int(field.value())
|
||||
elif isinstance(value, Real):
|
||||
value = float(str(field.text()))
|
||||
elif isinstance(value, datetime.datetime):
|
||||
value = field.dateTime().toPyDateTime()
|
||||
elif isinstance(value, datetime.date):
|
||||
value = field.date().toPyDate()
|
||||
else:
|
||||
value = eval(str(field.text()))
|
||||
valuelist.append(value)
|
||||
return valuelist
|
||||
|
||||
|
||||
class FormComboWidget(QtWidgets.QWidget):
|
||||
update_buttons = QtCore.Signal()
|
||||
|
||||
def __init__(self, datalist, comment="", parent=None):
|
||||
QtWidgets.QWidget.__init__(self, parent)
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
self.setLayout(layout)
|
||||
self.combobox = QtWidgets.QComboBox()
|
||||
layout.addWidget(self.combobox)
|
||||
|
||||
self.stackwidget = QtWidgets.QStackedWidget(self)
|
||||
layout.addWidget(self.stackwidget)
|
||||
self.combobox.currentIndexChanged.connect(
|
||||
self.stackwidget.setCurrentIndex)
|
||||
|
||||
self.widgetlist = []
|
||||
for data, title, comment in datalist:
|
||||
self.combobox.addItem(title)
|
||||
widget = FormWidget(data, comment=comment, parent=self)
|
||||
self.stackwidget.addWidget(widget)
|
||||
self.widgetlist.append(widget)
|
||||
|
||||
def setup(self):
|
||||
for widget in self.widgetlist:
|
||||
widget.setup()
|
||||
|
||||
def get(self):
|
||||
return [widget.get() for widget in self.widgetlist]
|
||||
|
||||
|
||||
class FormTabWidget(QtWidgets.QWidget):
|
||||
update_buttons = QtCore.Signal()
|
||||
|
||||
def __init__(self, datalist, comment="", parent=None):
|
||||
QtWidgets.QWidget.__init__(self, parent)
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
self.tabwidget = QtWidgets.QTabWidget()
|
||||
layout.addWidget(self.tabwidget)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.setLayout(layout)
|
||||
self.widgetlist = []
|
||||
for data, title, comment in datalist:
|
||||
if len(data[0]) == 3:
|
||||
widget = FormComboWidget(data, comment=comment, parent=self)
|
||||
else:
|
||||
widget = FormWidget(data, with_margin=True, comment=comment,
|
||||
parent=self)
|
||||
index = self.tabwidget.addTab(widget, title)
|
||||
self.tabwidget.setTabToolTip(index, comment)
|
||||
self.widgetlist.append(widget)
|
||||
|
||||
def setup(self):
|
||||
for widget in self.widgetlist:
|
||||
widget.setup()
|
||||
|
||||
def get(self):
|
||||
return [widget.get() for widget in self.widgetlist]
|
||||
|
||||
|
||||
class FormDialog(QtWidgets.QDialog):
|
||||
"""Form Dialog"""
|
||||
def __init__(self, data, title="", comment="",
|
||||
icon=None, parent=None, apply=None):
|
||||
QtWidgets.QDialog.__init__(self, parent)
|
||||
|
||||
self.apply_callback = apply
|
||||
|
||||
# Form
|
||||
if isinstance(data[0][0], (list, tuple)):
|
||||
self.formwidget = FormTabWidget(data, comment=comment,
|
||||
parent=self)
|
||||
elif len(data[0]) == 3:
|
||||
self.formwidget = FormComboWidget(data, comment=comment,
|
||||
parent=self)
|
||||
else:
|
||||
self.formwidget = FormWidget(data, comment=comment,
|
||||
parent=self)
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
layout.addWidget(self.formwidget)
|
||||
|
||||
self.float_fields = []
|
||||
self.formwidget.setup()
|
||||
|
||||
# Button box
|
||||
self.bbox = bbox = QtWidgets.QDialogButtonBox(
|
||||
QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
|
||||
self.formwidget.update_buttons.connect(self.update_buttons)
|
||||
if self.apply_callback is not None:
|
||||
apply_btn = bbox.addButton(QtWidgets.QDialogButtonBox.Apply)
|
||||
apply_btn.clicked.connect(self.apply)
|
||||
|
||||
bbox.accepted.connect(self.accept)
|
||||
bbox.rejected.connect(self.reject)
|
||||
layout.addWidget(bbox)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
self.setWindowTitle(title)
|
||||
if not isinstance(icon, QtGui.QIcon):
|
||||
icon = QtWidgets.QWidget().style().standardIcon(
|
||||
QtWidgets.QStyle.SP_MessageBoxQuestion)
|
||||
self.setWindowIcon(icon)
|
||||
|
||||
def register_float_field(self, field):
|
||||
self.float_fields.append(field)
|
||||
|
||||
def update_buttons(self):
|
||||
valid = True
|
||||
for field in self.float_fields:
|
||||
if not is_edit_valid(field):
|
||||
valid = False
|
||||
for btn_type in (QtWidgets.QDialogButtonBox.Ok,
|
||||
QtWidgets.QDialogButtonBox.Apply):
|
||||
btn = self.bbox.button(btn_type)
|
||||
if btn is not None:
|
||||
btn.setEnabled(valid)
|
||||
|
||||
def accept(self):
|
||||
self.data = self.formwidget.get()
|
||||
QtWidgets.QDialog.accept(self)
|
||||
|
||||
def reject(self):
|
||||
self.data = None
|
||||
QtWidgets.QDialog.reject(self)
|
||||
|
||||
def apply(self):
|
||||
self.apply_callback(self.formwidget.get())
|
||||
|
||||
def get(self):
|
||||
"""Return form result"""
|
||||
return self.data
|
||||
|
||||
|
||||
def fedit(data, title="", comment="", icon=None, parent=None, apply=None):
|
||||
"""
|
||||
Create form dialog and return result
|
||||
(if Cancel button is pressed, return None)
|
||||
|
||||
data: datalist, datagroup
|
||||
title: string
|
||||
comment: string
|
||||
icon: QIcon instance
|
||||
parent: parent QWidget
|
||||
apply: apply callback (function)
|
||||
|
||||
datalist: list/tuple of (field_name, field_value)
|
||||
datagroup: list/tuple of (datalist *or* datagroup, title, comment)
|
||||
|
||||
-> one field for each member of a datalist
|
||||
-> one tab for each member of a top-level datagroup
|
||||
-> one page (of a multipage widget, each page can be selected with a combo
|
||||
box) for each member of a datagroup inside a datagroup
|
||||
|
||||
Supported types for field_value:
|
||||
- int, float, str, unicode, bool
|
||||
- colors: in Qt-compatible text form, i.e. in hex format or name (red,...)
|
||||
(automatically detected from a string)
|
||||
- list/tuple:
|
||||
* the first element will be the selected index (or value)
|
||||
* the other elements can be couples (key, value) or only values
|
||||
"""
|
||||
|
||||
# Create a QApplication instance if no instance currently exists
|
||||
# (e.g., if the module is used directly from the interpreter)
|
||||
if QtWidgets.QApplication.startingUp():
|
||||
_app = QtWidgets.QApplication([])
|
||||
dialog = FormDialog(data, title, comment, icon, parent, apply)
|
||||
if dialog.exec_():
|
||||
return dialog.get()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
def create_datalist_example():
|
||||
return [('str', 'this is a string'),
|
||||
('list', [0, '1', '3', '4']),
|
||||
('list2', ['--', ('none', 'None'), ('--', 'Dashed'),
|
||||
('-.', 'DashDot'), ('-', 'Solid'),
|
||||
('steps', 'Steps'), (':', 'Dotted')]),
|
||||
('float', 1.2),
|
||||
(None, 'Other:'),
|
||||
('int', 12),
|
||||
('font', ('Arial', 10, False, True)),
|
||||
('color', '#123409'),
|
||||
('bool', True),
|
||||
('date', datetime.date(2010, 10, 10)),
|
||||
('datetime', datetime.datetime(2010, 10, 10)),
|
||||
]
|
||||
|
||||
def create_datagroup_example():
|
||||
datalist = create_datalist_example()
|
||||
return ((datalist, "Category 1", "Category 1 comment"),
|
||||
(datalist, "Category 2", "Category 2 comment"),
|
||||
(datalist, "Category 3", "Category 3 comment"))
|
||||
|
||||
#--------- datalist example
|
||||
datalist = create_datalist_example()
|
||||
|
||||
def apply_test(data):
|
||||
print("data:", data)
|
||||
print("result:", fedit(datalist, title="Example",
|
||||
comment="This is just an <b>example</b>.",
|
||||
apply=apply_test))
|
||||
|
||||
#--------- datagroup example
|
||||
datagroup = create_datagroup_example()
|
||||
print("result:", fedit(datagroup, "Global title"))
|
||||
|
||||
#--------- datagroup inside a datagroup example
|
||||
datalist = create_datalist_example()
|
||||
datagroup = create_datagroup_example()
|
||||
print("result:", fedit(((datagroup, "Title 1", "Tab 1 comment"),
|
||||
(datalist, "Title 2", "Tab 2 comment"),
|
||||
(datalist, "Title 3", "Tab 3 comment")),
|
||||
"Global title"))
|
||||
264
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/figureoptions.py
vendored
Normal file
264
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/figureoptions.py
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
# Copyright © 2009 Pierre Raybaut
|
||||
# Licensed under the terms of the MIT License
|
||||
# see the mpl licenses directory for a copy of the license
|
||||
|
||||
|
||||
"""Module that provides a GUI-based editor for matplotlib's figure options."""
|
||||
|
||||
import os.path
|
||||
import re
|
||||
|
||||
import matplotlib
|
||||
from matplotlib import cm, colors as mcolors, markers, image as mimage
|
||||
from matplotlib.backends.qt_compat import QtGui
|
||||
from matplotlib.backends.qt_editor import _formlayout
|
||||
|
||||
|
||||
def get_icon(name):
|
||||
basedir = os.path.join(matplotlib.rcParams['datapath'], 'images')
|
||||
return QtGui.QIcon(os.path.join(basedir, name))
|
||||
|
||||
|
||||
LINESTYLES = {'-': 'Solid',
|
||||
'--': 'Dashed',
|
||||
'-.': 'DashDot',
|
||||
':': 'Dotted',
|
||||
'None': 'None',
|
||||
}
|
||||
|
||||
DRAWSTYLES = {
|
||||
'default': 'Default',
|
||||
'steps-pre': 'Steps (Pre)', 'steps': 'Steps (Pre)',
|
||||
'steps-mid': 'Steps (Mid)',
|
||||
'steps-post': 'Steps (Post)'}
|
||||
|
||||
MARKERS = markers.MarkerStyle.markers
|
||||
|
||||
|
||||
def figure_edit(axes, parent=None):
|
||||
"""Edit matplotlib figure options"""
|
||||
sep = (None, None) # separator
|
||||
|
||||
# Get / General
|
||||
# Cast to builtin floats as they have nicer reprs.
|
||||
xmin, xmax = map(float, axes.get_xlim())
|
||||
ymin, ymax = map(float, axes.get_ylim())
|
||||
general = [('Title', axes.get_title()),
|
||||
sep,
|
||||
(None, "<b>X-Axis</b>"),
|
||||
('Left', xmin), ('Right', xmax),
|
||||
('Label', axes.get_xlabel()),
|
||||
('Scale', [axes.get_xscale(), 'linear', 'log', 'logit']),
|
||||
sep,
|
||||
(None, "<b>Y-Axis</b>"),
|
||||
('Bottom', ymin), ('Top', ymax),
|
||||
('Label', axes.get_ylabel()),
|
||||
('Scale', [axes.get_yscale(), 'linear', 'log', 'logit']),
|
||||
sep,
|
||||
('(Re-)Generate automatic legend', False),
|
||||
]
|
||||
|
||||
# Save the unit data
|
||||
xconverter = axes.xaxis.converter
|
||||
yconverter = axes.yaxis.converter
|
||||
xunits = axes.xaxis.get_units()
|
||||
yunits = axes.yaxis.get_units()
|
||||
|
||||
# Sorting for default labels (_lineXXX, _imageXXX).
|
||||
def cmp_key(label):
|
||||
match = re.match(r"(_line|_image)(\d+)", label)
|
||||
if match:
|
||||
return match.group(1), int(match.group(2))
|
||||
else:
|
||||
return label, 0
|
||||
|
||||
# Get / Curves
|
||||
linedict = {}
|
||||
for line in axes.get_lines():
|
||||
label = line.get_label()
|
||||
if label == '_nolegend_':
|
||||
continue
|
||||
linedict[label] = line
|
||||
curves = []
|
||||
|
||||
def prepare_data(d, init):
|
||||
"""Prepare entry for FormLayout.
|
||||
|
||||
`d` is a mapping of shorthands to style names (a single style may
|
||||
have multiple shorthands, in particular the shorthands `None`,
|
||||
`"None"`, `"none"` and `""` are synonyms); `init` is one shorthand
|
||||
of the initial style.
|
||||
|
||||
This function returns an list suitable for initializing a
|
||||
FormLayout combobox, namely `[initial_name, (shorthand,
|
||||
style_name), (shorthand, style_name), ...]`.
|
||||
"""
|
||||
if init not in d:
|
||||
d = {**d, init: str(init)}
|
||||
# Drop duplicate shorthands from dict (by overwriting them during
|
||||
# the dict comprehension).
|
||||
name2short = {name: short for short, name in d.items()}
|
||||
# Convert back to {shorthand: name}.
|
||||
short2name = {short: name for name, short in name2short.items()}
|
||||
# Find the kept shorthand for the style specified by init.
|
||||
canonical_init = name2short[d[init]]
|
||||
# Sort by representation and prepend the initial value.
|
||||
return ([canonical_init] +
|
||||
sorted(short2name.items(),
|
||||
key=lambda short_and_name: short_and_name[1]))
|
||||
|
||||
curvelabels = sorted(linedict, key=cmp_key)
|
||||
for label in curvelabels:
|
||||
line = linedict[label]
|
||||
color = mcolors.to_hex(
|
||||
mcolors.to_rgba(line.get_color(), line.get_alpha()),
|
||||
keep_alpha=True)
|
||||
ec = mcolors.to_hex(
|
||||
mcolors.to_rgba(line.get_markeredgecolor(), line.get_alpha()),
|
||||
keep_alpha=True)
|
||||
fc = mcolors.to_hex(
|
||||
mcolors.to_rgba(line.get_markerfacecolor(), line.get_alpha()),
|
||||
keep_alpha=True)
|
||||
curvedata = [
|
||||
('Label', label),
|
||||
sep,
|
||||
(None, '<b>Line</b>'),
|
||||
('Line style', prepare_data(LINESTYLES, line.get_linestyle())),
|
||||
('Draw style', prepare_data(DRAWSTYLES, line.get_drawstyle())),
|
||||
('Width', line.get_linewidth()),
|
||||
('Color (RGBA)', color),
|
||||
sep,
|
||||
(None, '<b>Marker</b>'),
|
||||
('Style', prepare_data(MARKERS, line.get_marker())),
|
||||
('Size', line.get_markersize()),
|
||||
('Face color (RGBA)', fc),
|
||||
('Edge color (RGBA)', ec)]
|
||||
curves.append([curvedata, label, ""])
|
||||
# Is there a curve displayed?
|
||||
has_curve = bool(curves)
|
||||
|
||||
# Get ScalarMappables.
|
||||
mappabledict = {}
|
||||
for mappable in [*axes.images, *axes.collections]:
|
||||
label = mappable.get_label()
|
||||
if label == '_nolegend_' or mappable.get_array() is None:
|
||||
continue
|
||||
mappabledict[label] = mappable
|
||||
mappablelabels = sorted(mappabledict, key=cmp_key)
|
||||
mappables = []
|
||||
cmaps = [(cmap, name) for name, cmap in sorted(cm.cmap_d.items())]
|
||||
for label in mappablelabels:
|
||||
mappable = mappabledict[label]
|
||||
cmap = mappable.get_cmap()
|
||||
if cmap not in cm.cmap_d.values():
|
||||
cmaps = [(cmap, cmap.name), *cmaps]
|
||||
low, high = mappable.get_clim()
|
||||
mappabledata = [
|
||||
('Label', label),
|
||||
('Colormap', [cmap.name] + cmaps),
|
||||
('Min. value', low),
|
||||
('Max. value', high),
|
||||
]
|
||||
if hasattr(mappable, "get_interpolation"): # Images.
|
||||
interpolations = [
|
||||
(name, name) for name in sorted(mimage.interpolations_names)]
|
||||
mappabledata.append((
|
||||
'Interpolation',
|
||||
[mappable.get_interpolation(), *interpolations]))
|
||||
mappables.append([mappabledata, label, ""])
|
||||
# Is there a scalarmappable displayed?
|
||||
has_sm = bool(mappables)
|
||||
|
||||
datalist = [(general, "Axes", "")]
|
||||
if curves:
|
||||
datalist.append((curves, "Curves", ""))
|
||||
if mappables:
|
||||
datalist.append((mappables, "Images, etc.", ""))
|
||||
|
||||
def apply_callback(data):
|
||||
"""This function will be called to apply changes"""
|
||||
orig_xlim = axes.get_xlim()
|
||||
orig_ylim = axes.get_ylim()
|
||||
|
||||
general = data.pop(0)
|
||||
curves = data.pop(0) if has_curve else []
|
||||
mappables = data.pop(0) if has_sm else []
|
||||
if data:
|
||||
raise ValueError("Unexpected field")
|
||||
|
||||
# Set / General
|
||||
(title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale,
|
||||
generate_legend) = general
|
||||
|
||||
if axes.get_xscale() != xscale:
|
||||
axes.set_xscale(xscale)
|
||||
if axes.get_yscale() != yscale:
|
||||
axes.set_yscale(yscale)
|
||||
|
||||
axes.set_title(title)
|
||||
axes.set_xlim(xmin, xmax)
|
||||
axes.set_xlabel(xlabel)
|
||||
axes.set_ylim(ymin, ymax)
|
||||
axes.set_ylabel(ylabel)
|
||||
|
||||
# Restore the unit data
|
||||
axes.xaxis.converter = xconverter
|
||||
axes.yaxis.converter = yconverter
|
||||
axes.xaxis.set_units(xunits)
|
||||
axes.yaxis.set_units(yunits)
|
||||
axes.xaxis._update_axisinfo()
|
||||
axes.yaxis._update_axisinfo()
|
||||
|
||||
# Set / Curves
|
||||
for index, curve in enumerate(curves):
|
||||
line = linedict[curvelabels[index]]
|
||||
(label, linestyle, drawstyle, linewidth, color, marker, markersize,
|
||||
markerfacecolor, markeredgecolor) = curve
|
||||
line.set_label(label)
|
||||
line.set_linestyle(linestyle)
|
||||
line.set_drawstyle(drawstyle)
|
||||
line.set_linewidth(linewidth)
|
||||
rgba = mcolors.to_rgba(color)
|
||||
line.set_alpha(None)
|
||||
line.set_color(rgba)
|
||||
if marker != 'none':
|
||||
line.set_marker(marker)
|
||||
line.set_markersize(markersize)
|
||||
line.set_markerfacecolor(markerfacecolor)
|
||||
line.set_markeredgecolor(markeredgecolor)
|
||||
|
||||
# Set ScalarMappables.
|
||||
for index, mappable_settings in enumerate(mappables):
|
||||
mappable = mappabledict[mappablelabels[index]]
|
||||
if len(mappable_settings) == 5:
|
||||
label, cmap, low, high, interpolation = mappable_settings
|
||||
mappable.set_interpolation(interpolation)
|
||||
elif len(mappable_settings) == 4:
|
||||
label, cmap, low, high = mappable_settings
|
||||
mappable.set_label(label)
|
||||
mappable.set_cmap(cm.get_cmap(cmap))
|
||||
mappable.set_clim(*sorted([low, high]))
|
||||
|
||||
# re-generate legend, if checkbox is checked
|
||||
if generate_legend:
|
||||
draggable = None
|
||||
ncol = 1
|
||||
if axes.legend_ is not None:
|
||||
old_legend = axes.get_legend()
|
||||
draggable = old_legend._draggable is not None
|
||||
ncol = old_legend._ncol
|
||||
new_legend = axes.legend(ncol=ncol)
|
||||
if new_legend:
|
||||
new_legend.set_draggable(draggable)
|
||||
|
||||
# Redraw
|
||||
figure = axes.get_figure()
|
||||
figure.canvas.draw()
|
||||
if not (axes.get_xlim() == orig_xlim and axes.get_ylim() == orig_ylim):
|
||||
figure.canvas.toolbar.push_current()
|
||||
|
||||
data = _formlayout.fedit(datalist, title="Figure options", parent=parent,
|
||||
icon=get_icon('qt4_editor_options.svg'),
|
||||
apply=apply_callback)
|
||||
if data is not None:
|
||||
apply_callback(data)
|
||||
7
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/formlayout.py
vendored
Normal file
7
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/formlayout.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
from .. import cbook
|
||||
from ._formlayout import *
|
||||
|
||||
|
||||
cbook.warn_deprecated(
|
||||
"3.1", name=__name__, obj_type="module",
|
||||
alternative="the formlayout module available on PyPI")
|
||||
56
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/formsubplottool.py
vendored
Normal file
56
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/qt_editor/formsubplottool.py
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
from matplotlib.backends.qt_compat import QtWidgets
|
||||
|
||||
|
||||
class UiSubplotTool(QtWidgets.QDialog):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.setObjectName("SubplotTool")
|
||||
self._widgets = {}
|
||||
|
||||
layout = QtWidgets.QHBoxLayout()
|
||||
self.setLayout(layout)
|
||||
|
||||
left = QtWidgets.QVBoxLayout()
|
||||
layout.addLayout(left)
|
||||
right = QtWidgets.QVBoxLayout()
|
||||
layout.addLayout(right)
|
||||
|
||||
box = QtWidgets.QGroupBox("Borders")
|
||||
left.addWidget(box)
|
||||
inner = QtWidgets.QFormLayout(box)
|
||||
for side in ["top", "bottom", "left", "right"]:
|
||||
self._widgets[side] = widget = QtWidgets.QDoubleSpinBox()
|
||||
widget.setMinimum(0)
|
||||
widget.setMaximum(1)
|
||||
widget.setDecimals(3)
|
||||
widget.setSingleStep(.005)
|
||||
widget.setKeyboardTracking(False)
|
||||
inner.addRow(side, widget)
|
||||
left.addStretch(1)
|
||||
|
||||
box = QtWidgets.QGroupBox("Spacings")
|
||||
right.addWidget(box)
|
||||
inner = QtWidgets.QFormLayout(box)
|
||||
for side in ["hspace", "wspace"]:
|
||||
self._widgets[side] = widget = QtWidgets.QDoubleSpinBox()
|
||||
widget.setMinimum(0)
|
||||
widget.setMaximum(1)
|
||||
widget.setDecimals(3)
|
||||
widget.setSingleStep(.005)
|
||||
widget.setKeyboardTracking(False)
|
||||
inner.addRow(side, widget)
|
||||
right.addStretch(1)
|
||||
|
||||
widget = QtWidgets.QPushButton("Export values")
|
||||
self._widgets["Export values"] = widget
|
||||
# Don't trigger on <enter>, which is used to input values.
|
||||
widget.setAutoDefault(False)
|
||||
left.addWidget(widget)
|
||||
|
||||
for action in ["Tight layout", "Reset", "Close"]:
|
||||
self._widgets[action] = widget = QtWidgets.QPushButton(action)
|
||||
widget.setAutoDefault(False)
|
||||
right.addWidget(widget)
|
||||
|
||||
self._widgets["Close"].setFocus()
|
||||
47
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/tkagg.py
vendored
Normal file
47
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/tkagg.py
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import tkinter as tk
|
||||
|
||||
import numpy as np
|
||||
|
||||
from matplotlib import cbook
|
||||
from matplotlib.backends import _tkagg
|
||||
|
||||
|
||||
cbook.warn_deprecated("3.0", name=__name__, obj_type="module")
|
||||
|
||||
|
||||
def blit(photoimage, aggimage, bbox=None, colormode=1):
|
||||
tk = photoimage.tk
|
||||
|
||||
if bbox is not None:
|
||||
bbox_array = bbox.__array__()
|
||||
# x1, x2, y1, y2
|
||||
bboxptr = (bbox_array[0, 0], bbox_array[1, 0],
|
||||
bbox_array[0, 1], bbox_array[1, 1])
|
||||
else:
|
||||
bboxptr = 0
|
||||
data = np.asarray(aggimage)
|
||||
dataptr = (data.shape[0], data.shape[1], data.ctypes.data)
|
||||
try:
|
||||
tk.call(
|
||||
"PyAggImagePhoto", photoimage,
|
||||
dataptr, colormode, bboxptr)
|
||||
except tk.TclError:
|
||||
if hasattr(tk, 'interpaddr'):
|
||||
_tkagg.tkinit(tk.interpaddr(), 1)
|
||||
else:
|
||||
# very old python?
|
||||
_tkagg.tkinit(tk, 0)
|
||||
tk.call("PyAggImagePhoto", photoimage,
|
||||
dataptr, colormode, bboxptr)
|
||||
|
||||
|
||||
def test(aggimage):
|
||||
r = tk.Tk()
|
||||
c = tk.Canvas(r, width=aggimage.width, height=aggimage.height)
|
||||
c.pack()
|
||||
p = tk.PhotoImage(width=aggimage.width, height=aggimage.height)
|
||||
blit(p, aggimage)
|
||||
c.create_image(aggimage.width, aggimage.height, image=p)
|
||||
blit(p, aggimage)
|
||||
while True:
|
||||
r.update_idletasks()
|
||||
43
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/all_figures.html
vendored
Normal file
43
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/all_figures.html
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{ prefix }}/_static/css/page.css" type="text/css">
|
||||
<link rel="stylesheet" href="{{ prefix }}/_static/css/boilerplate.css" type="text/css" />
|
||||
<link rel="stylesheet" href="{{ prefix }}/_static/css/fbm.css" type="text/css" />
|
||||
<link rel="stylesheet" href="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.css" >
|
||||
<script src="{{ prefix }}/_static/jquery-ui-1.12.1/external/jquery/jquery.js"></script>
|
||||
<script src="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.js"></script>
|
||||
<script src="{{ prefix }}/_static/js/mpl_tornado.js"></script>
|
||||
<script src="{{ prefix }}/js/mpl.js"></script>
|
||||
|
||||
<script>
|
||||
{% for (fig_id, fig_manager) in figures %}
|
||||
$(document).ready(
|
||||
function() {
|
||||
var main_div = $('div#figures');
|
||||
var figure_div = $('<div id="figure-div"/>')
|
||||
main_div.append(figure_div);
|
||||
var websocket_type = mpl.get_websocket_type();
|
||||
var websocket = new websocket_type(
|
||||
"{{ ws_uri }}" + "{{ fig_id }}" + "/ws");
|
||||
var fig = new mpl.figure(
|
||||
"{{ fig_id }}", websocket, mpl_ondownload, figure_div);
|
||||
|
||||
fig.focus_on_mouseover = true;
|
||||
|
||||
$(fig.canvas).attr('tabindex', {{ fig_id }});
|
||||
}
|
||||
);
|
||||
|
||||
{% end %}
|
||||
</script>
|
||||
|
||||
<title>MPL | WebAgg current figures</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="mpl-warnings" class="mpl-warnings"></div>
|
||||
|
||||
<div id="figures" style="margin: 10px 10px;"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
77
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/css/boilerplate.css
vendored
Normal file
77
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/css/boilerplate.css
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* HTML5 ✰ Boilerplate
|
||||
*
|
||||
* style.css contains a reset, font normalization and some base styles.
|
||||
*
|
||||
* Credit is left where credit is due.
|
||||
* Much inspiration was taken from these projects:
|
||||
* - yui.yahooapis.com/2.8.1/build/base/base.css
|
||||
* - camendesign.com/design/
|
||||
* - praegnanz.de/weblog/htmlcssjs-kickstart
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
|
||||
* v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
|
||||
* html5doctor.com/html-5-reset-stylesheet/
|
||||
*/
|
||||
|
||||
html, body, div, span, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
|
||||
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup { vertical-align: super; }
|
||||
sub { vertical-align: sub; }
|
||||
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
blockquote, q { quotes: none; }
|
||||
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after { content: ""; content: none; }
|
||||
|
||||
ins { background-color: #ff9; color: #000; text-decoration: none; }
|
||||
|
||||
mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
|
||||
|
||||
del { text-decoration: line-through; }
|
||||
|
||||
abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
|
||||
|
||||
table { border-collapse: collapse; border-spacing: 0; }
|
||||
|
||||
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
|
||||
|
||||
input, select { vertical-align: middle; }
|
||||
|
||||
|
||||
/**
|
||||
* Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
|
||||
*/
|
||||
|
||||
body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
|
||||
select, input, textarea, button { font:99% sans-serif; }
|
||||
|
||||
/* Normalize monospace sizing:
|
||||
en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
|
||||
pre, code, kbd, samp { font-family: monospace, sans-serif; }
|
||||
|
||||
em,i { font-style: italic; }
|
||||
b,strong { font-weight: bold; }
|
||||
97
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/css/fbm.css
vendored
Normal file
97
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/css/fbm.css
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
/* Flexible box model classes */
|
||||
/* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
|
||||
|
||||
.hbox {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-align: stretch;
|
||||
|
||||
display: -moz-box;
|
||||
-moz-box-orient: horizontal;
|
||||
-moz-box-align: stretch;
|
||||
|
||||
display: box;
|
||||
box-orient: horizontal;
|
||||
box-align: stretch;
|
||||
}
|
||||
|
||||
.hbox > * {
|
||||
-webkit-box-flex: 0;
|
||||
-moz-box-flex: 0;
|
||||
box-flex: 0;
|
||||
}
|
||||
|
||||
.vbox {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-align: stretch;
|
||||
|
||||
display: -moz-box;
|
||||
-moz-box-orient: vertical;
|
||||
-moz-box-align: stretch;
|
||||
|
||||
display: box;
|
||||
box-orient: vertical;
|
||||
box-align: stretch;
|
||||
}
|
||||
|
||||
.vbox > * {
|
||||
-webkit-box-flex: 0;
|
||||
-moz-box-flex: 0;
|
||||
box-flex: 0;
|
||||
}
|
||||
|
||||
.reverse {
|
||||
-webkit-box-direction: reverse;
|
||||
-moz-box-direction: reverse;
|
||||
box-direction: reverse;
|
||||
}
|
||||
|
||||
.box-flex0 {
|
||||
-webkit-box-flex: 0;
|
||||
-moz-box-flex: 0;
|
||||
box-flex: 0;
|
||||
}
|
||||
|
||||
.box-flex1, .box-flex {
|
||||
-webkit-box-flex: 1;
|
||||
-moz-box-flex: 1;
|
||||
box-flex: 1;
|
||||
}
|
||||
|
||||
.box-flex2 {
|
||||
-webkit-box-flex: 2;
|
||||
-moz-box-flex: 2;
|
||||
box-flex: 2;
|
||||
}
|
||||
|
||||
.box-group1 {
|
||||
-webkit-box-flex-group: 1;
|
||||
-moz-box-flex-group: 1;
|
||||
box-flex-group: 1;
|
||||
}
|
||||
|
||||
.box-group2 {
|
||||
-webkit-box-flex-group: 2;
|
||||
-moz-box-flex-group: 2;
|
||||
box-flex-group: 2;
|
||||
}
|
||||
|
||||
.start {
|
||||
-webkit-box-pack: start;
|
||||
-moz-box-pack: start;
|
||||
box-pack: start;
|
||||
}
|
||||
|
||||
.end {
|
||||
-webkit-box-pack: end;
|
||||
-moz-box-pack: end;
|
||||
box-pack: end;
|
||||
}
|
||||
|
||||
.center {
|
||||
-webkit-box-pack: center;
|
||||
-moz-box-pack: center;
|
||||
box-pack: center;
|
||||
}
|
||||
82
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/css/page.css
vendored
Normal file
82
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/css/page.css
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Primary styles
|
||||
*
|
||||
* Author: IPython Development Team
|
||||
*/
|
||||
|
||||
|
||||
body {
|
||||
background-color: white;
|
||||
/* This makes sure that the body covers the entire window and needs to
|
||||
be in a different element than the display: box in wrapper below */
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
|
||||
div#header {
|
||||
/* Initially hidden to prevent FLOUC */
|
||||
display: none;
|
||||
position: relative;
|
||||
height: 40px;
|
||||
padding: 5px;
|
||||
margin: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
span#ipython_notebook {
|
||||
position: absolute;
|
||||
padding: 2px 2px 2px 5px;
|
||||
}
|
||||
|
||||
span#ipython_notebook img {
|
||||
font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
|
||||
height: 24px;
|
||||
text-decoration:none;
|
||||
display: inline;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#site {
|
||||
width: 100%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* We set the fonts by hand here to override the values in the theme */
|
||||
.ui-widget {
|
||||
font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button {
|
||||
font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
/* Smaller buttons */
|
||||
.ui-button .ui-button-text {
|
||||
padding: 0.2em 0.8em;
|
||||
font-size: 77%;
|
||||
}
|
||||
|
||||
input.ui-button {
|
||||
padding: 0.3em 0.9em;
|
||||
}
|
||||
|
||||
span#login_widget {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.border-box-sizing {
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
}
|
||||
|
||||
#figure-div {
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<!-- Within the kernel, we don't know the address of the matplotlib
|
||||
websocket server, so we have to get in client-side and fetch our
|
||||
resources that way. -->
|
||||
<script>
|
||||
// We can't proceed until these Javascript files are fetched, so
|
||||
// we fetch them synchronously
|
||||
$.ajaxSetup({async: false});
|
||||
$.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/_static/js/mpl_tornado.js");
|
||||
$.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/js/mpl.js");
|
||||
$.ajaxSetup({async: true});
|
||||
|
||||
function init_figure{{ fig_id }}(e) {
|
||||
$('div.output').off('resize');
|
||||
|
||||
var output_div = $(e.target).find('div.output_subarea');
|
||||
var websocket_type = mpl.get_websocket_type();
|
||||
var websocket = new websocket_type(
|
||||
"ws://" + window.location.hostname + ":{{ port }}{{ prefix}}/" +
|
||||
{{ repr(str(fig_id)) }} + "/ws");
|
||||
|
||||
var fig = new mpl.figure(
|
||||
{{repr(str(fig_id))}}, websocket, mpl_ondownload, output_div);
|
||||
|
||||
// Fetch the first image
|
||||
fig.context.drawImage(fig.imageObj, 0, 0);
|
||||
|
||||
fig.focus_on_mouseover = true;
|
||||
}
|
||||
|
||||
// We can't initialize the figure contents until our content
|
||||
// has been added to the DOM. This is a bit of hack to get an
|
||||
// event for that.
|
||||
$('div.output').resize(init_figure{{ fig_id }});
|
||||
</script>
|
||||
@@ -0,0 +1,333 @@
|
||||
Authors ordered by first contribution
|
||||
A list of current team members is available at http://jqueryui.com/about
|
||||
|
||||
Paul Bakaus <paul.bakaus@gmail.com>
|
||||
Richard Worth <rdworth@gmail.com>
|
||||
Yehuda Katz <wycats@gmail.com>
|
||||
Sean Catchpole <sean@sunsean.com>
|
||||
John Resig <jeresig@gmail.com>
|
||||
Tane Piper <piper.tane@gmail.com>
|
||||
Dmitri Gaskin <dmitrig01@gmail.com>
|
||||
Klaus Hartl <klaus.hartl@gmail.com>
|
||||
Stefan Petre <stefan.petre@gmail.com>
|
||||
Gilles van den Hoven <gilles@webunity.nl>
|
||||
Micheil Bryan Smith <micheil@brandedcode.com>
|
||||
Jörn Zaefferer <joern.zaefferer@gmail.com>
|
||||
Marc Grabanski <m@marcgrabanski.com>
|
||||
Keith Wood <kbwood@iinet.com.au>
|
||||
Brandon Aaron <brandon.aaron@gmail.com>
|
||||
Scott González <scott.gonzalez@gmail.com>
|
||||
Eduardo Lundgren <eduardolundgren@gmail.com>
|
||||
Aaron Eisenberger <aaronchi@gmail.com>
|
||||
Joan Piedra <theneojp@gmail.com>
|
||||
Bruno Basto <b.basto@gmail.com>
|
||||
Remy Sharp <remy@leftlogic.com>
|
||||
Bohdan Ganicky <bohdan.ganicky@gmail.com>
|
||||
David Bolter <david.bolter@gmail.com>
|
||||
Chi Cheng <cloudream@gmail.com>
|
||||
Ca-Phun Ung <pazu2k@gmail.com>
|
||||
Ariel Flesler <aflesler@gmail.com>
|
||||
Maggie Wachs <maggie@filamentgroup.com>
|
||||
Scott Jehl <scottjehl@gmail.com>
|
||||
Todd Parker <todd@filamentgroup.com>
|
||||
Andrew Powell <andrew@shellscape.org>
|
||||
Brant Burnett <btburnett3@gmail.com>
|
||||
Douglas Neiner <doug@dougneiner.com>
|
||||
Paul Irish <paul.irish@gmail.com>
|
||||
Ralph Whitbeck <ralph.whitbeck@gmail.com>
|
||||
Thibault Duplessis <thibault.duplessis@gmail.com>
|
||||
Dominique Vincent <dominique.vincent@toitl.com>
|
||||
Jack Hsu <jack.hsu@gmail.com>
|
||||
Adam Sontag <ajpiano@ajpiano.com>
|
||||
Carl Fürstenberg <carl@excito.com>
|
||||
Kevin Dalman <development@allpro.net>
|
||||
Alberto Fernández Capel <afcapel@gmail.com>
|
||||
Jacek Jędrzejewski (http://jacek.jedrzejewski.name)
|
||||
Ting Kuei <ting@kuei.com>
|
||||
Samuel Cormier-Iijima <sam@chide.it>
|
||||
Jon Palmer <jonspalmer@gmail.com>
|
||||
Ben Hollis <bhollis@amazon.com>
|
||||
Justin MacCarthy <Justin@Rubystars.biz>
|
||||
Eyal Kobrigo <kobrigo@hotmail.com>
|
||||
Tiago Freire <tiago.freire@gmail.com>
|
||||
Diego Tres <diegotres@gmail.com>
|
||||
Holger Rüprich <holger@rueprich.de>
|
||||
Ziling Zhao <zilingzhao@gmail.com>
|
||||
Mike Alsup <malsup@gmail.com>
|
||||
Robson Braga Araujo <robsonbraga@gmail.com>
|
||||
Pierre-Henri Ausseil <ph.ausseil@gmail.com>
|
||||
Christopher McCulloh <cmcculloh@gmail.com>
|
||||
Andrew Newcomb <ext.github@preceptsoftware.co.uk>
|
||||
Lim Chee Aun <cheeaun@gmail.com>
|
||||
Jorge Barreiro <yortx.barry@gmail.com>
|
||||
Daniel Steigerwald <daniel@steigerwald.cz>
|
||||
John Firebaugh <john_firebaugh@bigfix.com>
|
||||
John Enters <github@darkdark.net>
|
||||
Andrey Kapitcyn <ru.m157y@gmail.com>
|
||||
Dmitry Petrov <dpetroff@gmail.com>
|
||||
Eric Hynds <eric@hynds.net>
|
||||
Chairat Sunthornwiphat <pipo@sixhead.com>
|
||||
Josh Varner <josh.varner@gmail.com>
|
||||
Stéphane Raimbault <stephane.raimbault@gmail.com>
|
||||
Jay Merrifield <fracmak@gmail.com>
|
||||
J. Ryan Stinnett <jryans@gmail.com>
|
||||
Peter Heiberg <peter@heiberg.se>
|
||||
Alex Dovenmuehle <adovenmuehle@gmail.com>
|
||||
Jamie Gegerson <git@jamiegegerson.com>
|
||||
Raymond Schwartz <skeetergraphics@gmail.com>
|
||||
Phillip Barnes <philbar@gmail.com>
|
||||
Kyle Wilkinson <kai@wikyd.org>
|
||||
Khaled AlHourani <me@khaledalhourani.com>
|
||||
Marian Rudzynski <mr@impaled.org>
|
||||
Jean-Francois Remy <jeff@melix.org>
|
||||
Doug Blood <dougblood@gmail.com>
|
||||
Filippo Cavallarin <filippo.cavallarin@codseq.it>
|
||||
Heiko Henning <heiko@thehennings.ch>
|
||||
Aliaksandr Rahalevich <saksmlz@gmail.com>
|
||||
Mario Visic <mario@mariovisic.com>
|
||||
Xavi Ramirez <xavi.rmz@gmail.com>
|
||||
Max Schnur <max.schnur@gmail.com>
|
||||
Saji Nediyanchath <saji89@gmail.com>
|
||||
Corey Frang <gnarf37@gmail.com>
|
||||
Aaron Peterson <aaronp123@yahoo.com>
|
||||
Ivan Peters <ivan@ivanpeters.com>
|
||||
Mohamed Cherif Bouchelaghem <cherifbouchelaghem@yahoo.fr>
|
||||
Marcos Sousa <falecomigo@marcossousa.com>
|
||||
Michael DellaNoce <mdellanoce@mailtrust.com>
|
||||
George Marshall <echosx@gmail.com>
|
||||
Tobias Brunner <tobias@strongswan.org>
|
||||
Martin Solli <msolli@gmail.com>
|
||||
David Petersen <public@petersendidit.com>
|
||||
Dan Heberden <danheberden@gmail.com>
|
||||
William Kevin Manire <williamkmanire@gmail.com>
|
||||
Gilmore Davidson <gilmoreorless@gmail.com>
|
||||
Michael Wu <michaelmwu@gmail.com>
|
||||
Adam Parod <mystic414@gmail.com>
|
||||
Guillaume Gautreau <guillaume+github@ghusse.com>
|
||||
Marcel Toele <EleotleCram@gmail.com>
|
||||
Dan Streetman <ddstreet@ieee.org>
|
||||
Matt Hoskins <matt@nipltd.com>
|
||||
Giovanni Giacobbi <giovanni@giacobbi.net>
|
||||
Kyle Florence <kyle.florence@gmail.com>
|
||||
Pavol Hluchý <lopo@losys.sk>
|
||||
Hans Hillen <hans.hillen@gmail.com>
|
||||
Mark Johnson <virgofx@live.com>
|
||||
Trey Hunner <treyhunner@gmail.com>
|
||||
Shane Whittet <whittet@gmail.com>
|
||||
Edward A Faulkner <ef@alum.mit.edu>
|
||||
Adam Baratz <adam@adambaratz.com>
|
||||
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
||||
Eike Send <eike.send@gmail.com>
|
||||
Kris Borchers <kris.borchers@gmail.com>
|
||||
Eddie Monge <eddie@eddiemonge.com>
|
||||
Israel Tsadok <itsadok@gmail.com>
|
||||
Carson McDonald <carson@ioncannon.net>
|
||||
Jason Davies <jason@jasondavies.com>
|
||||
Garrison Locke <gplocke@gmail.com>
|
||||
David Murdoch <david@davidmurdoch.com>
|
||||
Benjamin Scott Boyle <benjamins.boyle@gmail.com>
|
||||
Jesse Baird <jebaird@gmail.com>
|
||||
Jonathan Vingiano <jvingiano@gmail.com>
|
||||
Dylan Just <dev@ephox.com>
|
||||
Hiroshi Tomita <tomykaira@gmail.com>
|
||||
Glenn Goodrich <glenn.goodrich@gmail.com>
|
||||
Tarafder Ashek-E-Elahi <mail.ashek@gmail.com>
|
||||
Ryan Neufeld <ryan@neufeldmail.com>
|
||||
Marc Neuwirth <marc.neuwirth@gmail.com>
|
||||
Philip Graham <philip.robert.graham@gmail.com>
|
||||
Benjamin Sterling <benjamin.sterling@kenzomedia.com>
|
||||
Wesley Walser <waw325@gmail.com>
|
||||
Kouhei Sutou <kou@clear-code.com>
|
||||
Karl Kirch <karlkrch@gmail.com>
|
||||
Chris Kelly <ckdake@ckdake.com>
|
||||
Jason Oster <jay@kodewerx.org>
|
||||
Felix Nagel <info@felixnagel.com>
|
||||
Alexander Polomoshnov <alex.polomoshnov@gmail.com>
|
||||
David Leal <dgleal@gmail.com>
|
||||
Igor Milla <igor.fsp.milla@gmail.com>
|
||||
Dave Methvin <dave.methvin@gmail.com>
|
||||
Florian Gutmann <f.gutmann@chronimo.com>
|
||||
Marwan Al Jubeh <marwan.aljubeh@gmail.com>
|
||||
Milan Broum <midlis@googlemail.com>
|
||||
Sebastian Sauer <info@dynpages.de>
|
||||
Gaëtan Muller <m.gaetan89@gmail.com>
|
||||
Michel Weimerskirch <michel@weimerskirch.net>
|
||||
William Griffiths <william@ycymro.com>
|
||||
Stojce Slavkovski <stojce@gmail.com>
|
||||
David Soms <david.soms@gmail.com>
|
||||
David De Sloovere <david.desloovere@outlook.com>
|
||||
Michael P. Jung <michael.jung@terreon.de>
|
||||
Shannon Pekary <spekary@gmail.com>
|
||||
Dan Wellman <danwellman@hotmail.com>
|
||||
Matthew Edward Hutton <meh@corefiling.co.uk>
|
||||
James Khoury <james@jameskhoury.com>
|
||||
Rob Loach <robloach@gmail.com>
|
||||
Alberto Monteiro <betimbrasil@gmail.com>
|
||||
Alex Rhea <alex.rhea@gmail.com>
|
||||
Krzysztof Rosiński <rozwell69@gmail.com>
|
||||
Ryan Olton <oltonr@gmail.com>
|
||||
Genie <386@mail.com>
|
||||
Rick Waldron <waldron.rick@gmail.com>
|
||||
Ian Simpson <spoonlikesham@gmail.com>
|
||||
Lev Kitsis <spam4lev@gmail.com>
|
||||
TJ VanToll <tj.vantoll@gmail.com>
|
||||
Justin Domnitz <jdomnitz@gmail.com>
|
||||
Douglas Cerna <douglascerna@yahoo.com>
|
||||
Bert ter Heide <bertjh@hotmail.com>
|
||||
Jasvir Nagra <jasvir@gmail.com>
|
||||
Yuriy Khabarov <13real008@gmail.com>
|
||||
Harri Kilpiö <harri.kilpio@gmail.com>
|
||||
Lado Lomidze <lado.lomidze@gmail.com>
|
||||
Amir E. Aharoni <amir.aharoni@mail.huji.ac.il>
|
||||
Simon Sattes <simon.sattes@gmail.com>
|
||||
Jo Liss <joliss42@gmail.com>
|
||||
Guntupalli Karunakar <karunakarg@yahoo.com>
|
||||
Shahyar Ghobadpour <shahyar@gmail.com>
|
||||
Lukasz Lipinski <uzza17@gmail.com>
|
||||
Timo Tijhof <krinklemail@gmail.com>
|
||||
Jason Moon <jmoon@socialcast.com>
|
||||
Martin Frost <martinf55@hotmail.com>
|
||||
Eneko Illarramendi <eneko@illarra.com>
|
||||
EungJun Yi <semtlenori@gmail.com>
|
||||
Courtland Allen <courtlandallen@gmail.com>
|
||||
Viktar Varvanovich <non4eg@gmail.com>
|
||||
Danny Trunk <dtrunk90@gmail.com>
|
||||
Pavel Stetina <pavel.stetina@nangu.tv>
|
||||
Michael Stay <metaweta@gmail.com>
|
||||
Steven Roussey <sroussey@gmail.com>
|
||||
Michael Hollis <hollis21@gmail.com>
|
||||
Lee Rowlands <lee.rowlands@previousnext.com.au>
|
||||
Timmy Willison <timmywillisn@gmail.com>
|
||||
Karl Swedberg <kswedberg@gmail.com>
|
||||
Baoju Yuan <the_guy_1987@hotmail.com>
|
||||
Maciej Mroziński <maciej.k.mrozinski@gmail.com>
|
||||
Luis Dalmolin <luis.nh@gmail.com>
|
||||
Mark Aaron Shirley <maspwr@gmail.com>
|
||||
Martin Hoch <martin@fidion.de>
|
||||
Jiayi Yang <tr870829@gmail.com>
|
||||
Philipp Benjamin Köppchen <xgxtpbk@gws.ms>
|
||||
Sindre Sorhus <sindresorhus@gmail.com>
|
||||
Bernhard Sirlinger <bernhard.sirlinger@tele2.de>
|
||||
Jared A. Scheel <jared@jaredscheel.com>
|
||||
Rafael Xavier de Souza <rxaviers@gmail.com>
|
||||
John Chen <zhang.z.chen@intel.com>
|
||||
Robert Beuligmann <robertbeuligmann@gmail.com>
|
||||
Dale Kocian <dale.kocian@gmail.com>
|
||||
Mike Sherov <mike.sherov@gmail.com>
|
||||
Andrew Couch <andy@couchand.com>
|
||||
Marc-Andre Lafortune <github@marc-andre.ca>
|
||||
Nate Eagle <nate.eagle@teamaol.com>
|
||||
David Souther <davidsouther@gmail.com>
|
||||
Mathias Stenbom <mathias@stenbom.com>
|
||||
Sergey Kartashov <ebishkek@yandex.ru>
|
||||
Avinash R <nashpapa@gmail.com>
|
||||
Ethan Romba <ethanromba@gmail.com>
|
||||
Cory Gackenheimer <cory.gack@gmail.com>
|
||||
Juan Pablo Kaniefsky <jpkaniefsky@gmail.com>
|
||||
Roman Salnikov <bardt.dz@gmail.com>
|
||||
Anika Henke <anika@selfthinker.org>
|
||||
Samuel Bovée <samycookie2000@yahoo.fr>
|
||||
Fabrício Matté <ult_combo@hotmail.com>
|
||||
Viktor Kojouharov <vkojouharov@gmail.com>
|
||||
Pawel Maruszczyk (http://hrabstwo.net)
|
||||
Pavel Selitskas <p.selitskas@gmail.com>
|
||||
Bjørn Johansen <post@bjornjohansen.no>
|
||||
Matthieu Penant <thieum22@hotmail.com>
|
||||
Dominic Barnes <dominic@dbarnes.info>
|
||||
David Sullivan <david.sullivan@gmail.com>
|
||||
Thomas Jaggi <thomas@responsive.ch>
|
||||
Vahid Sohrabloo <vahid4134@gmail.com>
|
||||
Travis Carden <travis.carden@gmail.com>
|
||||
Bruno M. Custódio <bruno@brunomcustodio.com>
|
||||
Nathanael Silverman <nathanael.silverman@gmail.com>
|
||||
Christian Wenz <christian@wenz.org>
|
||||
Steve Urmston <steve@urm.st>
|
||||
Zaven Muradyan <megalivoithos@gmail.com>
|
||||
Woody Gilk <shadowhand@deviantart.com>
|
||||
Zbigniew Motyka <zbigniew.motyka@gmail.com>
|
||||
Suhail Alkowaileet <xsoh.k7@gmail.com>
|
||||
Toshi MARUYAMA <marutosijp2@yahoo.co.jp>
|
||||
David Hansen <hansede@gmail.com>
|
||||
Brian Grinstead <briangrinstead@gmail.com>
|
||||
Christian Klammer <christian314159@gmail.com>
|
||||
Steven Luscher <jquerycla@steveluscher.com>
|
||||
Gan Eng Chin <engchin.gan@gmail.com>
|
||||
Gabriel Schulhof <gabriel.schulhof@intel.com>
|
||||
Alexander Schmitz <arschmitz@gmail.com>
|
||||
Vilhjálmur Skúlason <vis@dmm.is>
|
||||
Siebrand Mazeland <siebrand@kitano.nl>
|
||||
Mohsen Ekhtiari <mohsenekhtiari@yahoo.com>
|
||||
Pere Orga <gotrunks@gmail.com>
|
||||
Jasper de Groot <mail@ugomobi.com>
|
||||
Stephane Deschamps <stephane.deschamps@gmail.com>
|
||||
Jyoti Deka <dekajp@gmail.com>
|
||||
Andrei Picus <office.nightcrawler@gmail.com>
|
||||
Ondrej Novy <novy@ondrej.org>
|
||||
Jacob McCutcheon <jacob.mccutcheon@gmail.com>
|
||||
Monika Piotrowicz <monika.piotrowicz@gmail.com>
|
||||
Imants Horsts <imants.horsts@inbox.lv>
|
||||
Eric Dahl <eric.c.dahl@gmail.com>
|
||||
Dave Stein <dave@behance.com>
|
||||
Dylan Barrell <dylan@barrell.com>
|
||||
Daniel DeGroff <djdegroff@gmail.com>
|
||||
Michael Wiencek <mwtuea@gmail.com>
|
||||
Thomas Meyer <meyertee@gmail.com>
|
||||
Ruslan Yakhyaev <ruslan@ruslan.io>
|
||||
Brian J. Dowling <bjd-dev@simplicity.net>
|
||||
Ben Higgins <ben@extrahop.com>
|
||||
Yermo Lamers <yml@yml.com>
|
||||
Patrick Stapleton <github@gdi2290.com>
|
||||
Trisha Crowley <trisha.crowley@gmail.com>
|
||||
Usman Akeju <akeju00+github@gmail.com>
|
||||
Rodrigo Menezes <rod333@gmail.com>
|
||||
Jacques Perrault <jacques_perrault@us.ibm.com>
|
||||
Frederik Elvhage <frederik.elvhage@googlemail.com>
|
||||
Will Holley <willholley@gmail.com>
|
||||
Uri Gilad <antishok@gmail.com>
|
||||
Richard Gibson <richard.gibson@gmail.com>
|
||||
Simen Bekkhus <sbekkhus91@gmail.com>
|
||||
Chen Eshchar <eshcharc@gmail.com>
|
||||
Bruno Pérel <brunoperel@gmail.com>
|
||||
Mohammed Alshehri <m@dralshehri.com>
|
||||
Lisa Seacat DeLuca <ldeluca@us.ibm.com>
|
||||
Anne-Gaelle Colom <coloma@westminster.ac.uk>
|
||||
Adam Foster <slimfoster@gmail.com>
|
||||
Luke Page <luke.a.page@gmail.com>
|
||||
Daniel Owens <daniel@matchstickmixup.com>
|
||||
Michael Orchard <morchard@scottlogic.co.uk>
|
||||
Marcus Warren <marcus@envoke.com>
|
||||
Nils Heuermann <nils@world-of-scripts.de>
|
||||
Marco Ziech <marco@ziech.net>
|
||||
Patricia Juarez <patrixd@gmail.com>
|
||||
Ben Mosher <me@benmosher.com>
|
||||
Ablay Keldibek <atomio.ak@gmail.com>
|
||||
Thomas Applencourt <thomas.applencourt@irsamc.ups-tlse.fr>
|
||||
Jiabao Wu <jiabao.foss@gmail.com>
|
||||
Eric Lee Carraway <github@ericcarraway.com>
|
||||
Victor Homyakov <vkhomyackov@gmail.com>
|
||||
Myeongjin Lee <aranet100@gmail.com>
|
||||
Liran Sharir <lsharir@gmail.com>
|
||||
Weston Ruter <weston@xwp.co>
|
||||
Mani Mishra <manimishra902@gmail.com>
|
||||
Hannah Methvin <hannahmethvin@gmail.com>
|
||||
Leonardo Balter <leonardo.balter@gmail.com>
|
||||
Benjamin Albert <benjamin_a5@yahoo.com>
|
||||
Michał Gołębiowski <m.goleb@gmail.com>
|
||||
Alyosha Pushak <alyosha.pushak@gmail.com>
|
||||
Fahad Ahmad <fahadahmad41@hotmail.com>
|
||||
Matt Brundage <github@mattbrundage.com>
|
||||
Francesc Baeta <francesc.baeta@gmail.com>
|
||||
Piotr Baran <piotros@wp.pl>
|
||||
Mukul Hase <mukulhase@gmail.com>
|
||||
Konstantin Dinev <kdinev@mail.bw.edu>
|
||||
Rand Scullard <rand@randscullard.com>
|
||||
Dan Strohl <dan@wjcg.net>
|
||||
Maksim Ryzhikov <rv.maksim@gmail.com>
|
||||
Amine HADDAD <haddad@allegorie.tv>
|
||||
Amanpreet Singh <apsdehal@gmail.com>
|
||||
Alexey Balchunas <bleshik@gmail.com>
|
||||
Peter Kehl <peter.kehl@gmail.com>
|
||||
Peter Dave Hello <hsu@peterdavehello.org>
|
||||
Johannes Schäfer <johnschaefer@gmx.de>
|
||||
Ville Skyttä <ville.skytta@iki.fi>
|
||||
Ryan Oriecuia <ryan.oriecuia@visioncritical.com>
|
||||
@@ -0,0 +1,43 @@
|
||||
Copyright jQuery Foundation and other contributors, https://jquery.org/
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals. For exact contribution history, see the revision history
|
||||
available at https://github.com/jquery/jquery-ui
|
||||
|
||||
The following license applies to all parts of this software except as
|
||||
documented below:
|
||||
|
||||
====
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
====
|
||||
|
||||
Copyright and related rights for sample code are waived via CC0. Sample
|
||||
code is defined as all source code contained within the demos directory.
|
||||
|
||||
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
====
|
||||
|
||||
All files located in the node_modules and external directories are
|
||||
externally maintained libraries used by this software which have their
|
||||
own licenses; we recommend you read them, as their terms may differ from
|
||||
the terms above.
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
@@ -0,0 +1,559 @@
|
||||
<!doctype html>
|
||||
<html lang="us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Example Page</title>
|
||||
<link href="jquery-ui.css" rel="stylesheet">
|
||||
<style>
|
||||
body{
|
||||
font-family: "Trebuchet MS", sans-serif;
|
||||
margin: 50px;
|
||||
}
|
||||
.demoHeaders {
|
||||
margin-top: 2em;
|
||||
}
|
||||
#dialog-link {
|
||||
padding: .4em 1em .4em 20px;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
#dialog-link span.ui-icon {
|
||||
margin: 0 5px 0 0;
|
||||
position: absolute;
|
||||
left: .2em;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
#icons {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#icons li {
|
||||
margin: 2px;
|
||||
position: relative;
|
||||
padding: 4px 0;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
#icons span.ui-icon {
|
||||
float: left;
|
||||
margin: 0 4px;
|
||||
}
|
||||
.fakewindowcontain .ui-widget-overlay {
|
||||
position: absolute;
|
||||
}
|
||||
select {
|
||||
width: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Welcome to jQuery UI!</h1>
|
||||
|
||||
<div class="ui-widget">
|
||||
<p>This page demonstrates the widgets and theme you selected in Download Builder. Please make sure you are using them with a compatible jQuery version.</p>
|
||||
</div>
|
||||
|
||||
<h1>YOUR COMPONENTS:</h1>
|
||||
|
||||
|
||||
<!-- Accordion -->
|
||||
<h2 class="demoHeaders">Accordion</h2>
|
||||
<div id="accordion">
|
||||
<h3>First</h3>
|
||||
<div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
|
||||
<h3>Second</h3>
|
||||
<div>Phasellus mattis tincidunt nibh.</div>
|
||||
<h3>Third</h3>
|
||||
<div>Nam dui erat, auctor a, dignissim quis.</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Autocomplete -->
|
||||
<h2 class="demoHeaders">Autocomplete</h2>
|
||||
<div>
|
||||
<input id="autocomplete" title="type "a"">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Button -->
|
||||
<h2 class="demoHeaders">Button</h2>
|
||||
<button id="button">A button element</button>
|
||||
<button id="button-icon">An icon-only button</button>
|
||||
|
||||
|
||||
|
||||
<!-- Checkboxradio -->
|
||||
<h2 class="demoHeaders">Checkboxradio</h2>
|
||||
<form style="margin-top: 1em;">
|
||||
<div id="radioset">
|
||||
<input type="radio" id="radio1" name="radio"><label for="radio1">Choice 1</label>
|
||||
<input type="radio" id="radio2" name="radio" checked="checked"><label for="radio2">Choice 2</label>
|
||||
<input type="radio" id="radio3" name="radio"><label for="radio3">Choice 3</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<!-- Controlgroup -->
|
||||
<h2 class="demoHeaders">Controlgroup</h2>
|
||||
<fieldset>
|
||||
<legend>Rental Car</legend>
|
||||
<div id="controlgroup">
|
||||
<select id="car-type">
|
||||
<option>Compact car</option>
|
||||
<option>Midsize car</option>
|
||||
<option>Full size car</option>
|
||||
<option>SUV</option>
|
||||
<option>Luxury</option>
|
||||
<option>Truck</option>
|
||||
<option>Van</option>
|
||||
</select>
|
||||
<label for="transmission-standard">Standard</label>
|
||||
<input type="radio" name="transmission" id="transmission-standard">
|
||||
<label for="transmission-automatic">Automatic</label>
|
||||
<input type="radio" name="transmission" id="transmission-automatic">
|
||||
<label for="insurance">Insurance</label>
|
||||
<input type="checkbox" name="insurance" id="insurance">
|
||||
<label for="horizontal-spinner" class="ui-controlgroup-label"># of cars</label>
|
||||
<input id="horizontal-spinner" class="ui-spinner-input">
|
||||
<button>Book Now!</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
||||
|
||||
<!-- Tabs -->
|
||||
<h2 class="demoHeaders">Tabs</h2>
|
||||
<div id="tabs">
|
||||
<ul>
|
||||
<li><a href="#tabs-1">First</a></li>
|
||||
<li><a href="#tabs-2">Second</a></li>
|
||||
<li><a href="#tabs-3">Third</a></li>
|
||||
</ul>
|
||||
<div id="tabs-1">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
|
||||
<div id="tabs-2">Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.</div>
|
||||
<div id="tabs-3">Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h2 class="demoHeaders">Dialog</h2>
|
||||
<p>
|
||||
<button id="dialog-link" class="ui-button ui-corner-all ui-widget">
|
||||
<span class="ui-icon ui-icon-newwin"></span>Open Dialog
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<h2 class="demoHeaders">Overlay and Shadow Classes</h2>
|
||||
<div style="position: relative; width: 96%; height: 200px; padding:1% 2%; overflow:hidden;" class="fakewindowcontain">
|
||||
<p>Lorem ipsum dolor sit amet, Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. </p><p>Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. </p><p>Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. </p><p>Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. </p>
|
||||
|
||||
<!-- ui-dialog -->
|
||||
<div class="ui-widget-overlay ui-front"></div>
|
||||
<div style="position: absolute; width: 320px; left: 50px; top: 30px; padding: 1.2em" class="ui-widget ui-front ui-widget-content ui-corner-all ui-widget-shadow">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ui-dialog -->
|
||||
<div id="dialog" title="Dialog Title">
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h2 class="demoHeaders">Framework Icons (content color preview)</h2>
|
||||
<ul id="icons" class="ui-widget ui-helper-clearfix">
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-n"><span class="ui-icon ui-icon-caret-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-ne"><span class="ui-icon ui-icon-caret-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-e"><span class="ui-icon ui-icon-caret-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-se"><span class="ui-icon ui-icon-caret-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-s"><span class="ui-icon ui-icon-caret-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-sw"><span class="ui-icon ui-icon-caret-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-w"><span class="ui-icon ui-icon-caret-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-1-nw"><span class="ui-icon ui-icon-caret-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-2-n-s"><span class="ui-icon ui-icon-caret-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-caret-2-e-w"><span class="ui-icon ui-icon-caret-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-n"><span class="ui-icon ui-icon-triangle-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-ne"><span class="ui-icon ui-icon-triangle-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-e"><span class="ui-icon ui-icon-triangle-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-se"><span class="ui-icon ui-icon-triangle-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-s"><span class="ui-icon ui-icon-triangle-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-sw"><span class="ui-icon ui-icon-triangle-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-w"><span class="ui-icon ui-icon-triangle-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-nw"><span class="ui-icon ui-icon-triangle-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-n-s"><span class="ui-icon ui-icon-triangle-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-e-w"><span class="ui-icon ui-icon-triangle-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-n"><span class="ui-icon ui-icon-arrow-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-ne"><span class="ui-icon ui-icon-arrow-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-e"><span class="ui-icon ui-icon-arrow-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-se"><span class="ui-icon ui-icon-arrow-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-s"><span class="ui-icon ui-icon-arrow-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-sw"><span class="ui-icon ui-icon-arrow-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-w"><span class="ui-icon ui-icon-arrow-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-nw"><span class="ui-icon ui-icon-arrow-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-n-s"><span class="ui-icon ui-icon-arrow-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-ne-sw"><span class="ui-icon ui-icon-arrow-2-ne-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-e-w"><span class="ui-icon ui-icon-arrow-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-se-nw"><span class="ui-icon ui-icon-arrow-2-se-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-n"><span class="ui-icon ui-icon-arrowstop-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-e"><span class="ui-icon ui-icon-arrowstop-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-s"><span class="ui-icon ui-icon-arrowstop-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-w"><span class="ui-icon ui-icon-arrowstop-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-n"><span class="ui-icon ui-icon-arrowthick-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-ne"><span class="ui-icon ui-icon-arrowthick-1-ne"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-e"><span class="ui-icon ui-icon-arrowthick-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-se"><span class="ui-icon ui-icon-arrowthick-1-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-s"><span class="ui-icon ui-icon-arrowthick-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-sw"><span class="ui-icon ui-icon-arrowthick-1-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-w"><span class="ui-icon ui-icon-arrowthick-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-nw"><span class="ui-icon ui-icon-arrowthick-1-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-n-s"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-ne-sw"><span class="ui-icon ui-icon-arrowthick-2-ne-sw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-e-w"><span class="ui-icon ui-icon-arrowthick-2-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-se-nw"><span class="ui-icon ui-icon-arrowthick-2-se-nw"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-n"><span class="ui-icon ui-icon-arrowthickstop-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-e"><span class="ui-icon ui-icon-arrowthickstop-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-s"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-w"><span class="ui-icon ui-icon-arrowthickstop-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-w"><span class="ui-icon ui-icon-arrowreturnthick-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-n"><span class="ui-icon ui-icon-arrowreturnthick-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-e"><span class="ui-icon ui-icon-arrowreturnthick-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-s"><span class="ui-icon ui-icon-arrowreturnthick-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-w"><span class="ui-icon ui-icon-arrowreturn-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-n"><span class="ui-icon ui-icon-arrowreturn-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-e"><span class="ui-icon ui-icon-arrowreturn-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-s"><span class="ui-icon ui-icon-arrowreturn-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-w"><span class="ui-icon ui-icon-arrowrefresh-1-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-n"><span class="ui-icon ui-icon-arrowrefresh-1-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-e"><span class="ui-icon ui-icon-arrowrefresh-1-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-s"><span class="ui-icon ui-icon-arrowrefresh-1-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4"><span class="ui-icon ui-icon-arrow-4"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4-diag"><span class="ui-icon ui-icon-arrow-4-diag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-extlink"><span class="ui-icon ui-icon-extlink"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-newwin"><span class="ui-icon ui-icon-newwin"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-refresh"><span class="ui-icon ui-icon-refresh"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-shuffle"><span class="ui-icon ui-icon-shuffle"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-transfer-e-w"><span class="ui-icon ui-icon-transfer-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-transferthick-e-w"><span class="ui-icon ui-icon-transferthick-e-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-collapsed"><span class="ui-icon ui-icon-folder-collapsed"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-open"><span class="ui-icon ui-icon-folder-open"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-document"><span class="ui-icon ui-icon-document"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-document-b"><span class="ui-icon ui-icon-document-b"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-note"><span class="ui-icon ui-icon-note"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-mail-open"><span class="ui-icon ui-icon-mail-open"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-suitcase"><span class="ui-icon ui-icon-suitcase"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-comment"><span class="ui-icon ui-icon-comment"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-person"><span class="ui-icon ui-icon-person"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-print"><span class="ui-icon ui-icon-print"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-trash"><span class="ui-icon ui-icon-trash"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-locked"><span class="ui-icon ui-icon-locked"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-unlocked"><span class="ui-icon ui-icon-unlocked"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-bookmark"><span class="ui-icon ui-icon-bookmark"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-tag"><span class="ui-icon ui-icon-tag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-home"><span class="ui-icon ui-icon-home"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-flag"><span class="ui-icon ui-icon-flag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-calculator"><span class="ui-icon ui-icon-calculator"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-cart"><span class="ui-icon ui-icon-cart"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pencil"><span class="ui-icon ui-icon-pencil"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-clock"><span class="ui-icon ui-icon-clock"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-disk"><span class="ui-icon ui-icon-disk"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-calendar"><span class="ui-icon ui-icon-calendar"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-zoomin"><span class="ui-icon ui-icon-zoomin"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-zoomout"><span class="ui-icon ui-icon-zoomout"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-search"><span class="ui-icon ui-icon-search"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-wrench"><span class="ui-icon ui-icon-wrench"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-gear"><span class="ui-icon ui-icon-gear"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-heart"><span class="ui-icon ui-icon-heart"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-star"><span class="ui-icon ui-icon-star"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-link"><span class="ui-icon ui-icon-link"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-cancel"><span class="ui-icon ui-icon-cancel"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-plus"><span class="ui-icon ui-icon-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-minus"><span class="ui-icon ui-icon-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-minusthick"><span class="ui-icon ui-icon-minusthick"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-close"><span class="ui-icon ui-icon-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-closethick"><span class="ui-icon ui-icon-closethick"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-key"><span class="ui-icon ui-icon-key"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-lightbulb"><span class="ui-icon ui-icon-lightbulb"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-scissors"><span class="ui-icon ui-icon-scissors"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-clipboard"><span class="ui-icon ui-icon-clipboard"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-copy"><span class="ui-icon ui-icon-copy"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-contact"><span class="ui-icon ui-icon-contact"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-image"><span class="ui-icon ui-icon-image"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-video"><span class="ui-icon ui-icon-video"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-script"><span class="ui-icon ui-icon-script"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-alert"><span class="ui-icon ui-icon-alert"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-info"><span class="ui-icon ui-icon-info"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-notice"><span class="ui-icon ui-icon-notice"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-help"><span class="ui-icon ui-icon-help"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-bullet"><span class="ui-icon ui-icon-bullet"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-radio-off"><span class="ui-icon ui-icon-radio-off"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-radio-on"><span class="ui-icon ui-icon-radio-on"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pin-w"><span class="ui-icon ui-icon-pin-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pin-s"><span class="ui-icon ui-icon-pin-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-play"><span class="ui-icon ui-icon-play"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-pause"><span class="ui-icon ui-icon-pause"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-next"><span class="ui-icon ui-icon-seek-next"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-prev"><span class="ui-icon ui-icon-seek-prev"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-end"><span class="ui-icon ui-icon-seek-end"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-first"><span class="ui-icon ui-icon-seek-first"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-stop"><span class="ui-icon ui-icon-stop"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-eject"><span class="ui-icon ui-icon-eject"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-off"><span class="ui-icon ui-icon-volume-off"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-on"><span class="ui-icon ui-icon-volume-on"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-power"><span class="ui-icon ui-icon-power"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-signal-diag"><span class="ui-icon ui-icon-signal-diag"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-signal"><span class="ui-icon ui-icon-signal"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-0"><span class="ui-icon ui-icon-battery-0"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-1"><span class="ui-icon ui-icon-battery-1"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-2"><span class="ui-icon ui-icon-battery-2"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-3"><span class="ui-icon ui-icon-battery-3"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-plus"><span class="ui-icon ui-icon-circle-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-minus"><span class="ui-icon ui-icon-circle-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-close"><span class="ui-icon ui-icon-circle-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-e"><span class="ui-icon ui-icon-circle-triangle-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-s"><span class="ui-icon ui-icon-circle-triangle-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-w"><span class="ui-icon ui-icon-circle-triangle-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-n"><span class="ui-icon ui-icon-circle-triangle-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-e"><span class="ui-icon ui-icon-circle-arrow-e"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-s"><span class="ui-icon ui-icon-circle-arrow-s"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-w"><span class="ui-icon ui-icon-circle-arrow-w"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-n"><span class="ui-icon ui-icon-circle-arrow-n"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomin"><span class="ui-icon ui-icon-circle-zoomin"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomout"><span class="ui-icon ui-icon-circle-zoomout"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-check"><span class="ui-icon ui-icon-circle-check"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-plus"><span class="ui-icon ui-icon-circlesmall-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-minus"><span class="ui-icon ui-icon-circlesmall-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-close"><span class="ui-icon ui-icon-circlesmall-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-plus"><span class="ui-icon ui-icon-squaresmall-plus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-minus"><span class="ui-icon ui-icon-squaresmall-minus"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-close"><span class="ui-icon ui-icon-squaresmall-close"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-vertical"><span class="ui-icon ui-icon-grip-dotted-vertical"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-horizontal"><span class="ui-icon ui-icon-grip-dotted-horizontal"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-vertical"><span class="ui-icon ui-icon-grip-solid-vertical"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-horizontal"><span class="ui-icon ui-icon-grip-solid-horizontal"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-gripsmall-diagonal-se"><span class="ui-icon ui-icon-gripsmall-diagonal-se"></span></li>
|
||||
<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-diagonal-se"><span class="ui-icon ui-icon-grip-diagonal-se"></span></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Slider -->
|
||||
<h2 class="demoHeaders">Slider</h2>
|
||||
<div id="slider"></div>
|
||||
|
||||
|
||||
|
||||
<!-- Datepicker -->
|
||||
<h2 class="demoHeaders">Datepicker</h2>
|
||||
<div id="datepicker"></div>
|
||||
|
||||
|
||||
|
||||
<!-- Progressbar -->
|
||||
<h2 class="demoHeaders">Progressbar</h2>
|
||||
<div id="progressbar"></div>
|
||||
|
||||
|
||||
|
||||
<!-- Progressbar -->
|
||||
<h2 class="demoHeaders">Selectmenu</h2>
|
||||
<select id="selectmenu">
|
||||
<option>Slower</option>
|
||||
<option>Slow</option>
|
||||
<option selected="selected">Medium</option>
|
||||
<option>Fast</option>
|
||||
<option>Faster</option>
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
<!-- Spinner -->
|
||||
<h2 class="demoHeaders">Spinner</h2>
|
||||
<input id="spinner">
|
||||
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
<h2 class="demoHeaders">Menu</h2>
|
||||
<ul style="width:100px;" id="menu">
|
||||
<li><div>Item 1</div></li>
|
||||
<li><div>Item 2</div></li>
|
||||
<li><div>Item 3</div>
|
||||
<ul>
|
||||
<li><div>Item 3-1</div></li>
|
||||
<li><div>Item 3-2</div></li>
|
||||
<li><div>Item 3-3</div></li>
|
||||
<li><div>Item 3-4</div></li>
|
||||
<li><div>Item 3-5</div></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><div>Item 4</div></li>
|
||||
<li><div>Item 5</div></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<!-- Tooltip -->
|
||||
<h2 class="demoHeaders">Tooltip</h2>
|
||||
<p id="tooltip">
|
||||
<a href="#" title="That's what this widget is">Tooltips</a> can be attached to any element. When you hover
|
||||
the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- Highlight / Error -->
|
||||
<h2 class="demoHeaders">Highlight / Error</h2>
|
||||
<div class="ui-widget">
|
||||
<div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;">
|
||||
<p><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
|
||||
<strong>Hey!</strong> Sample ui-state-highlight style.</p>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="ui-widget">
|
||||
<div class="ui-state-error ui-corner-all" style="padding: 0 .7em;">
|
||||
<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>
|
||||
<strong>Alert:</strong> Sample ui-state-error style.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="external/jquery/jquery.js"></script>
|
||||
<script src="jquery-ui.js"></script>
|
||||
<script>
|
||||
|
||||
$( "#accordion" ).accordion();
|
||||
|
||||
|
||||
|
||||
var availableTags = [
|
||||
"ActionScript",
|
||||
"AppleScript",
|
||||
"Asp",
|
||||
"BASIC",
|
||||
"C",
|
||||
"C++",
|
||||
"Clojure",
|
||||
"COBOL",
|
||||
"ColdFusion",
|
||||
"Erlang",
|
||||
"Fortran",
|
||||
"Groovy",
|
||||
"Haskell",
|
||||
"Java",
|
||||
"JavaScript",
|
||||
"Lisp",
|
||||
"Perl",
|
||||
"PHP",
|
||||
"Python",
|
||||
"Ruby",
|
||||
"Scala",
|
||||
"Scheme"
|
||||
];
|
||||
$( "#autocomplete" ).autocomplete({
|
||||
source: availableTags
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#button" ).button();
|
||||
$( "#button-icon" ).button({
|
||||
icon: "ui-icon-gear",
|
||||
showLabel: false
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#radioset" ).buttonset();
|
||||
|
||||
|
||||
|
||||
$( "#controlgroup" ).controlgroup();
|
||||
|
||||
|
||||
|
||||
$( "#tabs" ).tabs();
|
||||
|
||||
|
||||
|
||||
$( "#dialog" ).dialog({
|
||||
autoOpen: false,
|
||||
width: 400,
|
||||
buttons: [
|
||||
{
|
||||
text: "Ok",
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Cancel",
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Link to open the dialog
|
||||
$( "#dialog-link" ).click(function( event ) {
|
||||
$( "#dialog" ).dialog( "open" );
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#datepicker" ).datepicker({
|
||||
inline: true
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#slider" ).slider({
|
||||
range: true,
|
||||
values: [ 17, 67 ]
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#progressbar" ).progressbar({
|
||||
value: 20
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#spinner" ).spinner();
|
||||
|
||||
|
||||
|
||||
$( "#menu" ).menu();
|
||||
|
||||
|
||||
|
||||
$( "#tooltip" ).tooltip();
|
||||
|
||||
|
||||
|
||||
$( "#selectmenu" ).selectmenu();
|
||||
|
||||
|
||||
// Hover states on the static widgets
|
||||
$( "#dialog-link, #icons li" ).hover(
|
||||
function() {
|
||||
$( this ).addClass( "ui-state-hover" );
|
||||
},
|
||||
function() {
|
||||
$( this ).removeClass( "ui-state-hover" );
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
18706
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/jquery-ui-1.12.1/jquery-ui.js
vendored
Normal file
18706
matPlotLib/env/lib/python3.7/site-packages/matplotlib/backends/web_backend/jquery-ui-1.12.1/jquery-ui.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,886 @@
|
||||
/*!
|
||||
* jQuery UI CSS Framework 1.12.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://api.jqueryui.com/category/theming/
|
||||
*/
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden {
|
||||
display: none;
|
||||
}
|
||||
.ui-helper-hidden-accessible {
|
||||
border: 0;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
.ui-helper-reset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
line-height: 1.3;
|
||||
text-decoration: none;
|
||||
font-size: 100%;
|
||||
list-style: none;
|
||||
}
|
||||
.ui-helper-clearfix:before,
|
||||
.ui-helper-clearfix:after {
|
||||
content: "";
|
||||
display: table;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.ui-helper-clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
.ui-helper-zfix {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
filter:Alpha(Opacity=0); /* support: IE8 */
|
||||
}
|
||||
|
||||
.ui-front {
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled {
|
||||
cursor: default !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
.ui-icon {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-top: -.25em;
|
||||
position: relative;
|
||||
text-indent: -99999px;
|
||||
overflow: hidden;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.ui-widget-icon-block {
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-accordion .ui-accordion-header {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
margin: 2px 0 0 0;
|
||||
padding: .5em .5em .5em .7em;
|
||||
font-size: 100%;
|
||||
}
|
||||
.ui-accordion .ui-accordion-content {
|
||||
padding: 1em 2.2em;
|
||||
border-top: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
.ui-autocomplete {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
cursor: default;
|
||||
}
|
||||
.ui-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
outline: 0;
|
||||
}
|
||||
.ui-menu .ui-menu {
|
||||
position: absolute;
|
||||
}
|
||||
.ui-menu .ui-menu-item {
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
/* support: IE10, see #8844 */
|
||||
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
||||
}
|
||||
.ui-menu .ui-menu-item-wrapper {
|
||||
position: relative;
|
||||
padding: 3px 1em 3px .4em;
|
||||
}
|
||||
.ui-menu .ui-menu-divider {
|
||||
margin: 5px 0;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
.ui-menu .ui-state-focus,
|
||||
.ui-menu .ui-state-active {
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons {
|
||||
position: relative;
|
||||
}
|
||||
.ui-menu-icons .ui-menu-item-wrapper {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: .2em;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
.ui-button {
|
||||
padding: .4em 1em;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
line-height: normal;
|
||||
margin-right: .1em;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
/* Support: IE <= 11 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.ui-button,
|
||||
.ui-button:link,
|
||||
.ui-button:visited,
|
||||
.ui-button:hover,
|
||||
.ui-button:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* to make room for the icon, a width needs to be set here */
|
||||
.ui-button-icon-only {
|
||||
width: 2em;
|
||||
box-sizing: border-box;
|
||||
text-indent: -9999px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* no icon support for input elements */
|
||||
input.ui-button.ui-button-icon-only {
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
/* button icon element(s) */
|
||||
.ui-button-icon-only .ui-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -8px;
|
||||
margin-left: -8px;
|
||||
}
|
||||
|
||||
.ui-button.ui-icon-notext .ui-icon {
|
||||
padding: 0;
|
||||
width: 2.1em;
|
||||
height: 2.1em;
|
||||
text-indent: -9999px;
|
||||
white-space: nowrap;
|
||||
|
||||
}
|
||||
|
||||
input.ui-button.ui-icon-notext .ui-icon {
|
||||
width: auto;
|
||||
height: auto;
|
||||
text-indent: 0;
|
||||
white-space: normal;
|
||||
padding: .4em 1em;
|
||||
}
|
||||
|
||||
/* workarounds */
|
||||
/* Support: Firefox 5 - 40 */
|
||||
input.ui-button::-moz-focus-inner,
|
||||
button.ui-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ui-controlgroup {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
.ui-controlgroup > .ui-controlgroup-item {
|
||||
float: left;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.ui-controlgroup > .ui-controlgroup-item:focus,
|
||||
.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
|
||||
z-index: 9999;
|
||||
}
|
||||
.ui-controlgroup-vertical > .ui-controlgroup-item {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-item {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.ui-controlgroup .ui-controlgroup-label {
|
||||
padding: .4em 1em;
|
||||
}
|
||||
.ui-controlgroup .ui-controlgroup-label span {
|
||||
font-size: 80%;
|
||||
}
|
||||
.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
|
||||
border-left: none;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
|
||||
border-top: none;
|
||||
}
|
||||
.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
|
||||
border-right: none;
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Spinner specific style fixes */
|
||||
.ui-controlgroup-vertical .ui-spinner-input {
|
||||
|
||||
/* Support: IE8 only, Android < 4.4 only */
|
||||
width: 75%;
|
||||
width: calc( 100% - 2.4em );
|
||||
}
|
||||
.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
|
||||
border-top-style: solid;
|
||||
}
|
||||
|
||||
.ui-checkboxradio-label .ui-icon-background {
|
||||
box-shadow: inset 1px 1px 1px #ccc;
|
||||
border-radius: .12em;
|
||||
border: none;
|
||||
}
|
||||
.ui-checkboxradio-radio-label .ui-icon-background {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 1em;
|
||||
overflow: visible;
|
||||
border: none;
|
||||
}
|
||||
.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
|
||||
.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
|
||||
background-image: none;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
}
|
||||
.ui-checkboxradio-disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
.ui-datepicker {
|
||||
width: 17em;
|
||||
padding: .2em .2em 0;
|
||||
display: none;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-header {
|
||||
position: relative;
|
||||
padding: .2em 0;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev,
|
||||
.ui-datepicker .ui-datepicker-next {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
width: 1.8em;
|
||||
height: 1.8em;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev-hover,
|
||||
.ui-datepicker .ui-datepicker-next-hover {
|
||||
top: 1px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev {
|
||||
left: 2px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-next {
|
||||
right: 2px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev-hover {
|
||||
left: 1px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-next-hover {
|
||||
right: 1px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev span,
|
||||
.ui-datepicker .ui-datepicker-next span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-title {
|
||||
margin: 0 2.3em;
|
||||
line-height: 1.8em;
|
||||
text-align: center;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-title select {
|
||||
font-size: 1em;
|
||||
margin: 1px 0;
|
||||
}
|
||||
.ui-datepicker select.ui-datepicker-month,
|
||||
.ui-datepicker select.ui-datepicker-year {
|
||||
width: 45%;
|
||||
}
|
||||
.ui-datepicker table {
|
||||
width: 100%;
|
||||
font-size: .9em;
|
||||
border-collapse: collapse;
|
||||
margin: 0 0 .4em;
|
||||
}
|
||||
.ui-datepicker th {
|
||||
padding: .7em .3em;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border: 0;
|
||||
}
|
||||
.ui-datepicker td {
|
||||
border: 0;
|
||||
padding: 1px;
|
||||
}
|
||||
.ui-datepicker td span,
|
||||
.ui-datepicker td a {
|
||||
display: block;
|
||||
padding: .2em;
|
||||
text-align: right;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-buttonpane {
|
||||
background-image: none;
|
||||
margin: .7em 0 0 0;
|
||||
padding: 0 .2em;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-buttonpane button {
|
||||
float: right;
|
||||
margin: .5em .2em .4em;
|
||||
cursor: pointer;
|
||||
padding: .2em .6em .3em .6em;
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* with multiple calendars */
|
||||
.ui-datepicker.ui-datepicker-multi {
|
||||
width: auto;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-group {
|
||||
float: left;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-group table {
|
||||
width: 95%;
|
||||
margin: 0 auto .4em;
|
||||
}
|
||||
.ui-datepicker-multi-2 .ui-datepicker-group {
|
||||
width: 50%;
|
||||
}
|
||||
.ui-datepicker-multi-3 .ui-datepicker-group {
|
||||
width: 33.3%;
|
||||
}
|
||||
.ui-datepicker-multi-4 .ui-datepicker-group {
|
||||
width: 25%;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
|
||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
|
||||
border-left-width: 0;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-buttonpane {
|
||||
clear: left;
|
||||
}
|
||||
.ui-datepicker-row-break {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
/* RTL support */
|
||||
.ui-datepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-prev {
|
||||
right: 2px;
|
||||
left: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-next {
|
||||
left: 2px;
|
||||
right: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-prev:hover {
|
||||
right: 1px;
|
||||
left: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-next:hover {
|
||||
left: 1px;
|
||||
right: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane {
|
||||
clear: right;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
|
||||
float: left;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
|
||||
.ui-datepicker-rtl .ui-datepicker-group {
|
||||
float: right;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
|
||||
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
|
||||
border-right-width: 0;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
.ui-datepicker .ui-icon {
|
||||
display: block;
|
||||
text-indent: -99999px;
|
||||
overflow: hidden;
|
||||
background-repeat: no-repeat;
|
||||
left: .5em;
|
||||
top: .3em;
|
||||
}
|
||||
.ui-dialog {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: .2em;
|
||||
outline: 0;
|
||||
}
|
||||
.ui-dialog .ui-dialog-titlebar {
|
||||
padding: .4em 1em;
|
||||
position: relative;
|
||||
}
|
||||
.ui-dialog .ui-dialog-title {
|
||||
float: left;
|
||||
margin: .1em 0;
|
||||
white-space: nowrap;
|
||||
width: 90%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.ui-dialog .ui-dialog-titlebar-close {
|
||||
position: absolute;
|
||||
right: .3em;
|
||||
top: 50%;
|
||||
width: 20px;
|
||||
margin: -10px 0 0 0;
|
||||
padding: 1px;
|
||||
height: 20px;
|
||||
}
|
||||
.ui-dialog .ui-dialog-content {
|
||||
position: relative;
|
||||
border: 0;
|
||||
padding: .5em 1em;
|
||||
background: none;
|
||||
overflow: auto;
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane {
|
||||
text-align: left;
|
||||
border-width: 1px 0 0 0;
|
||||
background-image: none;
|
||||
margin-top: .5em;
|
||||
padding: .3em 1em .5em .4em;
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
|
||||
float: right;
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane button {
|
||||
margin: .5em .4em .5em 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-dialog .ui-resizable-n {
|
||||
height: 2px;
|
||||
top: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-e {
|
||||
width: 2px;
|
||||
right: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-s {
|
||||
height: 2px;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-w {
|
||||
width: 2px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-se,
|
||||
.ui-dialog .ui-resizable-sw,
|
||||
.ui-dialog .ui-resizable-ne,
|
||||
.ui-dialog .ui-resizable-nw {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.ui-dialog .ui-resizable-se {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-sw {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-ne {
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ui-dialog .ui-resizable-nw {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.ui-draggable .ui-dialog-titlebar {
|
||||
cursor: move;
|
||||
}
|
||||
.ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable {
|
||||
position: relative;
|
||||
}
|
||||
.ui-resizable-handle {
|
||||
position: absolute;
|
||||
font-size: 0.1px;
|
||||
display: block;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-resizable-disabled .ui-resizable-handle,
|
||||
.ui-resizable-autohide .ui-resizable-handle {
|
||||
display: none;
|
||||
}
|
||||
.ui-resizable-n {
|
||||
cursor: n-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
top: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-resizable-s {
|
||||
cursor: s-resize;
|
||||
height: 7px;
|
||||
width: 100%;
|
||||
bottom: -5px;
|
||||
left: 0;
|
||||
}
|
||||
.ui-resizable-e {
|
||||
cursor: e-resize;
|
||||
width: 7px;
|
||||
right: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-w {
|
||||
cursor: w-resize;
|
||||
width: 7px;
|
||||
left: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-resizable-se {
|
||||
cursor: se-resize;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
right: 1px;
|
||||
bottom: 1px;
|
||||
}
|
||||
.ui-resizable-sw {
|
||||
cursor: sw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
bottom: -5px;
|
||||
}
|
||||
.ui-resizable-nw {
|
||||
cursor: nw-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
left: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-resizable-ne {
|
||||
cursor: ne-resize;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
}
|
||||
.ui-progressbar {
|
||||
height: 2em;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ui-progressbar .ui-progressbar-value {
|
||||
margin: -1px;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-progressbar .ui-progressbar-overlay {
|
||||
background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
|
||||
height: 100%;
|
||||
filter: alpha(opacity=25); /* support: IE8 */
|
||||
opacity: 0.25;
|
||||
}
|
||||
.ui-progressbar-indeterminate .ui-progressbar-value {
|
||||
background-image: none;
|
||||
}
|
||||
.ui-selectable {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-selectable-helper {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
border: 1px dotted black;
|
||||
}
|
||||
.ui-selectmenu-menu {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
}
|
||||
.ui-selectmenu-menu .ui-menu {
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
line-height: 1.5;
|
||||
padding: 2px 0.4em;
|
||||
margin: 0.5em 0 0 0;
|
||||
height: auto;
|
||||
border: 0;
|
||||
}
|
||||
.ui-selectmenu-open {
|
||||
display: block;
|
||||
}
|
||||
.ui-selectmenu-text {
|
||||
display: block;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.ui-selectmenu-button.ui-button {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
width: 14em;
|
||||
}
|
||||
.ui-selectmenu-icon.ui-icon {
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
}
|
||||
.ui-slider {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
.ui-slider .ui-slider-handle {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
cursor: default;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-slider .ui-slider-range {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
font-size: .7em;
|
||||
display: block;
|
||||
border: 0;
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
/* support: IE8 - See #6727 */
|
||||
.ui-slider.ui-state-disabled .ui-slider-handle,
|
||||
.ui-slider.ui-state-disabled .ui-slider-range {
|
||||
filter: inherit;
|
||||
}
|
||||
|
||||
.ui-slider-horizontal {
|
||||
height: .8em;
|
||||
}
|
||||
.ui-slider-horizontal .ui-slider-handle {
|
||||
top: -.3em;
|
||||
margin-left: -.6em;
|
||||
}
|
||||
.ui-slider-horizontal .ui-slider-range {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.ui-slider-horizontal .ui-slider-range-min {
|
||||
left: 0;
|
||||
}
|
||||
.ui-slider-horizontal .ui-slider-range-max {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ui-slider-vertical {
|
||||
width: .8em;
|
||||
height: 100px;
|
||||
}
|
||||
.ui-slider-vertical .ui-slider-handle {
|
||||
left: -.3em;
|
||||
margin-left: 0;
|
||||
margin-bottom: -.6em;
|
||||
}
|
||||
.ui-slider-vertical .ui-slider-range {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.ui-slider-vertical .ui-slider-range-min {
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-slider-vertical .ui-slider-range-max {
|
||||
top: 0;
|
||||
}
|
||||
.ui-sortable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.ui-spinner {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.ui-spinner-input {
|
||||
border: none;
|
||||
background: none;
|
||||
color: inherit;
|
||||
padding: .222em 0;
|
||||
margin: .2em 0;
|
||||
vertical-align: middle;
|
||||
margin-left: .4em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
.ui-spinner-button {
|
||||
width: 1.6em;
|
||||
height: 50%;
|
||||
font-size: .5em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
right: 0;
|
||||
}
|
||||
/* more specificity required here to override default borders */
|
||||
.ui-spinner a.ui-spinner-button {
|
||||
border-top-style: none;
|
||||
border-bottom-style: none;
|
||||
border-right-style: none;
|
||||
}
|
||||
.ui-spinner-up {
|
||||
top: 0;
|
||||
}
|
||||
.ui-spinner-down {
|
||||
bottom: 0;
|
||||
}
|
||||
.ui-tabs {
|
||||
position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
||||
padding: .2em;
|
||||
}
|
||||
.ui-tabs .ui-tabs-nav {
|
||||
margin: 0;
|
||||
padding: .2em .2em 0;
|
||||
}
|
||||
.ui-tabs .ui-tabs-nav li {
|
||||
list-style: none;
|
||||
float: left;
|
||||
position: relative;
|
||||
top: 0;
|
||||
margin: 1px .2em 0 0;
|
||||
border-bottom-width: 0;
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
|
||||
float: left;
|
||||
padding: .5em 1em;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
|
||||
margin-bottom: -1px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
|
||||
.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
|
||||
cursor: text;
|
||||
}
|
||||
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-tabs .ui-tabs-panel {
|
||||
display: block;
|
||||
border-width: 0;
|
||||
padding: 1em 1.4em;
|
||||
background: none;
|
||||
}
|
||||
.ui-tooltip {
|
||||
padding: 8px;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
max-width: 300px;
|
||||
}
|
||||
body .ui-tooltip {
|
||||
border-width: 2px;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,443 @@
|
||||
/*!
|
||||
* jQuery UI CSS Framework 1.12.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://api.jqueryui.com/category/theming/
|
||||
*
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6
|
||||
*/
|
||||
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget {
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
.ui-widget .ui-widget {
|
||||
font-size: 1em;
|
||||
}
|
||||
.ui-widget input,
|
||||
.ui-widget select,
|
||||
.ui-widget textarea,
|
||||
.ui-widget button {
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
.ui-widget.ui-widget-content {
|
||||
border: 1px solid #c5c5c5;
|
||||
}
|
||||
.ui-widget-content {
|
||||
border: 1px solid #dddddd;
|
||||
background: #ffffff;
|
||||
color: #333333;
|
||||
}
|
||||
.ui-widget-content a {
|
||||
color: #333333;
|
||||
}
|
||||
.ui-widget-header {
|
||||
border: 1px solid #dddddd;
|
||||
background: #e9e9e9;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui-widget-header a {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default,
|
||||
.ui-widget-content .ui-state-default,
|
||||
.ui-widget-header .ui-state-default,
|
||||
.ui-button,
|
||||
|
||||
/* We use html here because we need a greater specificity to make sure disabled
|
||||
works properly when clicked or hovered */
|
||||
html .ui-button.ui-state-disabled:hover,
|
||||
html .ui-button.ui-state-disabled:active {
|
||||
border: 1px solid #c5c5c5;
|
||||
background: #f6f6f6;
|
||||
font-weight: normal;
|
||||
color: #454545;
|
||||
}
|
||||
.ui-state-default a,
|
||||
.ui-state-default a:link,
|
||||
.ui-state-default a:visited,
|
||||
a.ui-button,
|
||||
a:link.ui-button,
|
||||
a:visited.ui-button,
|
||||
.ui-button {
|
||||
color: #454545;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ui-state-hover,
|
||||
.ui-widget-content .ui-state-hover,
|
||||
.ui-widget-header .ui-state-hover,
|
||||
.ui-state-focus,
|
||||
.ui-widget-content .ui-state-focus,
|
||||
.ui-widget-header .ui-state-focus,
|
||||
.ui-button:hover,
|
||||
.ui-button:focus {
|
||||
border: 1px solid #cccccc;
|
||||
background: #ededed;
|
||||
font-weight: normal;
|
||||
color: #2b2b2b;
|
||||
}
|
||||
.ui-state-hover a,
|
||||
.ui-state-hover a:hover,
|
||||
.ui-state-hover a:link,
|
||||
.ui-state-hover a:visited,
|
||||
.ui-state-focus a,
|
||||
.ui-state-focus a:hover,
|
||||
.ui-state-focus a:link,
|
||||
.ui-state-focus a:visited,
|
||||
a.ui-button:hover,
|
||||
a.ui-button:focus {
|
||||
color: #2b2b2b;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-visual-focus {
|
||||
box-shadow: 0 0 3px 1px rgb(94, 158, 214);
|
||||
}
|
||||
.ui-state-active,
|
||||
.ui-widget-content .ui-state-active,
|
||||
.ui-widget-header .ui-state-active,
|
||||
a.ui-button:active,
|
||||
.ui-button:active,
|
||||
.ui-button.ui-state-active:hover {
|
||||
border: 1px solid #003eff;
|
||||
background: #007fff;
|
||||
font-weight: normal;
|
||||
color: #ffffff;
|
||||
}
|
||||
.ui-icon-background,
|
||||
.ui-state-active .ui-icon-background {
|
||||
border: #003eff;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.ui-state-active a,
|
||||
.ui-state-active a:link,
|
||||
.ui-state-active a:visited {
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight,
|
||||
.ui-widget-content .ui-state-highlight,
|
||||
.ui-widget-header .ui-state-highlight {
|
||||
border: 1px solid #dad55e;
|
||||
background: #fffa90;
|
||||
color: #777620;
|
||||
}
|
||||
.ui-state-checked {
|
||||
border: 1px solid #dad55e;
|
||||
background: #fffa90;
|
||||
}
|
||||
.ui-state-highlight a,
|
||||
.ui-widget-content .ui-state-highlight a,
|
||||
.ui-widget-header .ui-state-highlight a {
|
||||
color: #777620;
|
||||
}
|
||||
.ui-state-error,
|
||||
.ui-widget-content .ui-state-error,
|
||||
.ui-widget-header .ui-state-error {
|
||||
border: 1px solid #f1a899;
|
||||
background: #fddfdf;
|
||||
color: #5f3f3f;
|
||||
}
|
||||
.ui-state-error a,
|
||||
.ui-widget-content .ui-state-error a,
|
||||
.ui-widget-header .ui-state-error a {
|
||||
color: #5f3f3f;
|
||||
}
|
||||
.ui-state-error-text,
|
||||
.ui-widget-content .ui-state-error-text,
|
||||
.ui-widget-header .ui-state-error-text {
|
||||
color: #5f3f3f;
|
||||
}
|
||||
.ui-priority-primary,
|
||||
.ui-widget-content .ui-priority-primary,
|
||||
.ui-widget-header .ui-priority-primary {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui-priority-secondary,
|
||||
.ui-widget-content .ui-priority-secondary,
|
||||
.ui-widget-header .ui-priority-secondary {
|
||||
opacity: .7;
|
||||
filter:Alpha(Opacity=70); /* support: IE8 */
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui-state-disabled,
|
||||
.ui-widget-content .ui-state-disabled,
|
||||
.ui-widget-header .ui-state-disabled {
|
||||
opacity: .35;
|
||||
filter:Alpha(Opacity=35); /* support: IE8 */
|
||||
background-image: none;
|
||||
}
|
||||
.ui-state-disabled .ui-icon {
|
||||
filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
|
||||
}
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.ui-icon,
|
||||
.ui-widget-content .ui-icon {
|
||||
background-image: url("images/ui-icons_444444_256x240.png");
|
||||
}
|
||||
.ui-widget-header .ui-icon {
|
||||
background-image: url("images/ui-icons_444444_256x240.png");
|
||||
}
|
||||
.ui-state-hover .ui-icon,
|
||||
.ui-state-focus .ui-icon,
|
||||
.ui-button:hover .ui-icon,
|
||||
.ui-button:focus .ui-icon {
|
||||
background-image: url("images/ui-icons_555555_256x240.png");
|
||||
}
|
||||
.ui-state-active .ui-icon,
|
||||
.ui-button:active .ui-icon {
|
||||
background-image: url("images/ui-icons_ffffff_256x240.png");
|
||||
}
|
||||
.ui-state-highlight .ui-icon,
|
||||
.ui-button .ui-state-highlight.ui-icon {
|
||||
background-image: url("images/ui-icons_777620_256x240.png");
|
||||
}
|
||||
.ui-state-error .ui-icon,
|
||||
.ui-state-error-text .ui-icon {
|
||||
background-image: url("images/ui-icons_cc0000_256x240.png");
|
||||
}
|
||||
.ui-button .ui-icon {
|
||||
background-image: url("images/ui-icons_777777_256x240.png");
|
||||
}
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-blank { background-position: 16px 16px; }
|
||||
.ui-icon-caret-1-n { background-position: 0 0; }
|
||||
.ui-icon-caret-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-caret-1-e { background-position: -32px 0; }
|
||||
.ui-icon-caret-1-se { background-position: -48px 0; }
|
||||
.ui-icon-caret-1-s { background-position: -65px 0; }
|
||||
.ui-icon-caret-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-caret-1-w { background-position: -96px 0; }
|
||||
.ui-icon-caret-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-caret-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-caret-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -65px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -65px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 1px -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-on { background-position: -96px -144px; }
|
||||
.ui-icon-radio-off { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-all,
|
||||
.ui-corner-top,
|
||||
.ui-corner-left,
|
||||
.ui-corner-tl {
|
||||
border-top-left-radius: 3px;
|
||||
}
|
||||
.ui-corner-all,
|
||||
.ui-corner-top,
|
||||
.ui-corner-right,
|
||||
.ui-corner-tr {
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
.ui-corner-all,
|
||||
.ui-corner-bottom,
|
||||
.ui-corner-left,
|
||||
.ui-corner-bl {
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
.ui-corner-all,
|
||||
.ui-corner-bottom,
|
||||
.ui-corner-right,
|
||||
.ui-corner-br {
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay {
|
||||
background: #aaaaaa;
|
||||
opacity: .003;
|
||||
filter: Alpha(Opacity=.3); /* support: IE8 */
|
||||
}
|
||||
.ui-widget-shadow {
|
||||
-webkit-box-shadow: 0px 0px 5px #666666;
|
||||
box-shadow: 0px 0px 5px #666666;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user