Component Scripting Window Default Size

Hello Ignition Forums,

I was wondering if it's possible to change the default popup size of the component scripting window.

When I do ctrl J to quickly open a scripting window on a component my window seems to always reset back to the default size and is quite annoying to constantly be changing the size of the window to have more room / see what I am doing.

If anyone else has noticed if I move the window to far open to the right or left the left-hand side automatically collapses to be non-readable and is also annoying to open that back up constantly.

Is there any type of solution to this or have I just missed the settings for this?

1 Like

You might try closing the designer, deleting the .layout file(s) in the .ignition directory under your user profile, then relaunching.

I've definitely noticed this behavior when using the designer in a windows 10 environment. When opening component scripting, the window has to be resized to make the apply button visible, and often, adjusting the window size to the point where the apply button is visible causes the folder browser to collapse to a point where the event handlers become inaccessible. To make matters worse, the collapsed browser area can't be drug open all the way without adjusting the overall window size even wider.

Here is a video that demonstrates the issue:

2 Likes

This is happening to me on regular basis...

Is this a Windows scaling thing? Ive never had this issue. What are your guys' windows scaling? I always have mine at 100%

I never deviate from 100% either. It causes too many problems, but I've always had that problem on at least six separate windows 10 PCs

My scaling is also always on 100%...

Hi @nminchin

My windows scaling is at 100%

This demonstrates exactly what I am talking about, I am going to attempt what @PGriffith suggested but this is a good video show casing what I am explaining.

Good morning @PGriffith,

I removed all the. layout files from my user profiles .ignition directory and the problem persists. Exactly how @justinedwards.jle depicted in the video he showcases.

Interesting. No other windows have similar behavior, just component scripting in Vision?
You said Windows 10 and 100% scaling - do you have multiple monitors, or just one? What's your exact screen resolution? We can try to replicate in house.

Yes Windows 10 and 100% scaling, I have 2 monitors as well, screen resolution is 1920x1080 for both. I have not tested every window with any sort of methodology but assume there's others that do this.

It happens for us in single monitor and multimonitor systems. I have a vm system as well that also exhibits this behavior. I've gotten so used to it that the resizing act has become reflexive. I hardly notice the problem anymore, but it's always there.

I was annoyed by this problem again today, so I decided to poke at it a little bit. The cause of the problem is the minimum size parameter of the right jPanel in the main JSplitPane of the component script editor. The minimum width is more than 1100 pixels, and since the JPanel can't shrink below that, it pushes the buttons out of view, and at a certain point as the window is being widened, it pushes the SynthSplitPaneDivider between the left and right JPanels all the way to the left and traps it there.
Presentation

Until IA corrects it, this can be fixed from the script console using this script:

from java.awt import Window, Dimension
for window in Window.getWindows():
	if window.__class__.__name__ == 'ComponentScriptEditor':
		def fixSplitPane(window):
			for component in window.components:
				if component.__class__.__name__ == 'JSplitPane':
					component.rightComponent.minimumSize = Dimension(0,0)
				else:
					fixSplitPane(component)
		fixSplitPane(window)

The script just finds the JSplitPanes and sets their right JPanel's minimum size to zero.

Result:
Presentation1

UPDATE:

I developed this script a little further, so it meets the requirement of the OP's original question:

# RUN ONLY ONCE DURING A DESIGNER SESSION
# ...prior to opening any script editors
from java.awt import Toolkit, AWTEvent, Dimension
from java.awt.event import AWTEventListener

class WindowMonitor(AWTEventListener):
	def eventDispatched(self, event):
		if event.__class__.__name__ == 'WindowEvent' and event.ID == event.WINDOW_OPENED: 
			window = event.window
			if window.__class__.__name__ == 'ComponentScriptEditor': 
				# Fix the split pane divider and button off screen bug
				# ...by setting the right JPanel's minimum size to 0
				splitPane = self.getSplitPane(window)
				splitPane.rightComponent.minimumSize = Dimension(0,0)
				
				# Specify a desired default window size and apply it
				windowSize = Dimension(1000, 600)
				window.preferredSize = windowSize
				window.size = windowSize
	
	# Recursively findes the highest level split pane within a given window
	def getSplitPane(self, window):
		for component in window.components:
			if component.__class__.__name__ == 'JSplitPane': 
				return component
			elif self.getSplitPane(component):
				return self.getSplitPane(component) 
			
# added logic to prevent multiple of the same listener from being inadvertently added
toolkit = Toolkit.getDefaultToolkit()
for proxy in toolkit.AWTEventListeners:
	if proxy.listener.__class__.__name__ == 'WindowMonitor':
		toolkit.removeAWTEventListener(proxy.listener)
