SDS2 Parametric API
 All Classes Namespaces Functions Variables Pages
sds2.utility.gadget_protocol_member Namespace Reference

Detailed Description

The gadget_protocol provides API help for creating general purpose, multi-editable GadgetScreens. Custom members really need additional help because they have a a few special concerns.

First, some builtin member information, e.g. sequence and model complete, is not exposed thru the MemberBase module. To solve this developers use the member module and its Update functionality in some way. For example, a member might use a custom ItemController to read and update a member.Member for sequence.

Second, custom members have never been able to simply return 'OK' or 'Cancel' from Edit and MultiEdit like components are able to do. Instead the logic for what to return looks something like:

return ok and (is_new_member or did_something_change)

Implementing this logic gets complicated when you consider multiedit, member module attributes, MemberBase attributes, and components that are on the member.

This module provides two special ItemControllers (MemberAttrController and MemberDateController), two Entry's (Rotation0_90 and ChooseSequence), and a base class GadgetMember that takes care of implementing Edit and MultiEdit and all the boilerplate code that member's typically have to implement.

Usage:

import webbrowser

import Designable.ProcessableMember as PM import Designable.Proxies as DP import MemberBase as MB import Transform3D as x3d import dialog.checkbox as check import dialog.date as date import dialog.dimension as dim import dialog.entry as entry import sds2.obj as obj import sds2.utility.gadget_protocol as gp import sds2.utility.gadget_protocol_member as gpm

def general_settings(f): gpm.ChooseSequence( f, gpm.MemberAttrController('ErectionSequence'), 'Sequence:' ) #gpm.Rotation0_90(f, gpm.MemberAttrController('rotation'), 'Rotation:') gpm.Rotation0_90(f, 'rotation_degrees', 'Rotation:') check.Checkbox(f, 'graphical', 'Graphical') date.DateEntry(f, gpm.MemberDateController('DateModelCompleted'), 'Model complete date:')

def build_end_frame(f): dim.DimensionEntry(f, 'elevation', 'default', 'Elevation:') dim.DimensionEntry(f, 'thickness', 'thick', 'Thickness:')

def build_end_frame2(f): dim.DimensionEntry(f, 'width', 'default', 'Width:')

def build_column(column, controller, gadget_factory): gadget_factory.LoadSaveLeaf( column, controller, build_end_frame, 'Settings', '', #leaves in different columns will fold together '99c9dc74-b050-41d5-8dbf-82d54f7bac61', 'MyMember_settings_leaf_form', [] ) gadget_factory.LoadSaveLeaf( column, controller, build_end_frame2, 'Leaf description...', '', #leaves in different columns will fold together 'cc02d9a5-d422-4734-b56b-0d81559b50cb', 'MyMember_leaf_description_form', [] )

def build_ui(model, gadget_factory): mc_controller = gp.ModelCompleteSubdialogController( 'DateModelCompleted', model)

gadget_factory.LoadSaveBanner( mc_controller, general_settings, 'General settings', '', '98a104f2-da81-4598-8f61-7d6a81334828', 'MyMember_general_settings_form', ('graphical', 'DateModelCompleted', ) [] )

le_controller = gp.SubdialogController( [MyMemberEnd(m, 'left') for m in model] )

end_column_form_id = 'MyMember_end_column_form' le_column = gadget_factory.LoadSaveColumn( le_controller, None, 'Left end', '', 'aedf6b0d-7343-434c-8a06-01db14b072e1', end_column_form_id ) build_column(le_column, le_controller, gadget_factory)

re_controller = gp.SubdialogController( [MyMemberEnd(m, 'right') for m in model] )

re_column = gadget_factory.LoadSaveColumn( re_controller, None, 'Right end', '', 'fb1fde68-69c8-48ed-8f39-432e2c85cff3', end_column_form_id ) build_column(re_column, re_controller, gadget_factory)

class MyMemberEnd(object): def init(self, mb, end): self.mb = mb self.end = end

elevation = property( lambda o: getattr(o.mb, 's_elevation' % o.end), lambda o, v: setattr(o.mb, 's_elevation' % o.end, v) )

thickness = property( lambda o: getattr(o.mb, 's_thickness' % o.end), lambda o, v: setattr(o.mb, 's_thickness' % o.end, v) )

width = property( lambda o: getattr(o.mb, 's_width' % o.end), lambda o, v: setattr(o.mb, 's_width' % o.end, v) )

def property_maker(attr, default=None): underlying = '_s' % attr gettr = lambda o: (getattr(o, underlying) if hasattr(o, underlying) else default ) settr = lambda o, v: setattr(o, underlying, v) deltr = lambda o: delattr(o, underlying) return property(gettr, settr, deltr)

class ExampleGadgetMember(gpm.GadgetMember, PM.ProcessableMember): UserStr = 'Example Gadget' StandAloneEditWindowID = 'fc6eee0d-bcdd-4f4c-8478-577936ded16f'

def OnStandAloneEditHelp(): webbrowser.open('https://youtu.be/dQw4w9WgXcQ?t=42')

def CreateCustomMultiEditableUI(model, gadget_factory): build_ui(model, gadget_factory)

def init(self): PM.ProcessableMember.__init__(self)

left_width = property_maker('left_width', 6.) right_width = property_maker('right_width', 6.)

left_thickness = property_maker('left_thickness', .25) right_thickness = property_maker('right_thickness', .25)

def DesignForMember(self, mn): mb = obj.mb(mn) le = mb.left_location re = mb.right_location x, y, z = x3d.GetXYZ(x3d.MemberTransform(le, re, mb.rotation)) length = le.Distance(re) / 2. rp1 = DP.RectPlate( Member=mn, Thickness=self.left_thickness, Width=self.left_width, WorkpointSlopeDistance=length, _submaterial_to_global=x3d.Transform3D(x, y, z, le) ) rp2 = DP.RectPlate( Member=mn, Thickness=self.right_thickness, Width=self.right_width, WorkpointSlopeDistance=length, _submaterial_to_global=x3d.Transform3D( x, y, z, le + x * length) ) map(self.RegisterDesignProxy, (rp1, rp2)) return True

MB.UseLastSavedMemberOnAdd(ExampleGadgetMember.__name__, True) MB.RegisterMemberType(ExampleGadgetMember, ExampleGadgetMember.UserStr)