/site-packages/wx-2.8-msw-unicode/wx/lib/agw/aui/aui_utilities.py
Python | 468 lines | 279 code | 58 blank | 131 comment | 19 complexity | 5750314592400efc67bca6e31e06a5d7 MD5 | raw file
- """
- This module contains some common functions used by wxPython-AUI to
- manipulate colours, bitmaps, text, gradient shadings and custom
- dragging images for AuiNotebook tabs.
- """
-
- __author__ = "Andrea Gavana <andrea.gavana@gmail.com>"
- __date__ = "31 March 2009"
-
-
- import wx
-
- from aui_constants import AUI_BUTTON_STATE_PRESSED, AUI_GRADIENT_VERTICAL
- from aui_constants import AUI_BUTTON_STATE_HIDDEN
-
-
- if wx.Platform == "__WXMAC__":
- import Carbon.Appearance
-
-
- def BlendColour(fg, bg, alpha):
- """
- Blends the two colour component `fg` and `bg` into one colour component, adding
- an optional alpha channel.
-
- :param `fg`: the first colour component;
- :param `bg`: the second colour component;
- :param `alpha`: an optional transparency value.
- """
-
- result = bg + (alpha*(fg - bg))
-
- if result < 0.0:
- result = 0.0
- if result > 255:
- result = 255
-
- return result
-
-
- def StepColour(c, ialpha):
- """
- Darken/lighten the input colour `c`.
-
- :param `c`: a colour to darken/lighten;
- :param `ialpha`: a transparency value.
- """
-
- if ialpha == 100:
- return c
-
- r, g, b = c.Red(), c.Green(), c.Blue()
-
- # ialpha is 0..200 where 0 is completely black
- # and 200 is completely white and 100 is the same
- # convert that to normal alpha 0.0 - 1.0
- ialpha = min(ialpha, 200)
- ialpha = max(ialpha, 0)
- alpha = (ialpha - 100.0)/100.0
-
- if ialpha > 100:
-
- # blend with white
- bg = 255
- alpha = 1.0 - alpha # 0 = transparent fg 1 = opaque fg
-
- else:
-
- # blend with black
- bg = 0
- alpha = 1.0 + alpha # 0 = transparent fg 1 = opaque fg
-
- r = BlendColour(r, bg, alpha)
- g = BlendColour(g, bg, alpha)
- b = BlendColour(b, bg, alpha)
-
- return wx.Colour(r, g, b)
-
-
- def LightContrastColour(c):
- """
- Creates a new, lighter colour based on the input colour `c`.
-
- :param `c`: the input colour to analyze.
- """
-
- amount = 120
-
- # if the color is especially dark, then
- # make the contrast even lighter
- if c.Red() < 128 and c.Green() < 128 and c.Blue() < 128:
- amount = 160
-
- return StepColour(c, amount)
-
-
- def ChopText(dc, text, max_size):
- """
- Chops the input `text` if its size does not fit in `max_size`, by cutting the
- text and adding ellipsis at the end.
-
- :param `dc`: a wx.DC device context;
- :param `text`: the text to chop;
- :param `max_size`: the maximum size in which the text should fit.
- """
-
- # first check if the text fits with no problems
- x, y = dc.GetTextExtent(text)
-
- if x <= max_size:
- return text
-
- textLen = len(text)
- last_good_length = 0
-
- for i in xrange(textLen, -1, -1):
- s = text[0:i]
- s += "..."
-
- x, y = dc.GetTextExtent(s)
- last_good_length = i
-
- if x < max_size:
- break
-
- ret = text[0:last_good_length] + "..."
- return ret
-
-
- def BitmapFromBits(bits, w, h, color):
- """
- BitmapFromBits() is a utility function that creates a
- masked bitmap from raw bits (XBM format).
-
- :param `bits`: a string containing the raw bits of the bitmap;
- :param `w`: the bitmap width;
- :param `h`: the bitmap height;
- :param `colour`: the colour which will replace all white pixels in the
- raw bitmap.
- """
-
- img = wx.BitmapFromBits(bits, w, h).ConvertToImage()
- img.Replace(0, 0, 0, 123, 123, 123)
- img.Replace(255, 255, 255, color.Red(), color.Green(), color.Blue())
- img.SetMaskColour(123, 123, 123)
- return wx.BitmapFromImage(img)
-
-
- def IndentPressedBitmap(rect, button_state):
- """
- Indents the input rectangle `rect` based on the value of `button_state`.
-
- :param `rect`: an instance of wx.Rect;
- :param `button_state`: an AuiNotebook button state.
- """
-
- if button_state == AUI_BUTTON_STATE_PRESSED:
- rect.x += 1
- rect.y += 1
-
- return rect
-
-
- def GetBaseColour():
- """ Returns the face shading colour on push buttons/backgrounds. """
-
- if wx.Platform == "__WXMAC__":
-
- if hasattr(wx, 'MacThemeColour'):
- base_colour = wx.MacThemeColour(Carbon.Appearance.kThemeBrushToolbarBackground)
- else:
- brush = wx.Brush(wx.BLACK)
- brush.MacSetTheme(Carbon.Appearance.kThemeBrushToolbarBackground)
- base_colour = brush.GetColour()
-
- else:
-
- base_colour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE)
-
- # the base_colour is too pale to use as our base colour,
- # so darken it a bit
- if ((255-base_colour.Red()) +
- (255-base_colour.Green()) +
- (255-base_colour.Blue()) < 60):
-
- base_colour = StepColour(base_colour, 92)
-
- return base_colour
-
-
- def MakeDisabledBitmap(bitmap):
- """
- Convert the given image (in place) to a grayed-out version,
- appropriate for a 'disabled' appearance.
-
- :param: `bitmap`: the bitmap to gray-out.
- """
-
- anImage = bitmap.ConvertToImage()
- factor = 0.7 # 0 < f < 1. Higher Is Grayer
-
- if anImage.HasMask():
- maskColor = (anImage.GetMaskRed(), anImage.GetMaskGreen(), anImage.GetMaskBlue())
- else:
- maskColor = None
-
- data = map(ord, list(anImage.GetData()))
-
- for i in range(0, len(data), 3):
-
- pixel = (data[i], data[i+1], data[i+2])
- pixel = MakeGray(pixel, factor, maskColor)
-
- for x in range(3):
- data[i+x] = pixel[x]
-
- anImage.SetData(''.join(map(chr, data)))
-
- return anImage.ConvertToBitmap()
-
-
- def MakeGray((r,g,b), factor, maskColor):
- """
- Make a pixel grayed-out. If the pixel matches the `maskColor`, it won't be
- changed.
-
- :param `(r,g,b)`: a tuple representing a pixel colour;
- :param `factor`: a graying-out factor;
- :param `maskColor`: a colour mask.
- """
-
- if (r,g,b) != maskColor:
- return map(lambda x: int((230 - x) * factor) + x, (r,g,b))
- else:
- return (r,g,b)
-
-
- def Clip(a, b, c):
- """
- Clips the value in `a` based on the extremes `b` and `c`.
-
- :param `a`: the value to analyze;
- :param `b`: a minimum value;
- :param `c`: a maximum value.
- """
-
- return ((a < b and [b]) or [(a > c and [c] or [a])[0]])[0]
-
-
- def LightColour(color, percent):
- """
- Brighten input colour by `percent`.
-
- :param `colour`: the colour to be brightened;
- :param `percent`: brightening percentage.
- """
-
- end_color = wx.WHITE
-
- rd = end_color.Red() - color.Red()
- gd = end_color.Green() - color.Green()
- bd = end_color.Blue() - color.Blue()
-
- high = 100
-
- # We take the percent way of the color from color -. white
- i = percent
- r = color.Red() + ((i*rd*100)/high)/100
- g = color.Green() + ((i*gd*100)/high)/100
- b = color.Blue() + ((i*bd*100)/high)/100
- return wx.Colour(r, g, b)
-
-
- def PaneCreateStippleBitmap():
- """
- Creates a stipple bitmap to be used in a wx.Brush.
- This is used to draw sash resize hints.
- """
-
- data = [0, 0, 0, 192, 192, 192, 192, 192, 192, 0, 0, 0]
- img = wx.EmptyImage(2, 2)
- counter = 0
-
- for ii in xrange(2):
- for jj in xrange(2):
- img.SetRGB(ii, jj, data[counter], data[counter+1], data[counter+2])
- counter = counter + 3
-
- return img.ConvertToBitmap()
-
-
- def DrawMACCloseButton(colour, backColour=None):
- """
- Draws the wxMAC tab close button using wx.GraphicsContext.
-
- :param `colour`: the colour to use to draw the circle.
- """
-
- bmp = wx.EmptyBitmapRGBA(16, 16)
- dc = wx.MemoryDC()
- dc.SelectObject(bmp)
-
- gc = wx.GraphicsContext.Create(dc)
- gc.SetBrush(wx.Brush(colour))
- path = gc.CreatePath()
- path.AddCircle(6.5, 7, 6.5)
- path.CloseSubpath()
- gc.FillPath(path)
-
- path = gc.CreatePath()
- if backColour is not None:
- pen = wx.Pen(backColour, 2)
- else:
- pen = wx.Pen("white", 2)
-
- pen.SetCap(wx.CAP_BUTT)
- pen.SetJoin(wx.JOIN_BEVEL)
- gc.SetPen(pen)
- path.MoveToPoint(3.5, 4)
- path.AddLineToPoint(9.5, 10)
- path.MoveToPoint(3.5, 10)
- path.AddLineToPoint(9.5, 4)
- path.CloseSubpath()
- gc.DrawPath(path)
-
- dc.SelectObject(wx.NullBitmap)
- return bmp
-
-
- def DarkenBitmap(bmp, caption_colour, new_colour):
- """
- Darkens the input bitmap on wxMAC using the input colour.
- :param `bmp`: the bitmap to be manipulated;
- :param `caption_colour`: the colour of the pane caption
- :param `new_colour`: the colour used to darken the bitmap.
- """
-
- image = bmp.ConvertToImage()
- red = caption_colour.Red()/float(new_colour.Red())
- green = caption_colour.Green()/float(new_colour.Green())
- blue = caption_colour.Blue()/float(new_colour.Blue())
- image = image.AdjustChannels(red, green, blue)
- return image.ConvertToBitmap()
-
-
- def DrawGradientRectangle(dc, rect, start_colour, end_colour, direction, offset=0, length=0):
- """
- Draws a gradient-shaded rectangle.
-
- :param `dc`: a wx.DC device context;
- :param `rect`: the rectangle in which to draw the gradient;
- :param `start_colour`: the first colour of the gradient;
- :param `end_colour`: the second colour of the gradient;
- :param `direction`: the gradient direction (horizontal or vertical).
- """
-
- if direction == AUI_GRADIENT_VERTICAL:
- dc.GradientFillLinear(rect, start_colour, end_colour, wx.SOUTH)
- else:
- dc.GradientFillLinear(rect, start_colour, end_colour, wx.EAST)
-
-
- def FindFocusDescendant(ancestor):
- """
- Find a window with the focus, that is also a descendant of the given window.
- This is used to determine the window to initially send commands to.
-
- :param `ancestor`: the window to check for ancestry.
- """
-
- # Process events starting with the window with the focus, if any.
- focusWin = wx.Window.FindFocus()
- win = focusWin
-
- # Check if this is a descendant of this frame.
- # If not, win will be set to NULL.
- while win:
- if win == ancestor:
- break
- else:
- win = win.GetParent()
-
- if win is None:
- focusWin = None
-
- return focusWin
-
-
- #---------------------------------------------------------------------------
- # TabDragImage implementation
- # This class handles the creation of a custom image when dragging
- # AuiNotebook tabs
- #---------------------------------------------------------------------------
-
- class TabDragImage(wx.DragImage):
- """
- This class handles the creation of a custom image in case of drag and
- drop of a notebook tab.
- """
-
- def __init__(self, notebook, page, button_state, tabArt):
- """
- Default class constructor.
- For internal use: do not call it in your code!
-
- :param `notebook`: an instance of L{auibook.AuiNotebook};
- :param `page`: the dragged AuiNotebook page;
- :param `button_state`: the state of the close button on the tab;
- :param `tabArt`: an instance of L{tabart}.
- """
-
- self._backgroundColour = wx.NamedColour("pink")
- self._bitmap = self.CreateBitmap(notebook, page, button_state, tabArt)
- wx.DragImage.__init__(self, self._bitmap)
-
-
- def CreateBitmap(self, notebook, page, button_state, tabArt):
- """
- Actually creates the dnd bitmap.
-
- :param `notebook`: an instance of L{auibook.AuiNotebook};
- :param `page`: the dragged AuiNotebook page;
- :param `button_state`: the state of the close button on the tab;
- :param `tabArt`: an instance of L{tabart}.
- """
-
- memory = wx.MemoryDC(wx.EmptyBitmap(1, 1))
-
- tab_size, x_extent = tabArt.GetTabSize(memory, notebook, page.caption, page.bitmap, page.active,
- button_state)
-
- tab_width, tab_height = tab_size
- rect = wx.Rect(0, 0, tab_width, tab_height)
-
- bitmap = wx.EmptyBitmap(tab_width+1, tab_height+1)
- memory.SelectObject(bitmap)
-
- if wx.Platform == "__WXMAC__":
- memory.SetBackground(wx.TRANSPARENT_BRUSH)
- else:
- memory.SetBackground(wx.Brush(self._backgroundColour))
-
- memory.SetBackgroundMode(wx.TRANSPARENT)
- memory.Clear()
-
- tabArt.DrawTab(memory, notebook, page, rect, button_state)
- memory.SetBrush(wx.TRANSPARENT_BRUSH)
- memory.SetPen(wx.BLACK_PEN)
- memory.DrawRoundedRectangle(0, 0, tab_width+1, tab_height+1, 2)
-
- memory.SelectObject(wx.NullBitmap)
-
- # Gtk and Windows unfortunatly don't do so well with transparent
- # drawing so this hack corrects the image to have a transparent
- # background.
- if wx.Platform != '__WXMAC__':
- timg = bitmap.ConvertToImage()
- if not timg.HasAlpha():
- timg.InitAlpha()
- for y in xrange(timg.GetHeight()):
- for x in xrange(timg.GetWidth()):
- pix = wx.Colour(timg.GetRed(x, y),
- timg.GetGreen(x, y),
- timg.GetBlue(x, y))
- if pix == self._backgroundColour:
- timg.SetAlpha(x, y, 0)
- bitmap = timg.ConvertToBitmap()
- return bitmap