code for customizable form creation with dynamo, Data-Shapes package
#Copyright (c) mostafa el ayoubi , 2016 | |
#Data-Shapes www.data-shapes.net , elayoubi.mostafa@gmail.com | |
import clr | |
try: | |
clr.AddReference('System.Windows.Forms') | |
clr.AddReference('System.Drawing') | |
from System.Drawing import Point , Size , Graphics, Bitmap, Image, Font, FontStyle, Icon, Color | |
from System.Windows.Forms import Application, Button, Form, Label, ColumnHeader, TextBox, CheckBox, FolderBrowserDialog, OpenFileDialog, DialogResult, ComboBox, FormBorderStyle, ListView, ListViewItem , SortOrder, Panel, ImageLayout, GroupBox | |
from System.Collections.Generic import * | |
from System.Windows.Forms import View as vi | |
clr.AddReference('System') | |
from System import IntPtr | |
import sys | |
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib' | |
sys.path.append(pyt_path) | |
import os | |
clr.AddReference('RevitAPIUI') | |
from Autodesk.Revit.UI import Selection | |
importcolorselection = 0 | |
try: | |
from Autodesk.Revit.UI import ColorSelectionDialog | |
except: | |
importcolorselection = 1 | |
clr.AddReference('RevitNodes') | |
import Revit | |
clr.ImportExtensions(Revit.Elements) | |
clr.ImportExtensions(Revit.GeometryConversion) | |
clr.AddReference('RevitServices') | |
from RevitServices.Persistence import DocumentManager | |
doc = DocumentManager.Instance.CurrentDBDocument | |
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument | |
#getting screen resolution and creating resolution factor to handle high res screens | |
import ctypes | |
user32 = ctypes.windll.user32 | |
resolutionX = user32.GetSystemMetrics(0) | |
resolutionY = user32.GetSystemMetrics(1) | |
resfactX = resolutionX/1920 | |
resfactY = resolutionY/1080 | |
class MultiTextBoxForm(Form): | |
def __init__(self): | |
self.Text = 'Data-Shapes | Multi Input UI ++' | |
self.output = [] | |
self.values = [] | |
def setclose(self, sender, event): | |
cbindexread = 0 | |
for f in self.output: | |
if f.GetType() == TextBox: | |
self.values.append(f.Text) | |
if f.GetType() == CheckBox: | |
self.values.append(f.Checked) | |
if f.GetType() == Button: | |
if f.Tag == None : | |
self.values.append(f.Text) | |
else: | |
self.values.append(f.Tag) | |
if f.GetType() == ComboBox: | |
key = f.Text | |
self.values.append(f.Tag[key]) | |
if f.GetType() == mylistview: | |
self.values.append([f.Values[i.Text] for i in f.CheckedItems]) | |
self.Close() | |
def reset(self, sender, event): | |
pass | |
def openfile(self, sender, event): | |
ofd = OpenFileDialog() | |
dr = ofd.ShowDialog() | |
if dr == DialogResult.OK: | |
sender.Text = ofd.FileName | |
def opendirectory(self, sender, event): | |
fbd = FolderBrowserDialog() | |
dr = fbd.ShowDialog() | |
if dr == DialogResult.OK: | |
sender.Text = fbd.SelectedPath | |
def pickobjects(self, sender, event): | |
sel = uidoc.Selection.PickObjects(Selection.ObjectType.Element,'') | |
selelem = [doc.GetElement(s.ElementId) for s in sel] | |
sender.Tag = (selelem) | |
def pickfaces(self, sender, event): | |
selface = uidoc.Selection.PickObjects(Selection.ObjectType.Face,'') | |
faces = [uidoc.Document.GetElement(s).GetGeometryObjectFromReference(s).ToProtoType(True) for s in selface] | |
sender.Tag = [i for f in faces for i in f] | |
def pickedges(self, sender, event): | |
seledge = uidoc.Selection.PickObjects(Selection.ObjectType.Edge,'') | |
edges = [uidoc.Document.GetElement(s).GetGeometryObjectFromReference(s).AsCurve().ToProtoType(True) for s in seledge] | |
sender.Tag = edges | |
def colorpicker(self, sender, event): | |
dialog = ColorSelectionDialog() | |
selection = ColorSelectionDialog.Show(dialog) | |
selected = dialog.SelectedColor | |
sender.Tag = selected | |
sender.BackColor = Color.FromArgb(selected.Red,selected.Green,selected.Blue) | |
sender.ForeColor = Color.FromArgb(selected.Red,selected.Green,selected.Blue) | |
def topmost(self): | |
self.TopMost = True | |
def lvadd(self, sender, event): | |
sender.Tag = [i for i in sender.CheckedItems] | |
class mylistview(ListView): | |
def __init__(self): | |
self.Values = [] | |
#Form initialization | |
form = MultiTextBoxForm() | |
form.topmost() | |
xlabel = 25*resfactX | |
xinput = 150*resfactX | |
y = 10*resfactY | |
inputheight = 20*resfactY | |
inputwidth = 160*resfactX | |
fields = [] | |
error = 0 | |
#Description | |
if IN[3] != "": | |
des = Label() | |
des.Font = Font("Arial", 15,FontStyle.Bold) | |
des.Location = Point(xlabel,y) | |
des.AutoSize = True | |
des.MaximumSize = Size(300*resfactX,0) | |
des.Text = IN[3] | |
form.Controls.Add(des) | |
y = des.Bottom + 40*resfactY | |
#Input form | |
if isinstance(IN[0],list): | |
inputtypes = IN[0] | |
else: | |
inputtypes = [IN[0]] | |
for j in inputtypes: | |
label = Label() | |
label.Location = Point(xlabel,y+4) | |
label.AutoSize = True | |
label.MaximumSize = Size(120*resfactX,0) | |
label.Text = j.inputname | |
form.Controls.Add(label) | |
if j.__class__.__name__ == 'dropdown': | |
cb = ComboBox() | |
cb.Location = Point(xinput,y) | |
cb.Width = inputwidth | |
cb.Height = inputheight | |
[cb.Items.Add(i) for i in j.keys() if not (i == 'inputname' or i == 'height')] | |
cb.Tag = j | |
form.Controls.Add(cb) | |
form.output.append(cb) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'listview': | |
lv = mylistview() | |
lv.Values = j | |
lv.CheckBoxes = True | |
lv.View = vi.List | |
lv.Sorting = SortOrder.Ascending | |
[lv.Items.Add(i) for i in j.keys() if not (i == 'inputname' or i == 'height')] | |
lv.Location = Point(xinput,y) | |
lv.Width = inputwidth | |
lv.Height = j.height | |
lv.Scrollable = True | |
form.Controls.Add(lv) | |
form.output.append(lv) | |
y = lv.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uitext': | |
tb = TextBox() | |
tb.Text = j.defaultvalue | |
tb.Width = inputwidth | |
tb.Height = inputheight | |
tb.Location = Point(xinput,y) | |
form.Controls.Add(tb) | |
form.Controls.Add(label) | |
form.output.append(tb) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uitextnote': | |
gb = GroupBox() | |
gb.Text = j.title | |
gb.Parent = form | |
gb.SendToBack() | |
gb.BackColor = Color.Transparent | |
gb.Location = Point(xlabel, y) | |
tn = Label() | |
tn.Location = Point(xlabel*resfactX,18*resfactY) | |
tn.AutoSize = True | |
tn.MaximumSize = Size(260*resfactX,0) | |
tn.Text = j.textnote | |
tn.BringToFront() | |
gb.Controls.Add(tn) | |
gb.Size = Size(285*resfactX, tn.Bottom-tn.Top+25*resfactY) | |
y = gb.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uibool': | |
yn = CheckBox() | |
yn.Width = inputwidth | |
yn.Height = inputheight | |
yn.Location = Point(xinput,y) | |
yn.Text = j.booltext | |
yn.Checked = j.defaultvalue | |
form.Controls.Add(yn) | |
form.output.append(yn) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uifilepath': | |
fp = Button() | |
fp.Width = inputwidth | |
fp.Height = inputheight | |
fp.Text = j.defaultvalue | |
fp.Location = Point(xinput,y) | |
form.Controls.Add(fp) | |
fp.Click += form.openfile | |
form.output.append(fp) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uidirectorypath': | |
dp = Button() | |
dp.Width = inputwidth | |
dp.Height = inputheight | |
dp.Text = j.defaultvalue | |
dp.Location = Point(xinput,y) | |
form.Controls.Add(dp) | |
dp.Click += form.opendirectory | |
form.output.append(dp) | |
y = label.Bottom + 30*resfactY | |
elif j.__class__.__name__ == 'uiselectelements': | |
se = Button() | |
se.Width = inputwidth | |
se.Heigth = inputheight | |
se.Text = j.buttontext | |
se.Location = Point(xinput,y) | |
form.Controls.Add(se) | |
se.Click += form.pickobjects | |
form.output.append(se) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uiselectfaces': | |
sf = Button() | |
sf.Width = inputwidth | |
sf.Height = inputheight | |
sf.Text = j.buttontext | |
sf.Location = Point(xinput,y) | |
form.Controls.Add(sf) | |
sf.Click += form.pickfaces | |
form.output.append(sf) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uiselectedges': | |
sed = Button() | |
sed.Width = inputwidth | |
sed.Height = inputheight | |
sed.Text = j.buttontext | |
sed.Location = Point(xinput,y) | |
form.Controls.Add(sed) | |
sed.Click += form.pickedges | |
form.output.append(sed) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uicolorpick' and importcolorselection == 0: | |
cp = Button() | |
cp.Width = inputwidth | |
cp.Height = inputheight | |
cp.Text = j.buttontext | |
cp.Location = Point(xinput,y) | |
form.Controls.Add(cp) | |
cp.Click += form.colorpicker | |
form.output.append(cp) | |
y = label.Bottom + 25*resfactY | |
elif j.__class__.__name__ == 'uicolorpick' and importcolorselection == 1: | |
importcolorselection = 2 | |
#Adding validation button | |
button = Button() | |
button.Text = IN[1] | |
button.Width = inputwidth | |
button.Location = Point (150*resfactX,y+60*resfactY) | |
button.Click += form.setclose | |
form.Controls.Add(button) | |
form.MaximizeBox = False | |
form.MinimizeBox = False | |
form.FormBorderStyle = FormBorderStyle.FixedSingle | |
#Adding Logo | |
#default logo in case no input | |
try: | |
#There won't be a default logo if your package folder is not the default one | |
deflogopath = os.getenv('APPDATA')+"\\Dynamo\Dynamo Revit\\1.2\packages\Data-Shapes\extra\\a.png" | |
if IN[4] == '': | |
ima = Image.FromFile(deflogopath) | |
else : | |
ima = IN[4] | |
logo = Panel() | |
logo.Size = Size(100*resfactX,100*resfactX) | |
ratio = (ima.Height)/(ima.Width) | |
h = float(ima.Height) | |
w = float(ima.Width) | |
ratio = h/w | |
scaledimage = Bitmap(100*resfactX,(100*ratio)*resfactY) | |
gr = Graphics.FromImage(scaledimage) | |
gr.DrawImage(ima,0,0,100*resfactX,100*ratio*resfactY) | |
logo.BackgroundImage = scaledimage | |
logo.BackgroundImageLayout = ImageLayout.Center | |
form.Controls.Add(logo) | |
logo.Location = Point(20*resfactX,y+20*resfactY) | |
#Setting icon | |
if IN[4] == '': | |
bmp = Bitmap.FromFile(deflogopath) | |
else: | |
bmp = Bitmap(IN[4]) | |
thumb = bmp.GetThumbnailImage(64*resfactX, 64*resfactX, bmp.GetThumbnailImageAbort,IntPtr.Zero) | |
thumb.MakeTransparent(); | |
icon = Icon.FromHandle(thumb.GetHicon()) | |
form.Icon = icon | |
except: | |
form.ShowIcon = False | |
form.Height = y + 180*resfactY | |
form.Width = 350*resfactX | |
if IN[2]: | |
if importcolorselection != 2: | |
Application.Run(form) | |
result = form.values | |
OUT = result,True | |
else: | |
OUT = ['ColorSelection input is only available With Revit 2017'] , False | |
else : | |
OUT = ['Set toggle to true!'] , False | |
except: | |
import traceback | |
OUT = traceback.format_exc() , "error" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment