C4D插件:Py4D Icon Button UI Give Away 

2014-08-11 02:17 发布 | 作品版权归原作者所有,仅供参考学习,禁止商业使用!

818 3 0
C4D插件:Py4D Icon Button UI Give Away
C4D插件:Py4D Icon Button UI Give Away - C4D之家 - 2013-08-16-13_24_52-CINEMA-4D-R15.033-Studio-Untitled-1-_.png

What’s it?
Below you can find the source code for a user-area that implements a button-like interface, but additionally displays an icon on the left or right side. This icon can be a simple color or a bitmap.
IconButton UA Example
Source Code
The following is the source code for the above example. You can copy&paste the IconButton class and the AddIconButton function into your source code. As of version 1.2, the code is released under the WTFPL license, so do what the fuck you want with it!

  1. # Copyright (C) 2013, Niklas Rosenstein
  2. # http://niklasrosenstein.de/
  3. #
  4. # This work is free. You can redistribute it and/or modify it under the
  5. # terms of the Do What The Fuck You Want To Public License, Version 2,
  6. # as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
  7. #
  8. # Changelog:
  9. #
  10. # 1.1: Corrected action msg for Command() method, information like qualifiers
  11. #      and other input event information should now be correctly received in
  12. #      the Command() method.
  13. # 1.2: Changed license to WTFPL, do what the fuck you want with it!
  14. # 1.3: Thanks to Jet Kawa to tell me about the flickering when holding and
  15. #      dragging. As he suggested correctly, OffScreenOn() fixes this.
  16. # 1.4: Added mouse hover feature
  17. # 1.5: Fixed drawing algorithm to correctly update only parts of the user
  18. #      area. The x1, y1, x2, y2 only reflect the part of the user area
  19. #      that is being redrawn, not the actual dimensions of the area. Since
  20. #      these were used to caclculate width and height of the area, rendering
  21. #      issues occured when only parts of the user area were updated (eg.
  22. #      in a scroll group).
  23. #      The standard button has been renamed to "Close" and closes the dialog
  24. #      when clicked.

  25. import time
  26. import c4d
  27. from c4d.gui import GeUserArea, GeDialog

  28. class IconButton(GeUserArea):
  29.    
  30.     VERSION = (1, 4)

  31.     M_NOICON = 0
  32.     M_ICONLEFT = 1
  33.     M_ICONRIGHT = 2
  34.     M_FULL = 3

  35.     C_TEXT = c4d.COLOR_TEXT
  36.     C_BG = c4d.COLOR_BGEDIT
  37.     C_HIGHLIGHT = c4d.COLOR_BGFOCUS
  38.     C_BGPRESS = c4d.COLOR_BG

  39.     S_ICON = 24
  40.     S_PADH = 4
  41.     S_PADV = 4

  42.     def __init__(self, paramid, text, icon, mode=M_ICONLEFT):
  43.         super(IconButton, self).__init__()
  44.         self.paramid = paramid
  45.         self.text = text
  46.         self.icon = icon
  47.         self.mode = mode
  48.         self.pressed = False

  49.         self.last_t = -1
  50.         self.mouse_in = False
  51.         self.interval = 0.2

  52.     def _CalcLayout(self):
  53.         text_x = self.S_PADH
  54.         text_w = self.DrawGetTextWidth(str(self.text))
  55.         text_h = self.DrawGetFontHeight()
  56.         icon_x = self.S_PADH

  57.         width = text_w + self.S_PADH * 2
  58.         height = max([text_h, self.S_ICON]) + self.S_PADV * 2

  59.         draw_icon = True
  60.         if self.mode == self.M_ICONLEFT:
  61.             icon_x = self.S_PADH
  62.             text_x = self.S_PADH + self.S_ICON + self.S_PADH
  63.             width += self.S_ICON + self.S_PADH
  64.         elif self.mode == self.M_ICONRIGHT:
  65.             icon_x = self.GetWidth() - (self.S_PADH + self.S_ICON)
  66.             text_x = self.S_PADH
  67.             width += self.S_ICON + self.S_PADH
  68.         else:
  69.             draw_icon = False

  70.         return locals()

  71.     def _DrawIcon(self, icon, x1, y1, x2, y2):
  72.         # Determine if the icon is a simple color.
  73.         if not icon:
  74.             pass
  75.         if isinstance(icon, (int, c4d.Vector)):
  76.             self.DrawSetPen(icon)
  77.             self.DrawRectangle(x1, y1, x2, y2)
  78.         # or if it is a bitmap icon.
  79.         elif isinstance(icon, c4d.bitmaps.BaseBitmap):
  80.             self.DrawBitmap(icon, x1, y1, (x2 - x1), (y2 - y1),
  81.                             0, 0, icon.GetBw(), icon.GetBh(), c4d.BMP_ALLOWALPHA)
  82.         else:
  83.             return False

  84.         return True

  85.     def _GetHighlight(self):
  86.         delta = time.time() - self.last_t
  87.         return delta / self.interval

  88.     def _GetColor(self, v):
  89.         if isinstance(v, c4d.Vector):
  90.             return v
  91.         elif isinstance(v, int):
  92.             d = self.GetColorRGB(v)
  93.             return c4d.Vector(d['r'], d['g'], d['b']) ^ c4d.Vector(1.0 / 255)
  94.         else:
  95.             raise TypeError('Unexpected value of type %s' % v.__class__.__name__)

  96.     def _InterpolateColors(self, x, a, b):
  97.         if x < 0: x = 0.0
  98.         elif x > 1.0: x = 1.0

  99.         a = self._GetColor(a)
  100.         b = self._GetColor(b)
  101.         return a * x + b * (1 - x)

  102.     # GeUserArea Overrides

  103.     def DrawMsg(self, x1, y1, x2, y2, msg):
  104.         self.OffScreenOn() # Double buffering

  105.         # Draw the background color.
  106.         bgcolor = self.C_BG
  107.         if self.pressed:
  108.             bgcolor = self.C_BGPRESS
  109.         elif self.mode == self.M_FULL and self.icon:
  110.             bgcolor = self.icon
  111.         else:
  112.             h = self._GetHighlight()
  113.             ca, cb = self.C_HIGHLIGHT, self.C_BG
  114.             if not self.mouse_in:
  115.                 ca, cb = cb, ca

  116.             # Interpolate between these two colors.
  117.             bgcolor = self._InterpolateColors(h, ca, cb)

  118.         w, h = self.GetWidth(), self.GetHeight()
  119.         self._DrawIcon(bgcolor, 0, 0, w, h)

  120.         # Determine the drawing position and size of the
  121.         # colored icon and the text position.
  122.         layout = self._CalcLayout()

  123.         if layout['draw_icon']:
  124.             x = layout['icon_x']
  125.             y = min([h / 2 - self.S_ICON / 2, self.S_PADV])

  126.             # Determine if the icon_DrawIcon
  127.             self._DrawIcon(self.icon, x, y, x + self.S_ICON, y + self.S_ICON)

  128.         if 'draw_text':
  129.             self.DrawSetTextCol(self.C_TEXT, c4d.COLOR_TRANS)
  130.             x = layout['text_x']
  131.             y = max([h / 2 - layout['text_h'] / 2, self.S_PADV])
  132.             self.DrawText(str(self.text), x, y)

  133.     def GetMinSize(self):
  134.         layout = self._CalcLayout()
  135.         return layout['width'], layout['height']

  136.     def InputEvent(self, msg):
  137.         device = msg.GetLong(c4d.BFM_INPUT_DEVICE)
  138.         channel = msg.GetLong(c4d.BFM_INPUT_CHANNEL)

  139.         catched = False
  140.         if device == c4d.BFM_INPUT_MOUSE and channel == c4d.BFM_INPUT_MOUSELEFT:
  141.             self.pressed = True
  142.             catched = True

  143.             # Poll the event.
  144.             tlast = time.time()
  145.             while self.GetInputState(device, channel, msg):
  146.                 if not msg.GetLong(c4d.BFM_INPUT_VALUE): break

  147.                 x, y = msg.GetLong(c4d.BFM_INPUT_X), msg.GetLong(c4d.BFM_INPUT_Y)
  148.                 map_ = self.Global2Local()
  149.                 x += map_['x']
  150.                 y += map_['y']

  151.                 if x < 0 or y < 0 or x >= self.GetWidth() or y >= self.GetHeight():
  152.                     self.pressed = False
  153.                 else:
  154.                     self.pressed = True

  155.                 # Do not redraw all the time, this would be useless.
  156.                 tdelta = time.time() - tlast
  157.                 if tdelta > (1.0 / 30): # 30 FPS
  158.                     tlast = time.time()
  159.                     self.Redraw()

  160.             if self.pressed:
  161.                 # Invoke the dialogs Command() method.
  162.                 actionmsg = c4d.BaseContainer(msg)
  163.                 actionmsg.SetId(c4d.BFM_ACTION)
  164.                 actionmsg.SetLong(c4d.BFM_ACTION_ID, self.paramid)
  165.                 self.SendParentMessage(actionmsg)

  166.             self.pressed = False
  167.             self.Redraw()

  168.         return catched

  169.     def Message(self, msg, result):
  170.         if msg.GetId() == c4d.BFM_GETCURSORINFO:
  171.             if not self.mouse_in:
  172.                 self.mouse_in = True
  173.                 self.last_t = time.time()
  174.                 self.SetTimer(30)
  175.                 self.Redraw()
  176.         return super(IconButton, self).Message(msg, result)

  177.     def Timer(self, msg):
  178.         self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, msg)
  179.         g2l = self.Global2Local()
  180.         x = msg[c4d.BFM_INPUT_X] + g2l['x']
  181.         y = msg[c4d.BFM_INPUT_Y] + g2l['y']

  182.         # Check if the mouse is still inside the user area or not.
  183.         if x < 0 or y < 0 or x >= self.GetWidth() or y >= self.GetHeight():
  184.             if self.mouse_in:
  185.                 self.mouse_in = False
  186.                 self.last_t = time.time()

  187.         h = self._GetHighlight()
  188.         if h < 1.0:
  189.             self.Redraw()
  190.         elif not self.mouse_in:
  191.             self.Redraw()
  192.             self.SetTimer(0)
  193.         

  194. def AddIconButton(dialog, paramid, text, icon, mode=IconButton.M_ICONLEFT,
  195.                   auto_store=True):
  196.     r"""
  197.     Creates an Icon Button on the passed dialog.
  198.     """

  199.     ua = IconButton(paramid, text, icon, mode)

  200.     if auto_store:
  201.         if not hasattr(dialog, '_icon_buttons'):
  202.             dialog._icon_buttons = []
  203.         dialog._icon_buttons.append(ua)

  204.     dialog.AddUserArea(paramid, c4d.BFH_SCALEFIT)
  205.     dialog.AttachUserArea(ua, paramid)
  206.     return ua


  207. # Example
  208. # =======

  209. class Dialog(GeDialog):

  210.     def __init__(self):
  211.         super(Dialog, self).__init__()

  212.     # GeDialog Overrides

  213.     def CreateLayout(self):
  214.         self.SetTitle("Dialog")
  215.         self.ScrollGroupBegin(9000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, c4d.SCROLLGROUP_HORIZ | c4d.SCROLLGROUP_VERT, 0, 0)
  216.         self.GroupBegin(0, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0)

  217.         # Create a small example text + number field.
  218.         self.GroupBegin(1000, c4d.BFH_SCALEFIT, 0, 1, "", 0, 0)
  219.         self.AddStaticText(1001, 0, name="Value")
  220.         self.AddEditNumberArrows(1002, 0)
  221.         self.GroupEnd()
  222.    
  223.         # Create six different IconButton's
  224.         self.GroupBegin(2000, c4d.BFH_SCALEFIT, 3, 0, "", 0, 0)

  225.         # With an icon.
  226.         path = 'C:/Users/niklas/Desktop/foo.png'
  227.         bmp = c4d.bitmaps.BaseBitmap()
  228.         bmp.InitWith(path)
  229.         AddIconButton(self, 2001, "Image Icon Left", bmp, IconButton.M_ICONLEFT)
  230.         AddIconButton(self, 2002, "Image Icon Right", bmp, IconButton.M_ICONRIGHT)
  231.         AddIconButton(self, 2003, "No Icon Button", None, IconButton.M_NOICON)

  232.         # With a color.
  233.         color = c4d.Vector(0.2, 0.5, 0.3)
  234.         AddIconButton(self, 2004, "Color Left", color, IconButton.M_ICONLEFT)
  235.         AddIconButton(self, 2005, "Color Right", color, IconButton.M_ICONRIGHT)
  236.         AddIconButton(self, 2006, "Color Full", c4d.COLOR_TEXTFOCUS, IconButton.M_FULL)
  237.         self.GroupEnd()

  238.         # Create a button at the bottom of the dialog-
  239.         self.GroupBegin(3000, c4d.BFH_SCALEFIT, 0, 1, "", 0, 0)
  240.         self.AddStaticText(3001, c4d.BFH_SCALEFIT, name="") # Filler
  241.         self.AddButton(3002, c4d.BFH_RIGHT, name="Close")
  242.         self.GroupEnd()
  243.         
  244.         self.GroupEnd()
  245.         self.GroupEnd() #  Scroll Group
  246.         return True

  247.     def Command(self, paramid, msg):
  248.         if paramid == 3002:
  249.             self.Close()
  250.         print "Button with ID", paramid, "pressed."
  251.         return True

  252. dlg = Dialog()
  253. dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=180)