toolkit.addAWTEventListener(WindowMonitor(), AWTEvent.WINDOW_EVENT_MASK)

Run this script at the beginning of a designer session, and for the duration of that session, the split plane right panel issue will be automatically fixed any time a component scripting editor is opened, and the size of the scripting window will be automatically set to whatever dimension is specified.

Edit: Added logic that eliminates the possibility of inadvertently adding more than one of the same listener.

6 Likes

That's some serious 'hacking'... :face_with_monocle:

1 Like

If anybody is interested, I've also developed a way to apply this script automatically when the designer is opened, so there is no need to ever run the script from the script console.

To do this, simply package the code into a library script, and call it from a Vision client tag using the value changed event. For the client tag, I'm using the data type DateTime with the expression now(0). Since the polling rate is set to zero, the expression changes the value only once when the designer is first opened triggering the value changed event to apply the changes at that time.

Example:

#def valueChanged(tag, [...], missedEvents):
	# If this is the first event after initial subscription and if the event is in the designer environment,
	# ...patch the designer bug
	if initialChange and system.tag.readBlocking(['[System]Client/System/SystemFlags'])[0].value < 4:
		libraryScripts.setEditorPreferences()

Additionally, I'm now minimizing the property pane at the bottom of the editor, and I'm setting the default tab to the script editor tab instead of the navigation tab.

Here is an updated version of the library script
from java.awt import Toolkit, AWTEvent, Dimension
from java.awt.event import AWTEventListener
def setEditorPreferences(width = 1000, height = 600):
	'''
	• This function only works for the duration of the session it was called from [designer scope]
	• Fixes bug that pushes the ok, apply, and cancel buttons off the comppnent editor window in the designer
	• Sets the default size of the window to 1000 x 600, or the dimensions can be passed in when the function is called
	'''
	# RUN ONLY ONCE DURING A DESIGNER SESSION
	# ...prior to opening any script editors
	class WindowMonitor(AWTEventListener):
		def eventDispatched(self, event):
			if event.__class__.__name__ == 'WindowEvent' and event.ID == event.WINDOW_OPENED: 
				window = event.window
				if window.__class__.__name__ == 'ComponentScriptEditor': 
					# Fix the split pane divider and button off screen bug
					# ...by setting the right JPanel's minimum size to 0
					splitPane = self.getSplitPane(window)
					splitPane.rightComponent.minimumSize = Dimension(0,0)
					
					# Change the default tab from navigation to the script editor
					self.getTabbedPane(splitPane.rightComponent).selectedIndex = 4
					
					# Minimize the documentation pane at the bottom of the editor
					self.minimizeDocPane(window)
					
					# Specify a desired default window size and apply it
					windowSize = Dimension(width, height)
					window.preferredSize = windowSize
					window.size = windowSize
	    
	    # Recursively finds the highest level split pane within a given window
		def getSplitPane(self, window):
			for component in window.components:
				if component.__class__.__name__ == 'JSplitPane': 
					return component
				else:
					splitPane = self.getSplitPane(component)
					if splitPane:
						return self.getSplitPane(component) 
		
		# Locates the minimize button for the documentation pane, and fires its click logic
		def minimizeDocPane(self, window):
			for component in window.components:
			
				# There are three SynthSplitPaneDivider in a component editor,
				# ...but the documentation pane's is the only one is horizontal [wider that it is tall]
				if component.__class__.__name__ == 'SynthSplitPaneDivider' and component.width > component.height:
					rightButton = component.components[1] # The SynthSplitPaneDivider only contains two sub components: a left and right button
					rightButton.doClick()
					break
				else:
					self.minimizeDocPane(component)
		
		# Finds the tabbed pane and returns it
		def getTabbedPane(self, jpanel):
			for component in jpanel.components:
				if component.__class__.__name__ == 'JTabbedPane':
					return component
				else:
					tabbedPane = self.getTabbedPane(component)
					if tabbedPane:
						return tabbedPane

	# added logic to prevent multiple of the same listener from being inadvertently added
	toolkit = Toolkit.getDefaultToolkit()
	for proxy in toolkit.AWTEventListeners:
		if proxy.listener.__class__.__name__ == 'WindowMonitor':
			toolkit.removeAWTEventListener(proxy.listener)
	toolkit.addAWTEventListener(WindowMonitor(), AWTEvent.WINDOW_EVENT_MASK)

This has become a fun rabbit hole to explore because it opens the possibility of saving other user preferences that are currently not remembered by the designer such as column widths on the tag browser [which I've also already created a script for]. By adding parameters to the library scripts, these changes can be made user specific, and I can imagine using things like event.ID == event.WINDOW_CLOSED to save last used properties for the next use.

6 Likes