mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-29 06:32:40 -06:00
1194 lines
45 KiB
Python
1194 lines
45 KiB
Python
# -*- coding: utf-8 -*-
|
|
#----------------------------------------------------------------------------
|
|
# Name: dockart.py
|
|
# Purpose:
|
|
#
|
|
# Author: Andrea Gavana <andrea.gavana@gmail.com>
|
|
#
|
|
# Created:
|
|
# Version:
|
|
# Date: 31 March 2009
|
|
# Licence: wxWindows license
|
|
# Tags: phoenix-port, unittest, documented, py3-port
|
|
#----------------------------------------------------------------------------
|
|
"""
|
|
Dock art provider code - a dock provider provides all drawing functionality to
|
|
the AUI dock manager. This allows the dock manager to have a plugable look-and-feel.
|
|
|
|
By default, a :class:`~lib.agw.aui.framemanager` uses an instance of this class called :mod:`~lib.agw.aui.dockart`
|
|
which provides bitmap art and a colour scheme that is adapted to the major platforms'
|
|
look. You can either derive from that class to alter its behaviour or write a
|
|
completely new dock art class. Call :meth:`AuiManager.SetArtProvider() <lib.agw.aui.framemanager.AuiManager.SetArtProvider>`
|
|
to make use this new dock art.
|
|
"""
|
|
|
|
__author__ = "Andrea Gavana <andrea.gavana@gmail.com>"
|
|
__date__ = "31 March 2009"
|
|
|
|
|
|
import wx
|
|
|
|
from .aui_utilities import BitmapFromBits, StepColour, ChopText, GetBaseColour
|
|
from .aui_utilities import DrawGradientRectangle, DrawMACCloseButton
|
|
from .aui_utilities import DarkenBitmap, LightContrastColour
|
|
from .aui_constants import *
|
|
|
|
optionActive = 2**14
|
|
""" Indicates that a pane is active and should display an active caption (if present). """
|
|
|
|
_ctypes = False
|
|
|
|
# Try to import winxptheme for ModernDockArt
|
|
if wx.Platform == "__WXMSW__":
|
|
try:
|
|
import ctypes
|
|
import winxptheme
|
|
_ctypes = True
|
|
except ImportError:
|
|
pass
|
|
|
|
# -- AuiDefaultDockArt class implementation --
|
|
|
|
class AuiDefaultDockArt(object):
|
|
"""
|
|
Dock art provider code - a dock provider provides all drawing functionality to the AUI dock manager.
|
|
This allows the dock manager to have a plugable look-and-feel.
|
|
|
|
By default, a :class:`~lib.agw.aui.framemanager.AuiManager` uses an instance of this class called
|
|
:class:`AuiDefaultDockArt` which provides bitmap art and a colour scheme that is adapted to the major
|
|
platforms' look. You can either derive from that class to alter its behaviour or
|
|
write a completely new dock art class.
|
|
|
|
Call :meth:`AuiManager.SetArtProvider() <lib.agw.aui.framemanager.AuiManager.SetArtProvider>`
|
|
to make use this new dock art.
|
|
|
|
|
|
**Metric Ordinals**
|
|
|
|
These are the possible pane dock art settings for :class:`AuiDefaultDockArt`:
|
|
|
|
================================================ ======================================
|
|
Metric Ordinal Constant Description
|
|
================================================ ======================================
|
|
``AUI_DOCKART_SASH_SIZE`` Customizes the sash size
|
|
``AUI_DOCKART_CAPTION_SIZE`` Customizes the caption size
|
|
``AUI_DOCKART_GRIPPER_SIZE`` Customizes the gripper size
|
|
``AUI_DOCKART_PANE_BORDER_SIZE`` Customizes the pane border size
|
|
``AUI_DOCKART_PANE_BUTTON_SIZE`` Customizes the pane button size
|
|
``AUI_DOCKART_BACKGROUND_COLOUR`` Customizes the background colour
|
|
``AUI_DOCKART_BACKGROUND_GRADIENT_COLOUR`` Customizes the background gradient colour
|
|
``AUI_DOCKART_SASH_COLOUR`` Customizes the sash colour
|
|
``AUI_DOCKART_ACTIVE_CAPTION_COLOUR`` Customizes the active caption colour
|
|
``AUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR`` Customizes the active caption gradient colour
|
|
``AUI_DOCKART_INACTIVE_CAPTION_COLOUR`` Customizes the inactive caption colour
|
|
``AUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR`` Customizes the inactive gradient caption colour
|
|
``AUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR`` Customizes the active caption text colour
|
|
``AUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR`` Customizes the inactive caption text colour
|
|
``AUI_DOCKART_BORDER_COLOUR`` Customizes the border colour
|
|
``AUI_DOCKART_GRIPPER_COLOUR`` Customizes the gripper colour
|
|
``AUI_DOCKART_CAPTION_FONT`` Customizes the caption font
|
|
``AUI_DOCKART_GRADIENT_TYPE`` Customizes the gradient type (no gradient, vertical or horizontal)
|
|
``AUI_DOCKART_DRAW_SASH_GRIP`` Draw a sash grip on the sash
|
|
``AUI_DOCKART_HINT_WINDOW_COLOUR`` Customizes the hint window background colour (currently light blue)
|
|
================================================ ======================================
|
|
|
|
|
|
**Gradient Types**
|
|
|
|
These are the possible gradient dock art settings for :class:`AuiDefaultDockArt`:
|
|
|
|
============================================ ======================================
|
|
Gradient Constant Description
|
|
============================================ ======================================
|
|
``AUI_GRADIENT_NONE`` No gradient on the captions
|
|
``AUI_GRADIENT_VERTICAL`` Vertical gradient on the captions
|
|
``AUI_GRADIENT_HORIZONTAL`` Horizontal gradient on the captions
|
|
============================================ ======================================
|
|
|
|
|
|
**Button States**
|
|
|
|
These are the possible pane button / :class:`~lib.agw.aui.auibook.AuiNotebook` button /
|
|
:class:`~lib.agw.aui.auibar.AuiToolBar` button states:
|
|
|
|
============================================ ======================================
|
|
Button State Constant Description
|
|
============================================ ======================================
|
|
``AUI_BUTTON_STATE_NORMAL`` Normal button state
|
|
``AUI_BUTTON_STATE_HOVER`` Hovered button state
|
|
``AUI_BUTTON_STATE_PRESSED`` Pressed button state
|
|
``AUI_BUTTON_STATE_DISABLED`` Disabled button state
|
|
``AUI_BUTTON_STATE_HIDDEN`` Hidden button state
|
|
``AUI_BUTTON_STATE_CHECKED`` Checked button state
|
|
============================================ ======================================
|
|
|
|
|
|
**Button Identifiers**
|
|
|
|
These are the possible pane button / :class:`~lib.agw.aui.auibook.AuiNotebook` button /
|
|
:class:`~lib.agw.aui.auibar.AuiToolBar` button identifiers:
|
|
|
|
============================================ ======================================
|
|
Button Identifier Description
|
|
============================================ ======================================
|
|
``AUI_BUTTON_CLOSE`` Shows a close button on the pane
|
|
``AUI_BUTTON_MAXIMIZE_RESTORE`` Shows a maximize/restore button on the pane
|
|
``AUI_BUTTON_MINIMIZE`` Shows a minimize button on the pane
|
|
``AUI_BUTTON_PIN`` Shows a pin button on the pane
|
|
``AUI_BUTTON_OPTIONS`` Shows an option button on the pane (not implemented)
|
|
``AUI_BUTTON_WINDOWLIST`` Shows a window list button on the pane (for :class:`~lib.agw.aui.auibook.AuiNotebook`)
|
|
``AUI_BUTTON_LEFT`` Shows a left button on the pane (for :class:`~lib.agw.aui.auibook.AuiNotebook`)
|
|
``AUI_BUTTON_RIGHT`` Shows a right button on the pane (for :class:`~lib.agw.aui.auibook.AuiNotebook`)
|
|
``AUI_BUTTON_UP`` Shows an up button on the pane (not implemented)
|
|
``AUI_BUTTON_DOWN`` Shows a down button on the pane (not implemented)
|
|
``AUI_BUTTON_CUSTOM1`` Shows a custom button on the pane (not implemented)
|
|
``AUI_BUTTON_CUSTOM2`` Shows a custom button on the pane (not implemented)
|
|
``AUI_BUTTON_CUSTOM3`` Shows a custom button on the pane (not implemented)
|
|
============================================ ======================================
|
|
|
|
"""
|
|
|
|
def __init__(self):
|
|
""" Default class constructor. """
|
|
|
|
self.Init()
|
|
|
|
isMac = wx.Platform == "__WXMAC__"
|
|
|
|
if isMac:
|
|
self._caption_font = wx.SMALL_FONT
|
|
else:
|
|
self._caption_font = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False)
|
|
|
|
self.SetDefaultPaneBitmaps(isMac)
|
|
self._restore_bitmap = wx.Bitmap(restore_xpm)
|
|
|
|
# default metric values
|
|
self._sash_size = 4
|
|
|
|
if isMac:
|
|
# This really should be implemented in wx.SystemSettings
|
|
# There is no way to do this that I am aware outside of using
|
|
# the cocoa python bindings. 8 pixels looks correct on my system
|
|
# so hard coding it for now.
|
|
|
|
# How do I translate this?!? Not sure of the below implementation...
|
|
# SInt32 height;
|
|
# GetThemeMetric( kThemeMetricSmallPaneSplitterHeight , &height );
|
|
# self._sash_size = height;
|
|
|
|
self._sash_size = 8 # Carbon.Appearance.kThemeMetricPaneSplitterHeight
|
|
|
|
elif wx.Platform == "__WXGTK__":
|
|
self._sash_size = wx.RendererNative.Get().GetSplitterParams(wx.GetTopLevelWindows()[0]).widthSash
|
|
|
|
else:
|
|
self._sash_size = 4
|
|
|
|
self._caption_size = 19
|
|
self._border_size = 1
|
|
self._button_size = 14
|
|
self._gripper_size = 9
|
|
self._gradient_type = AUI_GRADIENT_VERTICAL
|
|
self._draw_sash = False
|
|
|
|
|
|
def Init(self):
|
|
""" Initializes the dock art. """
|
|
|
|
self.SetDefaultColours()
|
|
|
|
isMac = wx.Platform == "__WXMAC__"
|
|
|
|
if isMac:
|
|
self._active_caption_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT)
|
|
else:
|
|
self._active_caption_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_ACTIVECAPTION)
|
|
|
|
self._active_caption_gradient_colour = LightContrastColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))
|
|
self._active_caption_text_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
|
|
self._inactive_caption_text_colour = wx.BLACK
|
|
|
|
|
|
def SetDefaultColours(self, base_colour=None):
|
|
"""
|
|
Sets the default colours, which are calculated from the given base colour.
|
|
|
|
:param `base_colour`: an instance of :class:`Colour`. If defaulted to ``None``, a colour
|
|
is generated accordingly to the platform and theme.
|
|
"""
|
|
|
|
if base_colour is None:
|
|
base_colour = GetBaseColour()
|
|
|
|
darker1_colour = StepColour(base_colour, 85)
|
|
darker2_colour = StepColour(base_colour, 75)
|
|
darker3_colour = StepColour(base_colour, 60)
|
|
darker4_colour = StepColour(base_colour, 40)
|
|
|
|
self._background_colour = base_colour
|
|
self._background_gradient_colour = StepColour(base_colour, 180)
|
|
|
|
self._inactive_caption_colour = darker1_colour
|
|
self._inactive_caption_gradient_colour = StepColour(base_colour, 97)
|
|
|
|
self._sash_brush = wx.Brush(base_colour)
|
|
self._background_brush = wx.Brush(base_colour)
|
|
self._border_pen = wx.Pen(darker2_colour)
|
|
self._gripper_brush = wx.Brush(base_colour)
|
|
self._gripper_pen1 = wx.Pen(darker4_colour)
|
|
self._gripper_pen2 = wx.Pen(darker3_colour)
|
|
self._gripper_pen3 = wx.WHITE_PEN
|
|
|
|
self._hint_background_colour = colourHintBackground
|
|
|
|
|
|
def GetMetric(self, id):
|
|
"""
|
|
Gets the value of a certain setting.
|
|
|
|
:param integer `id`: can be one of the size values in `Metric Ordinals`.
|
|
"""
|
|
|
|
|
|
if id == AUI_DOCKART_SASH_SIZE:
|
|
return self._sash_size
|
|
elif id == AUI_DOCKART_CAPTION_SIZE:
|
|
return self._caption_size
|
|
elif id == AUI_DOCKART_GRIPPER_SIZE:
|
|
return self._gripper_size
|
|
elif id == AUI_DOCKART_PANE_BORDER_SIZE:
|
|
return self._border_size
|
|
elif id == AUI_DOCKART_PANE_BUTTON_SIZE:
|
|
return self._button_size
|
|
elif id == AUI_DOCKART_GRADIENT_TYPE:
|
|
return self._gradient_type
|
|
elif id == AUI_DOCKART_DRAW_SASH_GRIP:
|
|
return self._draw_sash
|
|
else:
|
|
raise Exception("Invalid Metric Ordinal.")
|
|
|
|
|
|
def SetMetric(self, id, new_val):
|
|
"""
|
|
Sets the value of a certain setting using `new_val`
|
|
|
|
:param integer `id`: can be one of the size values in `Metric Ordinals`;
|
|
:param `new_val`: the new value of the setting.
|
|
"""
|
|
|
|
if id == AUI_DOCKART_SASH_SIZE:
|
|
self._sash_size = new_val
|
|
elif id == AUI_DOCKART_CAPTION_SIZE:
|
|
self._caption_size = new_val
|
|
elif id == AUI_DOCKART_GRIPPER_SIZE:
|
|
self._gripper_size = new_val
|
|
elif id == AUI_DOCKART_PANE_BORDER_SIZE:
|
|
self._border_size = new_val
|
|
elif id == AUI_DOCKART_PANE_BUTTON_SIZE:
|
|
self._button_size = new_val
|
|
elif id == AUI_DOCKART_GRADIENT_TYPE:
|
|
self._gradient_type = new_val
|
|
elif id == AUI_DOCKART_DRAW_SASH_GRIP:
|
|
self._draw_sash = new_val
|
|
else:
|
|
raise Exception("Invalid Metric Ordinal.")
|
|
|
|
|
|
def GetColor(self, id):
|
|
"""
|
|
Gets the colour of a certain setting.
|
|
|
|
:param integer `id`: can be one of the colour values in `Metric Ordinals`.
|
|
"""
|
|
|
|
if id == AUI_DOCKART_BACKGROUND_COLOUR:
|
|
return self._background_brush.GetColour()
|
|
elif id == AUI_DOCKART_BACKGROUND_GRADIENT_COLOUR:
|
|
return self._background_gradient_colour
|
|
elif id == AUI_DOCKART_SASH_COLOUR:
|
|
return self._sash_brush.GetColour()
|
|
elif id == AUI_DOCKART_INACTIVE_CAPTION_COLOUR:
|
|
return self._inactive_caption_colour
|
|
elif id == AUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR:
|
|
return self._inactive_caption_gradient_colour
|
|
elif id == AUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR:
|
|
return self._inactive_caption_text_colour
|
|
elif id == AUI_DOCKART_ACTIVE_CAPTION_COLOUR:
|
|
return self._active_caption_colour
|
|
elif id == AUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR:
|
|
return self._active_caption_gradient_colour
|
|
elif id == AUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR:
|
|
return self._active_caption_text_colour
|
|
elif id == AUI_DOCKART_BORDER_COLOUR:
|
|
return self._border_pen.GetColour()
|
|
elif id == AUI_DOCKART_GRIPPER_COLOUR:
|
|
return self._gripper_brush.GetColour()
|
|
elif id == AUI_DOCKART_HINT_WINDOW_COLOUR:
|
|
return self._hint_background_colour
|
|
else:
|
|
raise Exception("Invalid Colour Ordinal.")
|
|
|
|
|
|
def SetColor(self, id, colour):
|
|
"""
|
|
Sets the colour of a certain setting.
|
|
|
|
:param integer `id`: can be one of the colour values in `Metric Ordinals`;
|
|
:param `colour`: the new value of the setting.
|
|
:type `colour`: :class:`Colour` or tuple or integer
|
|
"""
|
|
|
|
colour = wx.Colour(colour)
|
|
|
|
if id == AUI_DOCKART_BACKGROUND_COLOUR:
|
|
self._background_brush.SetColour(colour)
|
|
elif id == AUI_DOCKART_BACKGROUND_GRADIENT_COLOUR:
|
|
self._background_gradient_colour = colour
|
|
elif id == AUI_DOCKART_SASH_COLOUR:
|
|
self._sash_brush.SetColour(colour)
|
|
elif id == AUI_DOCKART_INACTIVE_CAPTION_COLOUR:
|
|
self._inactive_caption_colour = colour
|
|
if not self._custom_pane_bitmaps and wx.Platform == "__WXMAC__":
|
|
# No custom bitmaps for the pane close button
|
|
# Change the MAC close bitmap colour
|
|
self._inactive_close_bitmap = DrawMACCloseButton(wx.WHITE, colour)
|
|
|
|
elif id == AUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR:
|
|
self._inactive_caption_gradient_colour = colour
|
|
elif id == AUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR:
|
|
self._inactive_caption_text_colour = colour
|
|
elif id == AUI_DOCKART_ACTIVE_CAPTION_COLOUR:
|
|
self._active_caption_colour = colour
|
|
if not self._custom_pane_bitmaps and wx.Platform == "__WXMAC__":
|
|
# No custom bitmaps for the pane close button
|
|
# Change the MAC close bitmap colour
|
|
self._active_close_bitmap = DrawMACCloseButton(wx.WHITE, colour)
|
|
|
|
elif id == AUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR:
|
|
self._active_caption_gradient_colour = colour
|
|
elif id == AUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR:
|
|
self._active_caption_text_colour = colour
|
|
elif id == AUI_DOCKART_BORDER_COLOUR:
|
|
self._border_pen.SetColour(colour)
|
|
elif id == AUI_DOCKART_GRIPPER_COLOUR:
|
|
self._gripper_brush.SetColour(colour)
|
|
self._gripper_pen1.SetColour(StepColour(colour, 40))
|
|
self._gripper_pen2.SetColour(StepColour(colour, 60))
|
|
elif id == AUI_DOCKART_HINT_WINDOW_COLOUR:
|
|
self._hint_background_colour = colour
|
|
else:
|
|
raise Exception("Invalid Colour Ordinal.")
|
|
|
|
|
|
GetColour = GetColor
|
|
SetColour = SetColor
|
|
|
|
def SetFont(self, id, font):
|
|
"""
|
|
Sets a font setting.
|
|
|
|
:param integer `id`: must be ``AUI_DOCKART_CAPTION_FONT``;
|
|
:param `font`: an instance of :class:`Font`.
|
|
"""
|
|
|
|
if id == AUI_DOCKART_CAPTION_FONT:
|
|
self._caption_font = font
|
|
|
|
|
|
def GetFont(self, id):
|
|
"""
|
|
Gets a font setting.
|
|
|
|
:param integer `id`: must be ``AUI_DOCKART_CAPTION_FONT``, otherwise :class:`NullFont` is returned.
|
|
"""
|
|
|
|
if id == AUI_DOCKART_CAPTION_FONT:
|
|
return self._caption_font
|
|
|
|
return wx.NullFont
|
|
|
|
|
|
def DrawSash(self, dc, window, orient, rect):
|
|
"""
|
|
Draws a sash between two windows.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param integer `orient`: the sash orientation;
|
|
:param Rect `rect`: the sash rectangle.
|
|
"""
|
|
|
|
# AG: How do we make this work?!?
|
|
# RendererNative does not use the sash_brush chosen by the user
|
|
# and the rect.GetSize() is ignored as the sash is always drawn
|
|
# 3 pixel wide
|
|
# wx.RendererNative.Get().DrawSplitterSash(window, dc, rect.GetSize(), pos, orient)
|
|
|
|
dc.SetPen(wx.TRANSPARENT_PEN)
|
|
dc.SetBrush(self._sash_brush)
|
|
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
|
|
|
|
draw_sash = self.GetMetric(AUI_DOCKART_DRAW_SASH_GRIP)
|
|
if draw_sash:
|
|
self.DrawSashGripper(dc, orient, rect)
|
|
|
|
|
|
def DrawBackground(self, dc, window, orient, rect):
|
|
"""
|
|
Draws a background.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param integer `orient`: the gradient (if any) orientation;
|
|
:param Rect `rect`: the background rectangle.
|
|
"""
|
|
|
|
dc.SetPen(wx.TRANSPARENT_PEN)
|
|
if wx.Platform == "__WXMAC__":
|
|
# we have to clear first, otherwise we are drawing a light striped pattern
|
|
# over an already darker striped background
|
|
dc.SetBrush(wx.WHITE_BRUSH)
|
|
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
|
|
|
|
DrawGradientRectangle(dc, rect, self._background_brush.GetColour(),
|
|
self._background_gradient_colour,
|
|
AUI_GRADIENT_HORIZONTAL, rect.x, 700)
|
|
|
|
|
|
def DrawBorder(self, dc, window, rect, pane):
|
|
"""
|
|
Draws the pane border.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param Rect `rect`: the border rectangle;
|
|
:param `pane`: the pane for which the border is drawn.
|
|
"""
|
|
|
|
drect = wx.Rect(*rect)
|
|
|
|
dc.SetPen(self._border_pen)
|
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
|
|
border_width = self.GetMetric(AUI_DOCKART_PANE_BORDER_SIZE)
|
|
|
|
if pane.IsToolbar():
|
|
|
|
for ii in range(0, border_width):
|
|
|
|
dc.SetPen(wx.WHITE_PEN)
|
|
dc.DrawLine(drect.x, drect.y, drect.x+drect.width, drect.y)
|
|
dc.DrawLine(drect.x, drect.y, drect.x, drect.y+drect.height)
|
|
dc.SetPen(self._border_pen)
|
|
dc.DrawLine(drect.x, drect.y+drect.height-1,
|
|
drect.x+drect.width, drect.y+drect.height-1)
|
|
dc.DrawLine(drect.x+drect.width-1, drect.y,
|
|
drect.x+drect.width-1, drect.y+drect.height)
|
|
drect.Deflate(1, 1)
|
|
|
|
else:
|
|
|
|
for ii in range(0, border_width):
|
|
|
|
dc.DrawRectangle(drect.x, drect.y, drect.width, drect.height)
|
|
drect.Deflate(1, 1)
|
|
|
|
|
|
def DrawCaptionBackground(self, dc, rect, pane):
|
|
"""
|
|
Draws the text caption background in the pane.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param Rect `rect`: the text caption rectangle;
|
|
:param `pane`: the pane for which the text background is drawn.
|
|
"""
|
|
|
|
active = pane.state & optionActive
|
|
|
|
if self._gradient_type == AUI_GRADIENT_NONE:
|
|
if active:
|
|
dc.SetBrush(wx.Brush(self._active_caption_colour))
|
|
else:
|
|
dc.SetBrush(wx.Brush(self._inactive_caption_colour))
|
|
|
|
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
|
|
|
|
else:
|
|
|
|
switch_gradient = pane.HasCaptionLeft()
|
|
gradient_type = self._gradient_type
|
|
if switch_gradient:
|
|
gradient_type = (self._gradient_type == AUI_GRADIENT_HORIZONTAL and [AUI_GRADIENT_VERTICAL] or \
|
|
[AUI_GRADIENT_HORIZONTAL])[0]
|
|
|
|
if active:
|
|
if wx.Platform == "__WXMAC__":
|
|
DrawGradientRectangle(dc, rect, self._active_caption_colour,
|
|
self._active_caption_gradient_colour,
|
|
gradient_type)
|
|
else:
|
|
DrawGradientRectangle(dc, rect, self._active_caption_gradient_colour,
|
|
self._active_caption_colour,
|
|
gradient_type)
|
|
else:
|
|
if wx.Platform == "__WXMAC__":
|
|
DrawGradientRectangle(dc, rect, self._inactive_caption_gradient_colour,
|
|
self._inactive_caption_colour,
|
|
gradient_type)
|
|
else:
|
|
DrawGradientRectangle(dc, rect, self._inactive_caption_colour,
|
|
self._inactive_caption_gradient_colour,
|
|
gradient_type)
|
|
|
|
|
|
def DrawIcon(self, dc, rect, pane):
|
|
"""
|
|
Draws the icon in the pane caption area.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param Rect `rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which the icon is drawn.
|
|
"""
|
|
|
|
# Draw the icon centered vertically
|
|
if pane.icon.IsOk():
|
|
if pane.HasCaptionLeft():
|
|
bmp = wx.ImageFromBitmap(pane.icon).Rotate90(clockwise=False)
|
|
dc.DrawBitmap(bmp.ConvertToBitmap(), rect.x+(rect.width-pane.icon.GetWidth())/2, rect.y+rect.height-2-pane.icon.GetHeight(), True)
|
|
else:
|
|
dc.DrawBitmap(pane.icon, rect.x+2, rect.y+(rect.height-pane.icon.GetHeight())/2, True)
|
|
|
|
|
|
def DrawCaption(self, dc, window, text, rect, pane):
|
|
"""
|
|
Draws the text in the pane caption.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param string `text`: the text to be displayed;
|
|
:param Rect `rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which the text is drawn.
|
|
"""
|
|
|
|
dc.SetPen(wx.TRANSPARENT_PEN)
|
|
dc.SetFont(self._caption_font)
|
|
|
|
self.DrawCaptionBackground(dc, rect, pane)
|
|
|
|
if pane.state & optionActive:
|
|
dc.SetTextForeground(self._active_caption_text_colour)
|
|
else:
|
|
dc.SetTextForeground(self._inactive_caption_text_colour)
|
|
|
|
w, h = dc.GetTextExtent("ABCDEFHXfgkj")
|
|
|
|
clip_rect = wx.Rect(*rect)
|
|
btns = pane.CountButtons()
|
|
|
|
captionLeft = pane.HasCaptionLeft()
|
|
variable = (captionLeft and [rect.height] or [rect.width])[0]
|
|
|
|
variable -= 3 # text offset
|
|
variable -= 2 # button padding
|
|
|
|
caption_offset = 0
|
|
if pane.icon:
|
|
if captionLeft:
|
|
caption_offset += pane.icon.GetHeight() + 3
|
|
else:
|
|
caption_offset += pane.icon.GetWidth() + 3
|
|
|
|
self.DrawIcon(dc, rect, pane)
|
|
|
|
variable -= caption_offset
|
|
variable -= btns*(self._button_size + self._border_size)
|
|
draw_text = ChopText(dc, text, variable)
|
|
|
|
if captionLeft:
|
|
dc.DrawRotatedText(draw_text, rect.x+(rect.width/2)-(h/2)-1, rect.y+rect.height-3-caption_offset, 90)
|
|
else:
|
|
dc.DrawText(draw_text, rect.x+3+caption_offset, rect.y+(rect.height/2)-(h/2)-1)
|
|
|
|
|
|
def RequestUserAttention(self, dc, window, text, rect, pane):
|
|
"""
|
|
Requests the user attention by intermittently highlighting the pane caption.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param string `text`: the text to be displayed;
|
|
:param Rect `rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which we want to attract the user attention.
|
|
"""
|
|
|
|
state = pane.state
|
|
pane.state &= ~optionActive
|
|
|
|
for indx in range(6):
|
|
active = (indx%2 == 0 and [True] or [False])[0]
|
|
if active:
|
|
pane.state |= optionActive
|
|
else:
|
|
pane.state &= ~optionActive
|
|
|
|
self.DrawCaptionBackground(dc, rect, pane)
|
|
self.DrawCaption(dc, window, text, rect, pane)
|
|
wx.SafeYield()
|
|
wx.MilliSleep(350)
|
|
|
|
pane.state = state
|
|
|
|
|
|
def DrawGripper(self, dc, window, rect, pane):
|
|
"""
|
|
Draws a gripper on the pane.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param Rect `rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which the gripper is drawn.
|
|
"""
|
|
|
|
dc.SetPen(wx.TRANSPARENT_PEN)
|
|
dc.SetBrush(self._gripper_brush)
|
|
|
|
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
|
|
|
|
if not pane.HasGripperTop():
|
|
y = 4
|
|
while 1:
|
|
dc.SetPen(self._gripper_pen1)
|
|
dc.DrawPoint(rect.x+3, rect.y+y)
|
|
dc.SetPen(self._gripper_pen2)
|
|
dc.DrawPoint(rect.x+3, rect.y+y+1)
|
|
dc.DrawPoint(rect.x+4, rect.y+y)
|
|
dc.SetPen(self._gripper_pen3)
|
|
dc.DrawPoint(rect.x+5, rect.y+y+1)
|
|
dc.DrawPoint(rect.x+5, rect.y+y+2)
|
|
dc.DrawPoint(rect.x+4, rect.y+y+2)
|
|
y = y + 4
|
|
if y > rect.GetHeight() - 4:
|
|
break
|
|
else:
|
|
x = 4
|
|
while 1:
|
|
dc.SetPen(self._gripper_pen1)
|
|
dc.DrawPoint(rect.x+x, rect.y+3)
|
|
dc.SetPen(self._gripper_pen2)
|
|
dc.DrawPoint(rect.x+x+1, rect.y+3)
|
|
dc.DrawPoint(rect.x+x, rect.y+4)
|
|
dc.SetPen(self._gripper_pen3)
|
|
dc.DrawPoint(rect.x+x+1, rect.y+5)
|
|
dc.DrawPoint(rect.x+x+2, rect.y+5)
|
|
dc.DrawPoint(rect.x+x+2, rect.y+4)
|
|
x = x + 4
|
|
if x > rect.GetWidth() - 4:
|
|
break
|
|
|
|
|
|
def DrawPaneButton(self, dc, window, button, button_state, _rect, pane):
|
|
"""
|
|
Draws a pane button in the pane caption area.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param integer `button`: the button to be drawn;
|
|
:param integer `button_state`: the pane button state;
|
|
:param Rect `_rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which the button is drawn.
|
|
"""
|
|
|
|
if not pane:
|
|
return
|
|
|
|
if button == AUI_BUTTON_CLOSE:
|
|
if pane.state & optionActive:
|
|
bmp = self._active_close_bitmap
|
|
else:
|
|
bmp = self._inactive_close_bitmap
|
|
|
|
elif button == AUI_BUTTON_PIN:
|
|
if pane.state & optionActive:
|
|
bmp = self._active_pin_bitmap
|
|
else:
|
|
bmp = self._inactive_pin_bitmap
|
|
|
|
elif button == AUI_BUTTON_MAXIMIZE_RESTORE:
|
|
if pane.IsMaximized():
|
|
if pane.state & optionActive:
|
|
bmp = self._active_restore_bitmap
|
|
else:
|
|
bmp = self._inactive_restore_bitmap
|
|
else:
|
|
if pane.state & optionActive:
|
|
bmp = self._active_maximize_bitmap
|
|
else:
|
|
bmp = self._inactive_maximize_bitmap
|
|
|
|
elif button == AUI_BUTTON_MINIMIZE:
|
|
if pane.state & optionActive:
|
|
bmp = self._active_minimize_bitmap
|
|
else:
|
|
bmp = self._inactive_minimize_bitmap
|
|
|
|
isVertical = pane.HasCaptionLeft()
|
|
|
|
rect = wx.Rect(*_rect)
|
|
|
|
if isVertical:
|
|
old_x = rect.x
|
|
rect.x = rect.x + (rect.width/2) - (bmp.GetWidth()/2)
|
|
rect.width = old_x + rect.width - rect.x - 1
|
|
else:
|
|
old_y = rect.y
|
|
rect.y = rect.y + (rect.height/2) - (bmp.GetHeight()/2)
|
|
rect.height = old_y + rect.height - rect.y - 1
|
|
|
|
if button_state == AUI_BUTTON_STATE_PRESSED:
|
|
rect.x += 1
|
|
rect.y += 1
|
|
|
|
if button_state in [AUI_BUTTON_STATE_HOVER, AUI_BUTTON_STATE_PRESSED]:
|
|
|
|
if pane.state & optionActive:
|
|
|
|
dc.SetBrush(wx.Brush(StepColour(self._active_caption_colour, 120)))
|
|
dc.SetPen(wx.Pen(StepColour(self._active_caption_colour, 70)))
|
|
|
|
else:
|
|
|
|
dc.SetBrush(wx.Brush(StepColour(self._inactive_caption_colour, 120)))
|
|
dc.SetPen(wx.Pen(StepColour(self._inactive_caption_colour, 70)))
|
|
|
|
if wx.Platform != "__WXMAC__":
|
|
# draw the background behind the button
|
|
dc.DrawRectangle(rect.x, rect.y, 15, 15)
|
|
else:
|
|
# Darker the bitmap a bit
|
|
bmp = DarkenBitmap(bmp, self._active_caption_colour, StepColour(self._active_caption_colour, 110))
|
|
|
|
if isVertical:
|
|
bmp = wx.ImageFromBitmap(bmp).Rotate90(clockwise=False).ConvertToBitmap()
|
|
|
|
# draw the button itself
|
|
dc.DrawBitmap(bmp, rect.x, rect.y, True)
|
|
|
|
|
|
def DrawSashGripper(self, dc, orient, rect):
|
|
"""
|
|
Draws a sash gripper on a sash between two windows.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param integer `orient`: the sash orientation;
|
|
:param Rect `rect`: the sash rectangle.
|
|
"""
|
|
|
|
dc.SetBrush(self._gripper_brush)
|
|
|
|
if orient == wx.HORIZONTAL: # horizontal sash
|
|
|
|
x = rect.x + int((1.0/4.0)*rect.width)
|
|
xend = rect.x + int((3.0/4.0)*rect.width)
|
|
y = rect.y + (rect.height/2) - 1
|
|
|
|
while 1:
|
|
dc.SetPen(self._gripper_pen3)
|
|
dc.DrawRectangle(x, y, 2, 2)
|
|
dc.SetPen(self._gripper_pen2)
|
|
dc.DrawPoint(x+1, y+1)
|
|
x = x + 5
|
|
|
|
if x >= xend:
|
|
break
|
|
|
|
else:
|
|
|
|
y = rect.y + int((1.0/4.0)*rect.height)
|
|
yend = rect.y + int((3.0/4.0)*rect.height)
|
|
x = rect.x + (rect.width/2) - 1
|
|
|
|
while 1:
|
|
dc.SetPen(self._gripper_pen3)
|
|
dc.DrawRectangle(x, y, 2, 2)
|
|
dc.SetPen(self._gripper_pen2)
|
|
dc.DrawPoint(x+1, y+1)
|
|
y = y + 5
|
|
|
|
if y >= yend:
|
|
break
|
|
|
|
|
|
def SetDefaultPaneBitmaps(self, isMac):
|
|
"""
|
|
Assigns the default pane bitmaps.
|
|
|
|
:param bool `isMac`: whether we are on wxMAC or not.
|
|
"""
|
|
|
|
if isMac:
|
|
self._inactive_close_bitmap = DrawMACCloseButton(wx.WHITE, self._inactive_caption_colour)
|
|
self._active_close_bitmap = DrawMACCloseButton(wx.WHITE, self._active_caption_colour)
|
|
else:
|
|
self._inactive_close_bitmap = BitmapFromBits(close_bits, 16, 16, self._inactive_caption_text_colour)
|
|
self._active_close_bitmap = BitmapFromBits(close_bits, 16, 16, self._active_caption_text_colour)
|
|
|
|
if isMac:
|
|
self._inactive_maximize_bitmap = BitmapFromBits(max_bits, 16, 16, wx.WHITE)
|
|
self._active_maximize_bitmap = BitmapFromBits(max_bits, 16, 16, wx.WHITE)
|
|
else:
|
|
self._inactive_maximize_bitmap = BitmapFromBits(max_bits, 16, 16, self._inactive_caption_text_colour)
|
|
self._active_maximize_bitmap = BitmapFromBits(max_bits, 16, 16, self._active_caption_text_colour)
|
|
|
|
if isMac:
|
|
self._inactive_restore_bitmap = BitmapFromBits(restore_bits, 16, 16, wx.WHITE)
|
|
self._active_restore_bitmap = BitmapFromBits(restore_bits, 16, 16, wx.WHITE)
|
|
else:
|
|
self._inactive_restore_bitmap = BitmapFromBits(restore_bits, 16, 16, self._inactive_caption_text_colour)
|
|
self._active_restore_bitmap = BitmapFromBits(restore_bits, 16, 16, self._active_caption_text_colour)
|
|
|
|
if isMac:
|
|
self._inactive_minimize_bitmap = BitmapFromBits(minimize_bits, 16, 16, wx.WHITE)
|
|
self._active_minimize_bitmap = BitmapFromBits(minimize_bits, 16, 16, wx.WHITE)
|
|
else:
|
|
self._inactive_minimize_bitmap = BitmapFromBits(minimize_bits, 16, 16, self._inactive_caption_text_colour)
|
|
self._active_minimize_bitmap = BitmapFromBits(minimize_bits, 16, 16, self._active_caption_text_colour)
|
|
|
|
self._inactive_pin_bitmap = BitmapFromBits(pin_bits, 16, 16, self._inactive_caption_text_colour)
|
|
self._active_pin_bitmap = BitmapFromBits(pin_bits, 16, 16, self._active_caption_text_colour)
|
|
|
|
self._custom_pane_bitmaps = False
|
|
|
|
|
|
def SetCustomPaneBitmap(self, bmp, button, active, maximize=False):
|
|
"""
|
|
Sets a custom button bitmap for the pane button.
|
|
|
|
:param Bitmap `bmp`: the actual bitmap to set;
|
|
:param integer `button`: the button identifier;
|
|
:param bool `active`: whether it is the bitmap for the active button or not;
|
|
:param bool `maximize`: used to distinguish between the maximize and restore bitmaps.
|
|
"""
|
|
|
|
if bmp.GetWidth() > 16 or bmp.GetHeight() > 16:
|
|
raise Exception("The input bitmap is too big")
|
|
|
|
if button == AUI_BUTTON_CLOSE:
|
|
if active:
|
|
self._active_close_bitmap = bmp
|
|
else:
|
|
self._inactive_close_bitmap = bmp
|
|
|
|
if wx.Platform == "__WXMAC__":
|
|
self._custom_pane_bitmaps = True
|
|
|
|
elif button == AUI_BUTTON_PIN:
|
|
if active:
|
|
self._active_pin_bitmap = bmp
|
|
else:
|
|
self._inactive_pin_bitmap = bmp
|
|
|
|
elif button == AUI_BUTTON_MAXIMIZE_RESTORE:
|
|
if maximize:
|
|
if active:
|
|
self._active_maximize_bitmap = bmp
|
|
else:
|
|
self._inactive_maximize_bitmap = bmp
|
|
else:
|
|
if active:
|
|
self._active_restore_bitmap = bmp
|
|
else:
|
|
self._inactive_restore_bitmap = bmp
|
|
|
|
elif button == AUI_BUTTON_MINIMIZE:
|
|
if active:
|
|
self._active_minimize_bitmap = bmp
|
|
else:
|
|
self._inactive_minimize_bitmap = bmp
|
|
|
|
|
|
if _ctypes:
|
|
class RECT(ctypes.Structure):
|
|
""" Used to handle :class:`ModernDockArt` on Windows XP/Vista/7. """
|
|
_fields_ = [('left', ctypes.c_ulong),('top', ctypes.c_ulong),('right', ctypes.c_ulong),('bottom', ctypes.c_ulong)]
|
|
|
|
def dump(self):
|
|
""" Dumps `self` as a :class:`Rect`. """
|
|
return list(map(int, (self.left, self.top, self.right, self.bottom)))
|
|
|
|
|
|
class SIZE(ctypes.Structure):
|
|
""" Used to handle :class:`ModernDockArt` on Windows XP/Vista/7. """
|
|
_fields_ = [('x', ctypes.c_long),('y', ctypes.c_long)]
|
|
|
|
|
|
class ModernDockArt(AuiDefaultDockArt):
|
|
"""
|
|
ModernDockArt is a custom `AuiDockArt` class, that implements a look similar to Firefox and other recents applications.
|
|
|
|
Is uses the `winxptheme <http://sourceforge.net/projects/pywin32/>`_ module and
|
|
XP themes whenever possible, so it should look good even if the user has a custom theme.
|
|
|
|
:note: This dock art is Windows only and will only work if you have installed
|
|
Mark Hammond's `pywin32` module (http://sourceforge.net/projects/pywin32/).
|
|
"""
|
|
|
|
def __init__(self, win):
|
|
"""
|
|
Default class constructor.
|
|
|
|
:param Window `win`: the window managed by :class:`~lib.agw.aui.framemanager.AuiManager`.
|
|
"""
|
|
|
|
AuiDefaultDockArt.__init__(self)
|
|
|
|
self.win = win
|
|
|
|
# Get the size of a small close button (themed)
|
|
hwnd = self.win.GetHandle()
|
|
self.usingTheme = False
|
|
|
|
if _ctypes:
|
|
self.hTheme1 = winxptheme.OpenThemeData(hwnd, "Window")
|
|
self.usingTheme = True
|
|
|
|
if not self.hTheme1:
|
|
self.usingTheme = False
|
|
|
|
self._button_size = 13
|
|
|
|
self._button_border_size = 3
|
|
self._caption_text_indent = 6
|
|
self._caption_size = 22
|
|
|
|
# We only highlight the active pane with the caption text being in bold.
|
|
# So we do not want a special colour for active elements.
|
|
self._active_close_bitmap = self._inactive_close_bitmap
|
|
|
|
self.Init()
|
|
|
|
|
|
def Init(self):
|
|
""" Initializes the dock art. """
|
|
|
|
AuiDefaultDockArt.Init(self)
|
|
|
|
self._active_caption_colour = self._inactive_caption_colour
|
|
self._active_caption_text_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_CAPTIONTEXT)
|
|
self._inactive_caption_text_colour = self._active_caption_text_colour
|
|
|
|
|
|
def DrawCaption(self, dc, window, text, rect, pane):
|
|
"""
|
|
Draws the text in the pane caption.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param string `text`: the text to be displayed;
|
|
:param Rect `rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which the text is drawn.
|
|
"""
|
|
|
|
dc.SetPen(wx.TRANSPARENT_PEN)
|
|
self.DrawCaptionBackground(dc, rect, pane)
|
|
|
|
active = ((pane.state & optionActive) and [True] or [False])[0]
|
|
|
|
self._caption_font.SetWeight(wx.FONTWEIGHT_BOLD)
|
|
dc.SetFont(self._caption_font)
|
|
|
|
if active:
|
|
dc.SetTextForeground(self._active_caption_text_colour)
|
|
else:
|
|
dc.SetTextForeground(self._inactive_caption_text_colour)
|
|
|
|
w, h = dc.GetTextExtent("ABCDEFHXfgkj")
|
|
|
|
clip_rect = wx.Rect(*rect)
|
|
btns = pane.CountButtons()
|
|
|
|
captionLeft = pane.HasCaptionLeft()
|
|
variable = (captionLeft and [rect.height] or [rect.width])[0]
|
|
|
|
variable -= 3 # text offset
|
|
variable -= 2 # button padding
|
|
|
|
caption_offset = 0
|
|
if pane.icon:
|
|
if captionLeft:
|
|
caption_offset += pane.icon.GetHeight() + 3
|
|
else:
|
|
caption_offset += pane.icon.GetWidth() + 3
|
|
|
|
self.DrawIcon(dc, rect, pane)
|
|
|
|
diff = -2
|
|
if self.usingTheme:
|
|
diff = -1
|
|
|
|
variable -= caption_offset
|
|
variable -= btns*(self._button_size + self._button_border_size)
|
|
draw_text = ChopText(dc, text, variable)
|
|
|
|
if captionLeft:
|
|
dc.DrawRotatedText(draw_text, rect.x+(rect.width/2)-(h/2)-diff, rect.y+rect.height-3-caption_offset, 90)
|
|
else:
|
|
dc.DrawText(draw_text, rect.x+3+caption_offset, rect.y+(rect.height/2)-(h/2)-diff)
|
|
|
|
|
|
def DrawCaptionBackground(self, dc, rect, pane):
|
|
"""
|
|
Draws the text caption background in the pane.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param Rect `rect`: the text caption rectangle;
|
|
:param `pane`: the pane for which we are drawing the caption background.
|
|
"""
|
|
|
|
dc.SetBrush(self._background_brush)
|
|
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
|
|
|
|
active = ((pane.state & optionActive) and [True] or [False])[0]
|
|
|
|
if self.usingTheme:
|
|
|
|
rectangle = wx.Rect()
|
|
|
|
rc = RECT(rectangle.x, rectangle.y, rectangle.width, rectangle.height)
|
|
|
|
# If rect x/y values are negative rc.right/bottom values will overflow and winxptheme.DrawThemeBackground
|
|
# will raise a TypeError. Ensure they are never negative.
|
|
rect.x = max(0, rect.x)
|
|
rect.y = max(0, rect.y)
|
|
|
|
rc.top = rect.x
|
|
rc.left = rect.y
|
|
rc.right = rect.x + rect.width
|
|
rc.bottom = rect.y + rect.height
|
|
|
|
if active:
|
|
winxptheme.DrawThemeBackground(self.hTheme1, int(dc.GetHandle()), 5, 1, (rc.top, rc.left, rc.right, rc.bottom), None)
|
|
else:
|
|
winxptheme.DrawThemeBackground(self.hTheme1, int(dc.GetHandle()), 5, 2, (rc.top, rc.left, rc.right, rc.bottom), None)
|
|
|
|
else:
|
|
|
|
AuiDefaultDockArt.DrawCaptionBackground(self, dc, rect, pane)
|
|
|
|
|
|
def RequestUserAttention(self, dc, window, text, rect, pane):
|
|
"""
|
|
Requests the user attention by intermittently highlighting the pane caption.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param string `text`: the text to be displayed;
|
|
:param Rect `rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which the text is drawn.
|
|
"""
|
|
|
|
state = pane.state
|
|
pane.state &= ~optionActive
|
|
|
|
for indx in range(6):
|
|
active = (indx%2 == 0 and [True] or [False])[0]
|
|
if active:
|
|
pane.state |= optionActive
|
|
else:
|
|
pane.state &= ~optionActive
|
|
|
|
self.DrawCaptionBackground(dc, rect, pane)
|
|
self.DrawCaption(dc, window, text, rect, pane)
|
|
wx.SafeYield()
|
|
wx.MilliSleep(350)
|
|
|
|
pane.state = state
|
|
|
|
|
|
def DrawPaneButton(self, dc, window, button, button_state, rect, pane):
|
|
"""
|
|
Draws a pane button in the pane caption area.
|
|
|
|
:param `dc`: a :class:`DC` device context;
|
|
:param `window`: an instance of :class:`Window`;
|
|
:param integer `button`: the button to be drawn;
|
|
:param integer `button_state`: the pane button state;
|
|
:param Rect `rect`: the pane caption rectangle;
|
|
:param `pane`: the pane for which the button is drawn.
|
|
"""
|
|
|
|
if self.usingTheme:
|
|
|
|
hTheme = self.hTheme1
|
|
|
|
# Get the real button position (compensating for borders)
|
|
drect = wx.Rect(rect.x, rect.y, self._button_size, self._button_size)
|
|
|
|
# Draw the themed close button
|
|
rc = RECT(0, 0, 0, 0)
|
|
if pane.HasCaptionLeft():
|
|
rc.top = rect.x + self._button_border_size
|
|
rc.left = int(rect.y + 1.5*self._button_border_size)
|
|
rc.right = rect.x + self._button_size + self._button_border_size
|
|
rc.bottom = int(rect.y + self._button_size + 1.5*self._button_border_size)
|
|
else:
|
|
rc.top = rect.x - self._button_border_size
|
|
rc.left = int(rect.y + 1.5*self._button_border_size)
|
|
rc.right = rect.x + self._button_size- self._button_border_size
|
|
rc.bottom = int(rect.y + self._button_size + 1.5*self._button_border_size)
|
|
|
|
if button == AUI_BUTTON_CLOSE:
|
|
btntype = 19
|
|
|
|
elif button == AUI_BUTTON_PIN:
|
|
btntype = 23
|
|
|
|
elif button == AUI_BUTTON_MAXIMIZE_RESTORE:
|
|
if not pane.IsMaximized():
|
|
btntype = 17
|
|
else:
|
|
btntype = 21
|
|
else:
|
|
btntype = 15
|
|
|
|
state = 4 # CBS_DISABLED
|
|
|
|
if pane.state & optionActive:
|
|
|
|
if button_state == AUI_BUTTON_STATE_NORMAL:
|
|
state = 1 # CBS_NORMAL
|
|
|
|
elif button_state == AUI_BUTTON_STATE_HOVER:
|
|
state = 2 # CBS_HOT
|
|
|
|
elif button_state == AUI_BUTTON_STATE_PRESSED:
|
|
state = 3 # CBS_PUSHED
|
|
|
|
else:
|
|
raise Exception("ERROR: Unknown State.")
|
|
|
|
else: # inactive pane
|
|
|
|
if button_state == AUI_BUTTON_STATE_NORMAL:
|
|
state = 5 # CBS_NORMAL
|
|
|
|
elif button_state == AUI_BUTTON_STATE_HOVER:
|
|
state = 6 # CBS_HOT
|
|
|
|
elif button_state == AUI_BUTTON_STATE_PRESSED:
|
|
state = 7 # CBS_PUSHED
|
|
|
|
else:
|
|
raise Exception("ERROR: Unknown State.")
|
|
|
|
try:
|
|
winxptheme.DrawThemeBackground(hTheme, int(dc.GetHandle()), btntype, state, (rc.top, rc.left, rc.right, rc.bottom), None)
|
|
except TypeError:
|
|
return
|
|
|
|
else:
|
|
|
|
# Fallback to default closebutton if themes are not enabled
|
|
rect2 = wx.Rect(rect.x-4, rect.y+2, rect.width, rect.height)
|
|
AuiDefaultDockArt.DrawPaneButton(self, dc, window, button, button_state, rect2, pane)
|
|
|