复制代码
The buttons act just like normal Cinema 4D buttons. If the user presses the button, you will receive a call to your GeDialog.Command() method with the button’s ID. The IconButton interface supports three different types of icons and four different display modes.

Icon types

The icon is passed as the foruth parameter to AddIconButton()

Color constant (eg. c4d.COLOR_TEXTFOCUS)
Vector color (eg. c4d.Vector(1.0, 0.66, 0.12'))
BaseBitmap instance
Display modes

The display mode is passed as the fifth argument to AddIconButton(). The default value is IconButton.M_ICONLEFT.

IconButton.M_NOICON: Display no icon at all, just the text
IconButton.M_ICONLEFT: Display the icon on the left-hand side
IconButton.M_ICONLEFT: Display the icon on the right-hand side
IconButton.M_FULL: Scale the icon to the full size of the button.

  1. def get_some_basebitmap():
  2.     bmp = c4d.bitmaps.BaseBitmap()
  3.     bmp.InitWith('C:/Users/niklas/Desktop/foo.png')
  4.     return bmp

  5. class Dialog(GeDialog):

  6.     def CreateLayout(self):
  7.         AddIconButton(self, 1000, "Button One", c4d.COLOR_SYNTAX_STRING)
  8.         AddIconButton(self, 1001, "Button Two", c4d.Vector(1.0, 0.66, 0.12), IconButton.M_ICONRIGHT)
  9.         AddIconButton(self, 1002, "Button Three", get_some_basebitmap(), IconButton.M_ICONRIGHT)
  10.         AddIconButton(self, 1003, "Button Four", None, IconButton.M_NOICON)
  11.         return True

  12.     def Command(self, paramid, msg):
  13.         if paramid == 1000:
  14.             print "Button One pressed."
  15.         # ...
  16.         return True
复制代码
Adjustments

You can do any adjustments to the code you like to fit your personal needs. For example, if you want the icon to be of another size, just modify the IconButton.S_ICON value either directly on the IconButton class or on an instance.


B Color Smilies

Comment :3

插件脚本
软件性质:  
适用版本: C4D R15 - C4D R16 - C4D R17 - C4D R18 - C4D R19 - C4D R20 - C4D R21 - C4D S22 - C4D R23 - C4D S24 - C4D R25 - C4D S26 - C4D 2023 - C4D 2024 - C4D 2025
软件版本: 未知
系统平台: Win MAC 
软件语言: 英文 
插件来源: https://www.c4d.cn/c4dsoft.html

相关推荐

百套精美Kitbash3D模型专题合集下载
时尚卡通办公室人物C4D立体图标工程下载Cinema 4D Fashion Cartoon Office Character 3D Icon Project Download
C4D科技新闻片头电视栏目频道包装动画工程下载Cinema 4D Technology News Headline TV Program Channel Packaging Animation Project Download
关闭

C4D精选推荐 /10

智能
客服
快速回复 返回顶部 返回列表