code for customizable form creation with dynamo, Data-Shapes package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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