xsharp.eu • EntityViewer Plugin
Page 1 of 1

EntityViewer Plugin

Posted: Mon Sep 09, 2024 9:08 pm
by Irwin
Hi Chris,

I'm trying to build an Entity Viewer Plugin but I can't detect when a file is opened in order to update my plugin internal entity listbox and refresh the Pad. Here's what I got so far...

Code: Select all

USING Xide.PluginSystem
USING System.Drawing
USING System.Windows.Forms


CLASS EntityViewerPad INHERIT ToolPad
	PRIVATE oService AS PluginService
	PRIVATE oList AS ListBox	
	
	CONSTRUCTOR(toService AS PluginService)
		SUPER("Entity Viewer", Size{300, 400})
		SELF:oService := toService
		SELF:oList := ListBox{}
		SELF:oList:Dock := DockStyle.Fill
		SELF:oList:SelectedIndexChanged += SELF:OnEntitySelected
		SELF:Controls:Add(SELF:oList)
		SELF:DockTo(ToolPadDock.Left)			
		
		// try to subscribe to the activated event (IT'S DOESN'T WORK)
		SELF:oService:IdeForm:Activated += OnEditorActivated
		
		SELF:UpdateEntityList()
	END CONSTRUCTOR
	
	METHOD UpdateEntityList AS VOID
		LOCAL loFilePad := SELF:oService:GetActiveFilePad() AS FilePad
		IF loFilePad == NULL
			RETURN
		ENDIF
		LOCAL loEditor := loFilePad:Editor AS Editor
		LOCAL laEntities AS Entity[]
		laEntities := loEditor:GetEntities()
		
		SELF:oList:Items:Clear()
		
		FOREACH loEntity AS Entity IN laEntities
			SELF:oList:Items:Add(loEntity:Name + " (" + loEntity:Type:ToString() + ")")
		NEXT
	END METHOD
	
	METHOD OnEntitySelected(o AS OBJECT, e AS EventArgs) AS VOID
		LOCAL loFilePad := SELF:oService:GetActiveFilePad() AS FilePad
		IF loFilePad == NULL || SELF:oList:SelectedIndex == -1
			RETURN
		ENDIF
		LOCAL loEditor := loFilePad:Editor AS Editor
		LOCAL laEntities AS Entity[]
		laEntities := loEditor:GetEntities()
		
		LOCAL loSelectedEntity AS Entity
		loSelectedEntity := laEntities[SELF:oList:SelectedIndex+1]
		
		// Move the cursor to the selected entity line
		loEditor:MoveCaretTo(loSelectedEntity:GetStartLine(), 1)
		
	END METHOD 
	
	METHOD OnEditorActivated(sender AS OBJECT, e AS EventArgs) AS VOID
		SELF:UpdateEntityList()
	END METHOD
END CLASS
Any ideas?

BTW: should we have a "XIDE" forum for posting stuffs like this one?

thanks!

Re: EntityViewer Plugin

Posted: Mon Sep 09, 2024 11:06 pm
by Chris
Hi Irwin,

You can use the OnFileSelected() (which I realize now it should be named OnFilePadSelected() instead) callback of the Plugin class:

Code: Select all

OVERRIDE METHOD OnFileSelected(oFilePad AS Xide.PluginSystem.FilePad) AS VOID
	oEntityViewer:UpdateEntityList()
I just tried it and works well with your plugin!

Nice job on it btw! I have actually promised to implement something similar inside the Project window, to show classes/entities as subnodes of each file, but it's taking much longer than I wanted to, so it's good you're doing it in a plugin. And of course this way you can do it exactly the way you want! Just a small note, you need to reverse the order of arguments you pass to Editor:MoveCaretTo(), first one is for the column and the second one for the row (line).

Btw2, I have not forgotten about implementing OnAfterCompile(), will do that soon.

About a dedicated subforum for XIDE, I am afraid it could further fragment the forum. I mean there's no subforum for VS either. But if we start having a lot of posts about them, then I think it would be a good idea to create such subforums.

Re: EntityViewer Plugin

Posted: Tue Sep 10, 2024 6:29 am
by Irwin
Thanks Chris, it worked!

Re: EntityViewer Plugin

Posted: Tue Sep 10, 2024 10:16 am
by Irwin
By the way Chris, which is the proper way to pipe my plugins? I use this method:

1. Create the class in a separate file eg: MyCustomToolPad.prg
2. Create a class that inherits from Plugin
2.1 Create an atribute of type MyCustomToolPad eg: oCustomToolPad
2.2 Create an instance of MyCustomToolPad in SELF:oCustomToolPad

Example:
MyCustomToolPad.prg

Code: Select all

USING System
USING System.Windows.Forms
USING Xide.PluginSystem
USING System.Drawing

CLASS ReferenceToolPad INHERIT Xide.PluginSystem.ToolPad
	PRIVATE oListBox AS ListBox
	
	CONSTRUCTOR
		SUPER("My Custom ToolPad", Size{300, 200})
		SELF:oListBox := ListBox{}
		SELF:oListBox:Dock := DockStyle.Fill
		SELF:Controls:Add(SELF:oListBox)
	END CONSTRUCTOR 	
	
	METHOD ShowToolPad AS VOID
		SELF:DockTo(ToolPadDock.Right)
		SELF:Display()
	END METHOD
END CLASS
MyCustomToolPadPluginManager.prg

Code: Select all

USING System.Windows.Forms
USING Xide.PluginSystem

CLASS MyPluginBase INHERIT Xide.PluginSystem.Plugin
	PROTECT oService AS PluginService
	PRIVATE oToolPad AS ReferenceToolPad
	OVERRIDE PROPERTY Name AS STRING GET "My Custom Plugin"

	OVERRIDE METHOD Initialize(_oService AS PluginService) AS VOID		
		SELF:oService := _oService
		SELF:oToolPad := ReferenceToolPad{}		
	END METHOD 
		
	OVERRIDE METHOD OnAfterIdeShow AS VOID
		SELF:oToolPad:ShowToolPad()		
	END METHOD
			
END CLASS
Is that ok or is there a better option?

thks.

Re: EntityViewer Plugin

Posted: Tue Sep 10, 2024 11:20 am
by Chris
Hi Irwin,

Hmmm, good question... ToolPad is a relatively new class in the PluginSystem and it does not have much functionality in it yet, but this will change. It also inherits directly from the System.Windows.Forms.Panel class (so you can put controls in it and do any drawing you want), but this is probably a bad idea, as it makes it difficult to change the internal implementation, so I should better abstract the paint area. Also currently the ErrorsPad and OutputPad do not inherit from anything, but what makes more sense is if they inherit from this base ToolPad class.

I think designing it (both the plugin system and your code) to directly inherit from ToolPad class makes sense and this way you can also receive easily callback messages from the base class, when I add some. But I need to remove the inheritance from Panel, and instead provide the paint area (control) in a separate property (and probably allow you to use a different one, like a PaintControl).

So for now please keep it as it is, but maybe later you will need to change the code to something like

SELF:PaintArea:Controls:Add(SELF:oList)

also better not use something directly from the Panel control class level (i see you are not using any right now), like the BorderStyle property, as this can change to a different control. Of course I will make any changes in this area before the next official release of XIDE, and will let you know what changes I made in advance.

Another thing, please try not to use the Service:IdeForm property at all. This gives you direct access to the IDE main window (System.Windows.Forms.Form), but this is not how plugins should access the IDE and implement functionality. I only added this because of the still missing functionality in the plugin system (so for now plugin developers can do a quick and dirty hack and access XIDE directly), but please avoid suing this, I will also add an [Obsolete] attribute to it. Instead, please let me know what plugin system functionality you are missing and I will implement it.