C4D插件:Py4D Icon Button UI Give Away

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

1481 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. VERSION = (1, 4)

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

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

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

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

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

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

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

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

  69. return locals()

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

  83. return True

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

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

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

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

  101. # GeUserArea Overrides

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  167. return catched

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

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

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

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


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

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

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

  202. dialog.AddUserArea(paramid, c4d.BFH_SCALEFIT)
  203. dialog.AttachUserArea(ua, paramid)
  204. return ua


  205. # Example
  206. # =======

  207. class Dialog(GeDialog):

  208. def __init__(self):
  209. super(Dialog, self).__init__()

  210. # GeDialog Overrides

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

  215. # Create a small example text + number field.
  216. self.GroupBegin(1000, c4d.BFH_SCALEFIT, 0, 1, "", 0, 0)
  217. self.AddStaticText(1001, 0, name="Value")
  218. self.AddEditNumberArrows(1002, 0)
  219. self.GroupEnd()

  220. # Create six different IconButton's
  221. self.GroupBegin(2000, c4d.BFH_SCALEFIT, 3, 0, "", 0, 0)

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

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

  235. # Create a button at the bottom of the dialog-
  236. self.GroupBegin(3000, c4d.BFH_SCALEFIT, 0, 1, "", 0, 0)
  237. self.AddStaticText(3001, c4d.BFH_SCALEFIT, name="") # Filler
  238. self.AddButton(3002, c4d.BFH_RIGHT, name="Close")
  239. self.GroupEnd()

  240. self.GroupEnd()
  241. self.GroupEnd() # Scroll Group
  242. return True

  243. def Command(self, paramid, msg):
  244. if paramid == 3002:
  245. self.Close()
  246. print "Button with ID", paramid, "pressed."
  247. return True

  248. dlg = Dialog()
  249. 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 2026
软件版本: 未知
系统平台: Win MAC
软件语言: 英文
插件来源: https://www.c4d.com.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

知识
问答
快速回复 返回顶部 返回列表