class Mafia4ds_GlobalMeshProperties(types.PropertyGroup): Type: props.EnumProperty( name="Type", items=[ ("0x01", "Visual", ""), #("0x05", "Sector", ""), ("0x06", "Dummy", ""), #("0x07", "Target", ""), #("0x0a", "Joint", "") ]) VisualType: props.EnumProperty( name="Visual Type", items=[ ("0x00", "Mesh", ""), #("0x02", "SingleMesh", ""), #("0x03", "SingleMorph", ""), #("0x04", "Billboard", ""), #("0x05", "Morph", ""), #("0x06", "Glow", ""), #("0x08", "Mirror", "") ]) Parameters: props.StringProperty(name="Parameters", default="") RenderFlags: props.IntProperty(name="Render Flags", default=0x2a00) CullingFlags: props.IntProperty(name="Culling Flags", default=0x09) InstanceIdx: props.IntProperty(name="Instance Idx", default=0) LodRatio: props.FloatProperty(name="Lod Ratio", default=0.0)
class RP_OT_MailQuickSetup(bpy.types.Operator): bl_idname = 'renderplus.mail_quick_setup' bl_label = 'Mail quick setup' bl_description = 'Setup email automatically' bl_options = {'REGISTER'} provider = prop.EnumProperty(items=(('GMAIL', 'Gmail', ''), ('YAHOO', 'Yahoo', ''), ('LIVE', 'Live', '')), default='GMAIL') def execute(self, context): if self.provider == 'GMAIL': data.prefs['mail_ssl'] = True data.prefs['mail_server'] = 'smtp.gmail.com' data.prefs['mail_user'] = '******' if self.provider == 'YAHOO': data.prefs['mail_ssl'] = True data.prefs['mail_server'] = 'smtp.mail.yahoo.com' data.prefs['mail_user'] = '******' if self.provider == 'LIVE': data.prefs['mail_ssl'] = False data.prefs['mail_server'] = 'smtp.live.com' data.prefs['mail_user'] = '******' data.prefs['mail_password'] = '******' return {'FINISHED'}
class TemplateAttributeDefault(types.PropertyGroup): @property def hash(self): return str(hash(getattr(self, self.value_name))) @property def value_name(self): return "value_{}".format(self.type.lower()) @property def value(self): return getattr(self, self.value_name) @value.setter def value(self, value): setattr(self, self.value_name, value) name = props.StringProperty( description="Name of template attribute default value") type = props.EnumProperty( description="Data type of template attribute default value", items=TYPE_ENUMS) value_int = props.IntProperty() value_float = props.FloatProperty() value_string = props.StringProperty() value_bool = props.BoolProperty()
class RPCGroup(types.PropertyGroup): """PropertyGroup for RPC calls""" name = props.StringProperty("name", default="RPC", description="Name of RPC call") reliable = props.BoolProperty(default=False, description="Guarantee delivery of RPC call") simulated = props.BoolProperty( default=False, description="Allow execution for simulated proxies") target = props.EnumProperty(items=NETWORK_ENUMS, description="Netmode of RPC target") arguments = props.CollectionProperty(type=RPCArgumentGroup) arguments_index = props.IntProperty()
class ParameterGroup(types.PropertyGroup): name = props.StringProperty(name="Name") data_type = props.EnumProperty(items=enum_data_types) value_str = props.StringProperty() value_int = props.IntProperty() value_bool = props.BoolProperty() value_float = props.FloatProperty() @property def value(self): return getattr(self, "value_{}".format(self.data_type)) @value.setter def value(self, value): setattr(self, "value_{}".format(self.data_type), value)
class SnapToObject(bpy.types.Operator): bl_idname = "view3d.snap_to_object" bl_label = "Snap To Object" axesEnum = props.EnumProperty( items=(("X", "x", "snap to x-axis"), ("Y", "y", "snap to y-axis"), ("Z", "z", "snap to z-axis"), ("-X", "-x", "snap to -x axis"), ("-Y", "-y", "snap to -y axis"), ("-Z", "-z", "snap to -z axis")), name="Snap Axis:", default="X", update=onEnumUpdated) axesOffset = props.FloatVectorProperty(name="Offset:", description="", default=(0, 0, 0), update=onOffsetUpdated, step=1) # Check if user has selected exactly 2 objects @classmethod def poll(self, context): return len(context.selected_objects) == 2 def invoke(self, context, event): global objOne global objTwo offset = { "x": self.axesOffset[0], "y": self.axesOffset[1], "z": self.axesOffset[2] } objOne = context.active_object objTwo = getSecondObject() snapMeshToLocation(objOne, objTwo, offset, self.axesEnum) return context.window_manager.invoke_props_dialog(self) def execute(self, context): global objOne global objTwo objOne = None objTwo = None initLocation = None return {"FINISHED"}
class Mafia4ds_ExportDialog(types.Operator, io_utils.ExportHelper): "Export Mafia 4ds model." bl_idname = "mafia4ds.export" bl_text = "Mafia (.4ds)" bl_label = "Export 4DS" filename_ext = ".4ds" filter_glob: props.StringProperty(default="*.4ds", options={'HIDDEN'}, maxlen=255) IncludeMeshes: props.EnumProperty(name="Include Meshes", items=[("0", "All in Collection", ""), ("1", "Visible Only", "")], default="0") def execute(self, context): exporter = Mafia4ds_Exporter(self) return exporter.Export(self.filepath)
class LOGIC_OT_set_states_from_visible(types.Operator): """Write currently visible states to mask for this netmode""" bl_idname = "network.set_states_from_visible" bl_label = "Save logic states for this netmode" mode = props.EnumProperty(items=(("states", "states", "states"), ("simulated_states", "simulated_states", "simulated_states")), default="states") @classmethod def poll(cls, context): return context.active_object is not None def execute(self, context): obj = context.active_object mode_states = obj.states[obj.states_index] states = getattr(mode_states, self.mode) states[:] = obj.game.states_visible return {'FINISHED'}
class _PieMenu(ExecuteString): # {idname: index, ...} _last_item_index = {} idname = props.StringProperty(name="ID Name", get=prop_idname_get, set=prop_idname_set) active = props.BoolProperty(name="Active", description="Activate or deactivate menu", default=True) show_expanded = props.BoolProperty() poll_string = props.StringProperty( name="Poll", description="e.g.\nreturn context.mode == 'EDIT_MESH'", ) init_string = props.StringProperty(name="Init", ) label = props.StringProperty( name="Label", description="Menu title", ) draw_type = props.EnumProperty(name="Draw Type", items=[('SIMPLE', "Simple", ""), ('BOX', "Box", ""), ('CIRCLE', "Circle", "")], default='BOX', get=prop_draw_type_get, set=prop_draw_type_set) icon_scale = props.FloatProperty( name="Icon Scale", default=1.0, min=1.0, max=10.0, ) icon_expand = props.FloatProperty( name="Icon Expand", default=0.0, min=-1.0, max=1.0, ) radius = props.IntProperty(name="Radius", description="Pie menu size in pixels", min=0, default=0, get=prop_radius_get, set=prop_radius_set) quick_action = props.EnumProperty( name="Quick Action", items=[('NONE', "None", ""), ('LAST', "Last", ""), ('FIXED', "Fixed", "")], default='NONE', ) quick_action_index = props.IntProperty( name="Quick Action Index", description="", min=0, max=16, default=0, ) highlight = props.EnumProperty( name="Highlight", items=[('NONE', "None", ""), ('LAST', "Last", ""), ('FIXED', "Fixed", "")], default='NONE', ) highlight_index = props.IntProperty( name="Highlight Index", description="", min=0, max=16, default=0, ) translate = props.BoolProperty( name="Translate", default=True, ) items_num = props.EnumProperty( name="Number of Items", items=[('4', "4", ""), ('8', "8", ""), ('16', "16", "")], default='8', ) # menu_items = props.CollectionProperty( # name="Items", type=PieMenuItem) menu_items = [] # ↑継承で上書きする場合に問題が発生する item_order = props.EnumProperty( name="Item Order", items=[ ('CW', "Clockwise", "[0, 1, 2, 3, 4, 5, 6, 7]"), ('CW6', "Clockwise 6", "[4, 5, 6, 7, 0, 1, 2, 3] Start from six o'clock"), ('OFFICIAL', "Official", "[3, 5, 1, 7, 2, 6, 0, 4]"), ('MODIFIED', "Modified", "[3, 7, 1, 5, 2, 4, 0, 6]"), ], default='OFFICIAL', ) next = props.StringProperty( name="Next Menu", description="Shortcut: wheel down", ) prev = props.StringProperty( name="Previous Menu", description="Shortcut: wheel up", ) # 上書き radius_ = props.IntProperty() quick_action_index_ = props.IntProperty() highlight_index_ = props.IntProperty() # 描画時に使用 active_index = props.IntProperty(default=-1) active_item_index = props.IntProperty(default=-1) # -1: None is_valid_click = props.BoolProperty(default=True) co = props.FloatVectorProperty(subtype='XYZ', size=2) current_items_type = props.StringProperty( ) # "", "shift", "ctrl", "alt", "oskey" @property def item_boundary_angles(self): return self["item_boundary_angles"] @item_boundary_angles.setter def item_boundary_angles(self, value): self["item_boundary_angles"] = value @property def current_items(self): mod = self.current_items_type items = [] for item in self.menu_items: if item.active: if mod == "shift" and item.shift.active: items.append(item.shift) elif mod == "ctrl" and item.ctrl.active: items.append(item.ctrl) else: items.append(item) ls = [] for i in self["current_items_indices"]: if i == -1: ls.append(None) else: item = items[i] if item.type == 'SPACER': ls.append(None) else: ls.append(item) return ls def poll(self, context, event=None): if self.poll_string: return bool(self.exec_string("poll_string", context, event)) else: return True def init(self, context): if self.init_string: self.exec_string("init_string", context, None) @staticmethod def calc_item_indices(item_order, num): def sort_cw(): for n in (4, 8, 16): if num <= n: return list(range(num)) + [-1] * (n - num) def sort_cw6(): indices = sort_cw() n = int(len(indices) / 2) indices = indices[n:] + indices[:n] return indices def sort_official_modified(modified=False): if modified: if num <= 4: order = [3, 1, 2, 0] elif num <= 8: order = [3, 7, 1, 5, 2, 4, 0, 6] else: # if num <= 16: order = [ 3, 15, 7, 11, 1, 9, 5, 13, 2, 12, 4, 8, 0, 10, 6, 14 ] else: if num <= 4: order = [3, 1, 2, 0] elif num <= 8: order = [3, 5, 1, 7, 2, 6, 0, 4] else: # if num <= 16: order = [ 3, 15, 5, 11, 1, 9, 7, 13, 2, 12, 6, 8, 0, 10, 4, 14 ] indices = list(range(num)) + [-1] * (len(order) - num) return [indices[i] for i in order] if num > 16: raise ValueError() if item_order == 'CW': indices = sort_cw() elif item_order == 'CW6': indices = sort_cw6() elif item_order == 'OFFICIAL': indices = sort_official_modified() else: # elif self.item_order == 'MODIFIED': indices = sort_official_modified(True) return indices def update_current_items(self, context, op): mod = op.last_modifier() self.current_items_type = mod items = [] for item in self.menu_items: if item.active: if mod == "shift" and item.shift.active: items.append(item.shift) elif mod == "ctrl" and item.ctrl.active: items.append(item.ctrl) else: items.append(item) items = items[:16] num = len(items) indices = self.calc_item_indices(self.item_order, num) self["current_items_indices"] = indices # quick_action_index, highlight_index if num <= 4: n = 4 elif num <= 8: n = 8 else: # if num <= 16: n = 16 indices_ = self.calc_item_indices(self.item_order, n) for attr in ["quick_action_index", "highlight_index"]: index = getattr(self, attr) if 0 <= index < num: setattr(self, attr + "_", indices_.index(index)) # poll() for i in indices: if i != -1: item = items[i] item.enabled = item.poll(context) # calc boundaries num = len(indices) pie_angle = math.pi * 2 / num item_boundary_angles = [[0.0, 0.0] for i in range(num)] current_items = self.current_items for i, item in enumerate(current_items): if not item: continue angle = math.pi * 0.5 - pie_angle * i if angle < -1e-5: angle += math.pi * 2 # CCW side for k in range(1, num + 1): if current_items[i - k]: ang = angle + pie_angle * k * 0.5 item_boundary_angles[i][0] = ang break # CW side for k in range(1, num + 1): if current_items[(i + k) % num]: ang = angle - pie_angle * k * 0.5 item_boundary_angles[i][1] = ang break self.item_boundary_angles = item_boundary_angles def correct_radius(self): """Item同士が重ならないようにMenu半径を大きくする。 値は redius_ に格納する """ addon_prefs = pie_menu.addon_preferences radius = self.get("radius", addon_prefs.menu_radius) current_items = self.current_items if len(current_items) == 0: return pie_angle = math.pi * 2 / len(current_items) widget_unit = vawm.widget_unit() if self.draw_type == 'SIMPLE': n = len(current_items) / 4 r = widget_unit * (n - 0.5) + addon_prefs.item_min_space * n self.radius_ = max(r, radius) else: icon_box_size = widget_unit * self.icon_scale if self.draw_type == 'CIRCLE': # >>> (r + icon_size / 2) * math.sin(pie_angle / 2) = \ # (icon_size + item_min_space) / 2 r = (icon_box_size + addon_prefs.item_min_space) / 2 / \ math.sin(pie_angle / 2) - icon_box_size / 2 self.radius_ = max(r, radius) else: # 'BOX' # >>> (r + icon_size / 2) * math.sin(pie_angle) = \ # icon_size + item_min_space r = (icon_box_size + addon_prefs.item_min_space) / \ math.sin(pie_angle) - icon_box_size / 2 self.radius_ = max(r, radius) def calc_active(self, mco): """:rtype: (int, int)""" addon_prefs = pie_menu.addon_preferences current_items = self.current_items if not current_items: return -1, -1 vec = mco - self.co if vec.length < addon_prefs.menu_radius_center: active_index = -1 else: idx = 0 for i, item in enumerate(current_items): if not item: continue idx = i a1, a2 = self.item_boundary_angles[i] a1 += 1e-4 a2 -= 1e-4 v1 = (math.cos(a1), math.sin(a1)) v2 = (math.cos(a2), math.sin(a2)) if cross2d(v2, vec) >= 0 and cross2d(vec, v1) >= 0: active_index = i break else: active_index = idx active_item_index = -1 if active_index == -1: if self.quick_action == 'LAST': last_item_index = self.get_last_item_index() if 0 <= last_item_index < len(current_items): item = current_items[last_item_index] if item: active_item_index = last_item_index elif self.quick_action == 'FIXED': if 0 <= self.quick_action_index_ < len(current_items): item = current_items[self.quick_action_index_] if item: active_item_index = self.quick_action_index_ else: item = current_items[active_index] if item: active_item_index = active_index return active_index, active_item_index def update_active(self, mco, mco_press): """active_indexとactive_itemを更新。 """ self.active_index, self.active_item_index = self.calc_active(mco) if mco_press is not None: i, _ = self.calc_active(mco_press) self.is_valid_click = i == self.active_index else: self.is_valid_click = True def get_last_item_index(self): return self._last_item_index.get(self.idname, -1) def set_last_item_index(self, index): self._last_item_index[self.idname] = index def clear_last_item_idnex(self): if self.idname in self._last_item_index: del self._last_item_index[self.idname] def draw_ui(self, context, layout): if self.show_expanded: main_layout = layout.box().column() else: main_layout = layout.column() main_layout.context_pointer_set("pie_menu", self) row = main_layout.row() icon = 'TRIA_DOWN' if self.show_expanded else 'TRIA_RIGHT' sub = row.row() sub.alignment = 'LEFT' sub.prop(self, "show_expanded", text="", icon=icon, emboss=False) sub.prop(self, "active", text="") sub = row.row() if not self.active: sub.active = False sub.prop(self, "label", text="") sub2 = sub.row() """:type: bpy.types.UILayout""" if not self.idname: sub2.alert = True sub2.prop(self, "name", text="ID Name") sub = row.row(align=True) sub.alignment = 'RIGHT' sub1 = sub.row(align=True) op = sub1.operator(ops.WM_OT_pie_menu_menu_copy.bl_idname, text="", icon='COPYDOWN') sub2 = sub.row(align=True) op = sub2.operator(ops.WM_OT_pie_menu_menu_paste.bl_idname, text="", icon='PASTEDOWN') sub1 = sub.row(align=True) op = sub1.operator(ops.WM_OT_pie_menu_menu_move.bl_idname, text="", icon='TRIA_UP') op.direction = -1 sub2 = sub.row(align=True) op = sub2.operator(ops.WM_OT_pie_menu_menu_move.bl_idname, text="", icon='TRIA_DOWN') op.direction = 1 sub.operator(ops.WM_OT_pie_menu_menu_remove.bl_idname, text="", icon='X') if not self.show_expanded: return column = main_layout.column() row = column.row() split = row.split() sp_column1 = split.column() sp_column2 = split.column() draw_property(sp_column1, self, "draw_type", unset=True, context_attr="pie_menu") draw_property(sp_column1, self, "icon_scale") draw_property(sp_column1, self, "icon_expand") draw_property(sp_column1, self, "radius", unset=True, context_attr="pie_menu") draw_property(sp_column1, self, "translate") draw_property(sp_column1, self, "item_order") sp_column2.label("Quick Action:") draw_property(sp_column2, self, "quick_action", text="", context_attr="pie_menu") sub = sp_column2.row() if self.quick_action != 'FIXED': sub.active = False draw_property(sub, self, "quick_action_index", context_attr="pie_menu") sp_column2.label("Highlight:") draw_property(sp_column2, self, "highlight", text="", context_attr="pie_menu") sub = sp_column2.row() if self.highlight != 'FIXED': sub.active = False draw_property(sub, self, "highlight_index", context_attr="pie_menu") draw_separator(column) draw_property(column, self, "poll_string", "Poll Function", paste=True, context_attr="pie_menu") draw_property(column, self, "init_string", "Init Function", paste=True, context_attr="pie_menu") draw_separator(column) column = main_layout.column() for i, item in enumerate(self.menu_items): col = column.column() item.draw_ui(context, col, self, i) row = column.row() row.alignment = 'LEFT' op = row.operator(ops.WM_OT_pie_menu_item_add.bl_idname, text="Add Item", icon='ZOOMIN')
class _PieMenuItem(ExecuteString): active = props.BoolProperty( name="Active", description="Activate or deactivate item", default=True, ) show_expanded = props.BoolProperty() type = props.EnumProperty( name="Type", items=[('OPERATOR', "Operator", ""), ('MENU', "Menu", ""), ('ADVANCED', "Advanced", ""), ('SPACER', "Spacer", "")], default='ADVANCED', ) poll_string = props.StringProperty( name="Poll", get=prop_poll_get, set=prop_poll_set, ) execute_string = props.StringProperty(name="Execute", ) # operator_arguments更新用 ensure_argument = props.StringProperty(get=prop_ensure_argument_get, ) operator = props.StringProperty(name="Operator", description="e.g. 'transform.translate'", get=prop_operator_get, set=prop_operator_set, update=prop_operator_update) # operator_arguments = props.CollectionProperty( # type=OperatorArgument) operator_arguments = [] # ↑継承で上書きする場合に問題が発生する label = props.StringProperty( name="Label", description="Item label", get=prop_label_get, set=prop_label_set, ) description = props.StringProperty( name="Description", get=prop_description_get, set=prop_description_set, ) icon = props.StringProperty(name="Icon", description="Item icon") menu = props.StringProperty(name="Menu", ) undo_push = props.BoolProperty(name="Undo Push", ) shortcut = props.StringProperty("Shortcut", ) translate = props.BoolProperty( name="Translate", default=True, ) # 描画時に使う enabled = props.BoolProperty() @property def icon_box_rect(self): return self.get("icon_box_rect", []) @icon_box_rect.setter def icon_box_rect(self, value): self["icon_box_rect"] = value @property def text_box_rect(self): return self.get("text_box_rect", []) @text_box_rect.setter def text_box_rect(self, value): self["text_box_rect"] = value def get_execute_string(self): if self.type == 'OPERATOR': if not verify_operator_string(self.operator): return "" arg_string_list = [] for arg in self.operator_arguments: if arg.name in arg: value = getattr(arg, arg.name) if isinstance(value, str): value = "'" + value + "'" else: value = str(value) arg_name = "".join(arg.name.split("."))[1:] arg_string_list.append(arg_name + "=" + value) text = self.operator + "(" + ", ".join(arg_string_list) + ")" return text elif self.type == 'ADVANCED': return self.execute_string else: return "" def draw_ui(self, context, layout, menu, index, sub_item_type=""): if self.show_expanded: main_layout = layout.box().column() else: main_layout = layout.column() main_layout.context_pointer_set("pie_menu_item", self) row = main_layout.row() pcol = custom_icons.preview_collections["main"] if not sub_item_type: icon = 'TRIA_DOWN' if self.show_expanded else 'TRIA_RIGHT' sub = row.row() sub.alignment = 'LEFT' sub.prop(self, "show_expanded", text="", icon=icon, emboss=False) sub.prop(self, "active", text="") # draw direction icon items = {} i = 0 for item in menu.menu_items: if item.active: items[item] = i i += 1 if i == 16: break if self not in items: icon = pcol["empty"] sub.label(text="", icon_value=icon.icon_id) else: num = len(items) if num <= 4: num = 4 names = list(range(0, 16, 4)) elif num <= 8: num = 8 names = list(range(0, 16, 2)) else: num = 16 names = list(range(0, 16, 1)) item_indices = menu.calc_item_indices(menu.item_order, num) name = str(names[item_indices.index(items[self])]) icon = pcol[name] sub.label(text="", icon_value=icon.icon_id) sp = row.split(0.2) if not self.active: sp.active = False sub1 = sp.row() sp_sub = sp.split(0.5) sub2 = sp_sub.row() sub3 = sp_sub.row(align=True) sub3_1 = sub3.row(align=True) sub3_1.alignment = 'LEFT' sub3_2 = sub3.row(align=True) sub3_3 = sub3.row(align=True) sub1.prop(self, "type", text="") if self.type != 'SPACER': draw_property(sub2, self, "label", "", unset=True, context_attr="pie_menu_item", active=True) if self.icon in all_icon_identifiers: icon_value = all_icon_identifiers[self.icon] elif self.icon in pcol: icon_value = pcol[self.icon].icon_id elif self.icon.endswith((".png", ".jpg")): try: preview = pcol.load(self.icon, self.icon, 'IMAGE') icon_value = preview.icon_id except: # no exception ? icon_value = pcol["empty"].icon_id sub3_2.alert = True else: if self.icon: sub3_2.alert = True icon_value = pcol["empty"].icon_id sub3_1.label(text="", icon_value=icon_value) sub3_2.prop(self, "icon", text="") sub3_3.operator(ops.WM_OT_pie_menu_item_icon_search.bl_idname, text="", icon='VIEWZOOM') op = sub3_3.operator( ops.WM_OT_pie_menu_item_icon_file_search.bl_idname, text="", icon='FILE_IMAGE') op.display_type = 'THUMBNAIL' # if self.icon and os.path.exists(self.icon): if self.icon: op.filepath = self.icon sub = row.row(align=True) sub.alignment = 'RIGHT' sub1 = sub.row(align=True) op = sub1.operator(ops.WM_OT_pie_menu_item_copy.bl_idname, text="", icon='COPYDOWN') sub2 = sub.row(align=True) op = sub2.operator(ops.WM_OT_pie_menu_item_paste.bl_idname, text="", icon='PASTEDOWN') if not sub_item_type: # sub = row.row(align=True) # sub.alignment = 'RIGHT' sub1 = sub.row(align=True) op = sub1.operator(ops.WM_OT_pie_menu_item_move.bl_idname, text="", icon='TRIA_UP') op.direction = -1 sub2 = sub.row(align=True) op = sub2.operator(ops.WM_OT_pie_menu_item_move.bl_idname, text="", icon='TRIA_DOWN') op.direction = 1 # sub = row.row(align=True) # sub.alignment = 'RIGHT' sub.operator(ops.WM_OT_pie_menu_item_remove.bl_idname, text="", icon='X') if not self.show_expanded: return column = main_layout.column() if self.type == 'SPACER': return elif self.type == 'MENU': column.prop(self, "menu") elif self.type == 'OPERATOR': _ = self.ensure_argument row = column.row() is_valid = verify_operator_string(self.operator) if self.operator != "": if not is_valid: row.alert = True sub = row.row(align=True) sub1 = sub.row(align=True) if self.operator and not oputils.get_operator_rna(self.operator): sub1.alert = True sub1.prop(self, "operator") # 重いのでコメントアウト # sub.operator(ops.WM_OT_pie_menu_item_operator_search.bl_idname, # text="", icon='VIEWZOOM') if is_valid and self.operator_arguments: box = column.box() flow = box.column_flow(2) for arg in self.operator_arguments: arg.draw_ui(context, flow) else: draw_property(column, self, "execute_string", "Execute", paste=True, context_attr="pie_menu_item") draw_property(column, self, "poll_string", "Poll", unset=True, paste=True, context_attr="pie_menu_item", active=True) draw_property(column, self, "description", unset=True, paste=True, context_attr="pie_menu_item", active=True) column.prop(self, "menu") column.prop(self, "undo_push") column.prop(self, "shortcut") # draw_property(column, self, "translate", unset=True, # context_attr="pie_menu_item") column.prop(self, "translate") for key in ["shift", "ctrl"]: if hasattr(self, key): sub_item = getattr(self, key) row = main_layout.row() icon = 'TRIA_DOWN' if sub_item.show_expanded else 'TRIA_RIGHT' sub = row.row() sub.alignment = 'LEFT' sub.prop(sub_item, "show_expanded", text="", icon=icon, emboss=False) sub.prop(sub_item, "active", text="") sub = row.row() if not sub_item.active: sub.active = False sub.label(key.title() + ":", translate=False) if sub_item.show_expanded: column = main_layout.column() col = indented_layout(column) sub_item.draw_ui(context, col, menu, index, sub_item_type=key) def poll(self, context, event=None): if self.poll_string: return bool(self.exec_string("poll_string", context, event)) else: return True def execute(self, context, event=None): if self.type == 'OPERATOR': text = self.get_execute_string() return self.exec_string_data(text, context, event) elif self.type == 'ADVANCED': return self.exec_string("execute_string", context, event) else: return None
class ParallelRenderPropertyGroup(types.PropertyGroup): def update(self, context): addon_props = context.user_preferences.addons[__name__].preferences if not addon_props.ffmpeg_valid and self.concatenate: LOGGER.info( "ParallelRenderPropertyGroup forcing concatenate to false") self.concatenate = False self.clean_up_parts = False if not self.concatenate: self.clean_up_parts = False last_run_result = props.EnumProperty( items=[ # (identifier, name, description, icon, number) ('done', '', ''), ('pending', '', ''), ('failed', '', ''), ], name="Render Batch Size") batch_type = props.EnumProperty( items=[ # (identifier, name, description, icon, number) ('parts', 'No. parts', 'Render in given number of batches (automatically splits it)'), ('fixed', 'Fixed', 'Render in fixed size batches'), ], name="Render Batch Size") max_parallel = props.IntProperty( name="Number of background worker Blender instances", min=1, default=cpu_count() - 1, max=10000) overwrite = props.BoolProperty( name="Overwrite existing files", default=True, ) mixdown = props.BoolProperty( name="Mixdown sound", default=True, ) concatenate = props.BoolProperty( name="Concatenate output files into one", update=lambda self, context: self.update(context), ) clean_up_parts = props.BoolProperty( name="Clean up partial files (after successful concatenation)", ) fixed = props.IntProperty(name="Number of frames per batch", min=1, default=300, max=10000) parts = props.IntProperty(name="Number of batches", min=1, default=cpu_count() * 2, max=10000)
class ParallelRenderPropertyGroup(types.PropertyGroup): def update(self, context): addon_props = context.preferences.addons[__name__].preferences if not addon_props.ffmpeg_valid and self.concatenate: LOGGER.info( "ParallelRenderPropertyGroup forcing concatenate to false") self.concatenate = False self.clean_up_parts = False if not self.concatenate: self.clean_up_parts = False last_run_result: props.EnumProperty( items=[ # (identifier, name, description, icon, number) ('done', '', ''), ('pending', '', ''), ('failed', '', ''), ], name="Render Batch Size") batch_type: props.EnumProperty( items=[ # (identifier, name, description, icon, number) ('parts', 'Parts', 'Render in given number of batches (automatically splits it)'), ('fixed', 'Fixed', 'Render in fixed size batches'), ], name="Render Batch Size") max_parallel: props.IntProperty(name="Blender Instances", min=1, default=cpu_count() - 1, max=10000) overwrite: props.BoolProperty( name="Overwrite Existing Files", default=True, ) mixdown: props.BoolProperty( name="Mixdown Sound", default=True, ) concatenate: props.BoolProperty( name="Concatenate Output Files", update=lambda self, context: self.update(context), ) clean_up_parts: props.BoolProperty(name="Clean Up Partial Files", ) fixed: props.IntProperty(name="Number of Frames per Batch", min=1, default=300, max=10000) parts: props.IntProperty(name="Number of Parts", min=1, default=(cpu_count() - 1) * 2, max=10000)
class PieMenuPreferences(addongroup.AddonGroup, bpy.types.PropertyGroup if "." in __name__ else bpy.types.AddonPreferences): bl_idname = __package__ submodules = None menus = props.CollectionProperty(type=PieMenu) font_id = props.IntProperty(name="Font ID", default=0, min=0, get=font_id_get) # 読み込み専用 font_id_mono = props.IntProperty(name="Font ID Mono", default=1, min=0) # 読み込み専用 # 中心からアイコンの円の境界まで menu_radius = props.IntProperty(name="Menu Radius", default=30, min=10) menu_radius_center = props.IntProperty(name="Menu Radius Center", default=10, min=0) # submenuに切り替えた際に中心を変えない lock_menu_location = props.BoolProperty(name="Lock Menu Location", default=False) # Itemの上下の隙間がこれより狭いならmenu_radiusを広げる item_min_space = props.IntProperty(name="MenuItem Min Space", default=4, min=0) colors = props.PointerProperty(type=PieMenu_PG_Colors) """:type: PieMenu_PG_Colors""" draw_type = props.EnumProperty(name="Draw Type", description="Default draw type", items=[('SIMPLE', "Simple", ""), ('BOX', "Box", ""), ('CIRCLE', "Circle", ""), ('SIMPLE_BOX', "Simple - Box", ""), ('SIMPLE_CIRCLE', "Simple - Circle", "")], default='BOX') def reset_menus(self): self.menus.clear() pass def draw(self, context): layout = self.layout draw_install = False try: import pie_menu except: draw_install = True else: try: mod = importlib.import_module(".".join( __name__.split(".")[:-1])) except: draw_install = True else: if pie_menu.VERSION != mod.bl_info["version"]: draw_install = True if draw_install: dst = ops.WM_OT_pie_menu_module_install.install_path() row = layout.row() row.operator(ops.WM_OT_pie_menu_module_install.bl_idname, text="Install Module") row = layout.row() row.label("Install Path: " + dst) if ops.module_installed: row = layout.row() row.label("Restart Blender !", icon='ERROR') layout.separator() super().draw(context) return colors = self.colors column = layout.column() sp = column.split() col = sp.column() col.prop(self, "draw_type") col.prop(self, "menu_radius") col.prop(self, "menu_radius_center") col = sp.column() col.prop(self, "lock_menu_location") # col.prop(self, "item_min_space") # わざわざ設定する人もいないだろう col.prop(colors, "use_theme", "Use Current Theme") split = layout.split() column = split.column() sub = column.box().column() sub.prop(colors, "line") sub.prop(colors, "separator") sub.prop(colors, "pointer") sub.prop(colors, "pointer_outline") sub.prop(colors, "pie_sel") sub.prop(colors, "item_highlight") column = split.column() sub = column.box().column() sub.active = not colors.use_theme sub.label("Menu Back:") sub.prop(colors, "menu_inner", text="Inner") sub.prop(colors, "menu_show_shaded") sub2 = sub.column(align=True) sub2.active = colors.menu_show_shaded sub2.prop(colors, "menu_shadetop") sub2.prop(colors, "menu_shadedown") sub.prop(colors, "text") column = split.column() sub = column.box().column() sub.active = not colors.use_theme sub.label("Title:") sub.prop(colors, "title_outline", text="Outline") sub.prop(colors, "title_inner", text="Inner") sub.prop(colors, "title_inner_sel", text="Inner Sel") sub.prop(colors, "title_text", text="Text") sub.prop(colors, "title_text_sel", text="Text Sel") sub.prop(colors, "title_show_shaded") sub2 = sub.column(align=True) sub2.active = colors.title_show_shaded sub2.prop(colors, "title_shadetop") sub2.prop(colors, "title_shadedown") column = split.column() sub = column.box().column() sub.active = not colors.use_theme sub.label("Item:") sub.prop(colors, "item_outline", text="Outline") sub.prop(colors, "item_inner", text="Inner") sub.prop(colors, "item_inner_sel", text="Inner Sel") sub.prop(colors, "item_text", text="Text") sub.prop(colors, "item_text_sel", text="Text Sel") sub.prop(colors, "item_show_shaded") sub2 = sub.column(align=True) sub2.active = colors.item_show_shaded sub2.prop(colors, "item_shadetop") sub2.prop(colors, "item_shadedown") column = split.column() sub = column.box().column() sub.active = not colors.use_theme sub.label("Tooltip:") sub.prop(colors, "tooltip_outline", text="Outline") sub.prop(colors, "tooltip_inner", text="Inner") sub.prop(colors, "tooltip_text", text="Text") sub.prop(colors, "tooltip_show_shaded") sub2 = sub.column(align=True) sub2.active = colors.tooltip_show_shaded sub2.prop(colors, "tooltip_shadetop") sub2.prop(colors, "tooltip_shadedown") draw_separator(layout) # Menus row = layout.row() row.label("Menus:") draw_menus(self, context, layout) draw_separator(layout) super().draw(context)
class BatchStripPropertyCopy(types.Operator): """Batch Strip Property Copy""" bl_idname = "sequencer.batch_strip_property_copy" bl_label = "Batch Set Strip Properties" bl_options = {'REGISTER', 'UNDO'} set_proxy = props.EnumProperty( items = TRIBOOL, default = 'NO_CHANGE', ) proxy_sizes = props.CollectionProperty( name='Set proxy', type=ProxySettingsProperty, description='Select properties to copy from active strip to all selected', ) def check(self, event): return True def _selected_strips(self, context): editor = context.scene.sequence_editor return [ seq for seq in editor.sequences_all if seq.select ] def _selected_move_strips(self, context): return [ seq for seq in self._selected_strips(context) if seq.type == 'MOVIE' ] def draw(self, context): layout = self.layout enabled = str(self.set_proxy) == 'SET' self.selected_all = self._selected_strips(context) self.selected_movie_strips = self._selected_move_strips(context) layout.label( 'Slected movie strips: {}/{}'.format( len(self.selected_movie_strips), len(self.selected_all) ) ) row = layout.row() row.label('Set Proxy') row.prop(self, 'set_proxy', expand=True) proxy_counts = {size: 0 for size in PROXY_SIZES} for seq in self.selected_movie_strips: if seq.use_proxy: for size in PROXY_SIZES: if getattr(seq.proxy, 'build_{}'.format(size)): proxy_counts[size] += 1 for size, prop in zip(PROXY_SIZES, self.proxy_sizes): row = layout.row() row.enabled = enabled row.separator() row.label('{}%'.format(size)) row.prop(prop, 'action', expand=True) row.label('{}/{}'.format(proxy_counts[size], len(self.selected_movie_strips))) def execute(self, context): if self.set_proxy == 'SET': for seq in self.selected_movie_strips: seq.use_proxy = True for size, prop in zip(PROXY_SIZES, self.proxy_sizes): if prop.action == 'SET': setattr(seq.proxy, 'build_{}'.format(size), True) elif prop.action == 'UNSET': setattr(seq.proxy, 'build_{}'.format(size), False) elif self.set_proxy == 'UNSET': for seq in self.selected_movie_strips: seq.use_proxy = False return {'FINISHED'} def invoke(self, context, event): wm = context.window_manager for size in PROXY_SIZES: self.proxy_sizes.add() editor = context.scene.sequence_editor if not editor: return {'FINISHED'} return wm.invoke_props_dialog(self)