[ create a new paste ] login | about

Link: http://codepad.org/urk0FFkg    [ raw code | fork ]

Python, pasted on Sep 13:
"""--------------------------------------------------------------------------------------------
   --- fhPatternGadegt
   --- 2013 Ferdinand Hoppe
   --------------------------------------------------------------------------------------------"""
import math

import c4d
import fhp
from c4d import gui


class fhPatternGadegt(gui.GeUserArea):
    """
    A gui gadget to modify and display boolean patterns.
    """
    def __init__(self, host):
        """
        :param host: The hosting BaseToolData instance
        """
        self.Host          = host
        self.BorderWidth   = None
        self.CellPerColumn = None
        self.CellWidht     = fhp.IDC_SELECTLOOP_CELLSIZE[0]
        self.CellHeight    = fhp.IDC_SELECTLOOP_CELLSIZE[1]
        self.Columns       = None
        self.Height        = None
        self.Width         = None
        self.MinHeight     = fhp.IDC_SELECTLOOP_GADGET_MINH
        self.MinWidht      = fhp.IDC_SELECTLOOP_GADGET_MINW
        self.MouseX        = None
        self.MouseY        = None

    
    """--------------------------------------------------------------------------------------------
        Overridden methods
        -------------------------------------------------------------------------------------------"""
        
    def Init(self):
        """
        Init the gadegt.
        :return : Bool
        """
        self.GetColors()
        return True
     
    def GetMinSize(self):
        """
        Resize the gadget
        :return : int, int
        """
        return int(self.MinWidht), int(self.MinHeight)
     
    def Sized(self, w, h):
        """
        Get the gadegts height and width
        """
        self.Height, self.Width = int(h), int(w)
        self.FitGadegt()  
        
    def Message(self, msg, result):
        """
        Fetch and store mouse over events
        :return : bool
        """
        if msg.GetId() == c4d.BFM_GETCURSORINFO:
            base = self.Local2Screen()
            if base:
                self.MouseX = msg.GetLong(c4d.BFM_DRAG_SCREENX) - base['x']
                self.MouseY = msg.GetLong(c4d.BFM_DRAG_SCREENY) - base['y']
                self.Redraw()
                self.SetTimer(100)
        return gui.GeUserArea.Message(self, msg, result)    
    
    def Timer(self, msg):
        """
        Timer loop to catch OnMouseExit
        """
        base = self.Local2Global()
        bc = c4d.BaseContainer()
        res = gui.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, bc)
        mx = bc.GetLong(c4d.BFM_INPUT_X) - base['x']
        my = bc.GetLong(c4d.BFM_INPUT_Y) - base['y']
        if res:
            if not (mx >= 0 and mx <= self.Width and my >= 0 and my <= self.Height):
                self.SetTimer(0)
                self.Redraw()    
    
    def DrawMsg(self, x1, y1, x2, y2, msg):
        """
        Draws the gadget
        """
        # double buffering
        self.OffScreenOn(x1,y1,x2,y2)
        # background & border
        self.DrawSetPen(self.ColBackground)
        self.DrawRectangle(x1,y1,x2,y2)
        if self.BorderWidth:
            self.DrawBorder(c4d.BORDER_THIN_IN, x1, y1, self.BorderWidth + 2, y2 - 1)
        # draw pattern
        for pid, state in self.Host.Pattern:
            x, y = self.GetRect(pid)
            self.DrawCell(x,y, state, self.IsFocus(x, y))   
    
    """--------------------------------------------------------------------------------------------
        Public methods
        -------------------------------------------------------------------------------------------"""

    def Update(self, cid = None):
        """
        Update the gadget.
        :param cid: A pattern id to toggle.
        """
        if cid and cid < self.Host.PatternSize:
            self.Host.Pattern[cid] = not self.Host.Pattern[cid]
        self.FitGadegt()
        self.Redraw()
        
    """--------------------------------------------------------------------------------------------
        Private methods
        -------------------------------------------------------------------------------------------"""

    def GetColors(self, force = False):
        """
        Set the drawing colors.
        :return : Bool
        """
        self.ColScale        = 1.0 / 255.0
        if self.IsEnabled() or force:
            self.ColBackground   = self.getColorVector(c4d.COLOR_BG)
            self.ColCellActive   = c4d.GetViewColor(c4d.VIEWCOLOR_ACTIVEPOINT) * 0.9
            self.ColCellFocus    = self.getColorVector(c4d.COLOR_BGFOCUS)
            self.ColCellInactive = self.getColorVector(c4d.COLOR_BGEDIT)
            self.ColEdgeDark     = self.getColorVector(c4d.COLOR_EDGEDK)
            self.ColEdgeLight    = self.getColorVector(c4d.COLOR_EDGELT)
        else:
            self.ColBackground   = self.getColorVector(c4d.COLOR_BG)
            self.ColCellActive   = self.getColorVector(c4d.COLOR_BG)
            self.ColCellFocus    = self.getColorVector(c4d.COLOR_BG)
            self.ColCellInactive = self.getColorVector(c4d.COLOR_BG)
            self.ColEdgeDark     = self.getColorVector(c4d.COLOR_EDGEDK)
            self.ColEdgeLight    = self.getColorVector(c4d.COLOR_EDGELT)
        return True

    def GetCellPen(self, state, isfocus):
        """
        Get the color for cell depending on its state.
        :param state   : The state
        :param isfocus : If the cell is hoovered.
        :return        : c4d.Vector()
        """
        if state: pen = self.ColCellActive
        else:     pen = self.ColCellInactive
        if self.IsEnabled() and isfocus:
            return (pen + c4d.Vector(2)) * 1/3
        else: return pen

    def DrawCell(self, x, y, state, isfocus):
        """
        Draws a gadget cell.
        :param x:       local x
        :param y:       local y
        :param state:   On/Off
        :param isfocus: MouseOver state
        """
        # left and top bright border
        self.DrawSetPen(self.ColEdgeLight)
        self.DrawLine(x , y, x + self.CellWidht , y)
        self.DrawLine(x , y, x , y + self.CellHeight)
        # bottom and right dark border
        self.DrawSetPen(self.ColEdgeDark)
        self.DrawLine(x , y + self.CellHeight - 1, x + self.CellWidht - 1, y + self.CellHeight -1)
        self.DrawLine(x + self.CellWidht - 1, y, x + self.CellWidht - 1, y + self.CellHeight - 1)
        # cell content
        self.DrawSetPen(self.GetCellPen(state, isfocus))
        self.DrawRectangle(x + 1, y + 1, x + self.CellWidht - 2, y + self.CellHeight - 2)

    def GetRect(self, pid, offset = 1):
        """
        Get the drawing rect for an array id.
        :param pid    : the pattern id
        :param offset : the pixel border offset
        :return       : int, int
        """
        pid = int(pid)
        col    = pid / self.CellPerColumn
        head = pid % self.CellPerColumn
        return self.CellWidht * head + offset, self.CellHeight * col + offset

    def GetID(self, x, y):
        """
        Get the array id for a coord within the gadget.
        :param x : local x
        :param y : local y
        :return  : int
        """
        col = (y - 1) / self.CellHeight
        head = (x - 1) / self.CellWidht
        return col * self.CellPerColumn  + head

    def IsFocus(self, x, y):
        """
        Test if the cell coords are under the cursor.
        :param x : local x
        :param y : local y
        :return  : bool
        """
        if (self.MouseX >= x and self.MouseX <= x + self.CellWidht and
            self.MouseY >= y and self.MouseY <= y + self.CellHeight):
            self.MouseX = c4d.NOTOK
            self.MouseY = c4d.NOTOK
            return True
        else: return False

    def InputEvent(self, msg):
        """
        Fetch and store mouse clicks
        :return : bool
        """
        if isinstance(msg, c4d.BaseContainer):
            if msg.GetLong(c4d.BFM_INPUT_DEVICE) == c4d.BFM_INPUT_MOUSE:
                if msg.GetLong(c4d.BFM_INPUT_CHANNEL) == c4d.BFM_INPUT_MOUSELEFT:
                    base = self.Local2Global()
                    if base:
                        x = msg.GetLong(c4d.BFM_INPUT_X) - base['x']
                        y = msg.GetLong(c4d.BFM_INPUT_Y) - base['y']
                        pid = self.GetID(x, y)
                        if pid <= self.Host.PatternSize:
                            self.Host.Pattern[pid] = not self.Host.Pattern[pid]
                            self.Redraw()
        return True

    def FitGadegt(self):
        """
        Fit the gadget size to the the array
        """
        oldHeight          = self.MinHeight
        self.CellPerColumn = int((self.Width - 2) / self.CellWidht)
        self.Columns       = math.ceil(self.Host.PatternSize / self.CellPerColumn) + 1
        self.MinHeight     = int(fhp.IDC_SELECTLOOP_GADGET_MINH * self.Columns) + 3
        self.MinWidht      = int(fhp.IDC_SELECTLOOP_GADGET_MINW)
        self.BorderWidth   = self.CellWidht * self.CellPerColumn
        if oldHeight != self.MinHeight: self.LayoutChanged()

    def getColorVector(self, cid):
        """
        Get a color vector from a color ID.
        :param cid : The color ID
        :return    : c4d.Vector()
        """
        dic = self.GetColorRGB(cid)
        if dic: return c4d.Vector(float(dic['r']) * self.ColScale, float(dic['g'])* self.ColScale, float(dic['b'])* self.ColScale)
        else: return c4d.Vector()


Create a new paste based on this one


Comments: