PDA

View Full Version : Piggy backing a "windowreferencecontrol"



Ken L
December 31st, 2017, 23:10
I'm looking to override the default activate() function but it's protected. The main goal is to perform some logic when the windowreference is activated, for instance, updating several panels or setting some values.

My usecase is a ship control panel, opening subsystems of a ship to access their details will update a desktop panel element of that subsystem's layout automatically, making the desktop panel serve as an 'info panel' of sorts in the context of the opened windowreference. I ideally want to have a single piece of logic on the trigger point, rather than have separate scripts for each window class when opened given how similar it is save for a few datum I can easily grab in the windowreference itself.

Bidmaron
January 1st, 2018, 18:25
KenL, you keep running across the same things that limit what you can do through the API, and this is another of them. I have found no way to synthesize this thing you want.

MW, if you are listening, please add to FGU:
onFocus
onActivate [windows]
onTime
onLostFocus
onDeactivate [windows]
getTime
for formattedtextcontrols:
getSelection
getSelectionLength
setSelection
setSelectionLength
getCursor
setCursor
for text control:
getSelectionLength
setSelectionLength
getCursorIcon
setCursorIcon
imagecontrols letting you specify the filename of the image rather than some hard-coded image resource [or] the ability to add a resource definition at runtime from a file location.
import .txt file into string
export string into .txt file

I would add these to the wish list (many of them are already there), but they never get any votes because no one but us modders understand the need for them.

pindercarl
January 1st, 2018, 19:45
Bidmaron.

The Wishlist isn't just useful to generate votes, but also provides an index of features requested. It's easier to look at and search the Wishlist than it is to remember that there is a thread somewhere in the forums. John and I do look at the Wishlist, so it would be helpful to add this there. Thanks.

Nickademus
January 2nd, 2018, 00:25
I managed to do this. I'll post a small example in the next couple days (have to go to work soon). It have its caveats, but I manage to do anything I want with a link (which are mostly windowreferencecontrols).

Bidmaron
January 2nd, 2018, 02:51
Wow, Nickademus, my hat's off to you. Looking forward to seeing it.

Bidmaron
January 2nd, 2018, 02:54
I posted a list of requested API calls on Idea Informer here (https://fg2app.idea.informer.com/proj/?ia=115645). Please give it a vote.

Moon Wizard
January 2nd, 2018, 08:11
Usually, in these scenarios when I want something different than a built-in control, I create a brand new control template using genericcontrol as a base.

Cheers,
JPG

Nickademus
January 2nd, 2018, 18:13
I needed something that could be embedded in the formattedtext. I don't believe we have any control over anything inside the formattedtextcontrol.

Moon Wizard
January 2nd, 2018, 21:30
No. Though you can intercept links using the onLinkActivated event for formattedtextcontrols. I use this for reference manuals.

Regards,
JPG

Ken L
January 4th, 2018, 05:28
Here's what I ended up using.

Following Moon's suggestion, I just morphed a generic control to emulate a 'windowreferencecontrol'. I may be missing bits, but it serves my needs. I added custom logic on my activate method which I've omitted for brevity, fits in a script tag within a generic control.



local gTargetClass;
local gTargetRecordName;
local gIconNormal;
local gIconPressed;


function onInit()
end

function onClickRelease(button, x, y)
self.setIcon(gIconNormal,true);
activate();
return true;
end

function onClickDown(button, x, y)
self.setIcon(gIconPressed,true);
return true;
end

function onHover(state)
if state == false then
self.setIcon(gIconNormal,true);
end
end

function setIcons(normal, pressed)
gIconNormal = normal;
gIconPressed = pressed;
self.setIcon(gIconNormal,true);
end

function setValue(class, recordname)
gTargetClass = class;
gTargetRecordName = recordname;
onValueChanged();
end

function onValueChanged()
end

function isEmpty()
return gTargetClass == nil;
end

function getTargetDatabaseNode()
return DB.findNode(gTargetRecordName);
end


function activate()
local wnd = Interface.findWindow(gTargetClass,gTargetRecordNam e);
if wnd then
wnd.bringToFront();
else
wnd = Interface.openWindow(gTargetClass,gTargetRecordNam e);
end
return true;
end

Bidmaron
January 4th, 2018, 05:37
Thanks, KenL for posting solution.

Nickademus
January 7th, 2018, 07:54
Okay, so I finally have time to type this up. Making your own button is a good solution overall, but it doesn’t address the issue of not being able to control the links (windowreferencecontrols) in the formattedtextcontrols. I unfortunately use a lot of these so I tried to come up with a way to do some, preferably lua script, when a link was clicked. Ultimately it is impossible with the way things are normally done, since the link only opens a new window of a certain class and fills it with data from a certain database node. But then I took a step back and looked at what I had available and what I was trying to do. I found that I could accomplish what I was wanting if I just stopping assuming one simple thing.

Why does the link have to contain the window we want to open? It doesn’t. We can put any window in the link, as long as we end up with the window we want opened...

Looking at the windowreferencecontrols, they contain two pieces of data: a class for a windowclass, and a string. The string is usually used to point to a place in the database to grab data, but it doesn’t need to be. The string can be used for anything or passed along to another window.

So I made a set of classes called custom links. I have included two of them in this extension. The classes are invisible windows that fire an onInit() lua script block, which allows us to do anything we want. These move themselves to the bottom right corner of the screen and open the desired window, resizing and positioning to where I personally place them in the layout I use when DMing. But you can do anything that can be done in a lua script block. You can even pass data to the script through the recordname with self.getDatabaseNode().

There is a caveat though. The window can’t be closed from the onInit() or it will crash FG. Currently I have it covering the Library button, since I rarely use that during the game. But to get rid of the window, I set up a garbage collection system using a script manager GarbageCan. At the end of the script block in the custom link window, I send it to the garbage can. I then overwrite the template for all close buttons to empty the garbage can so that as soon as you close something, the custom windows will disappear.

I rarely ever have an issue with the windows being in the way as I close things frequently and rarely access the Library, but in the one instance it happened, I just right clicked the ‘Library button’ (actually the invisible custom link window) and closed it.

Hope this different way of thinking about windowreferencecontrols helps some of you. It was going to be included in an extension I was working on, but that is getting increasingly delayed.

damned
January 7th, 2018, 08:34
Hi Nickademus is it possible to position so that only 1px or 1 column of pixels is on the visible desktop?
Or even off the visible desktop?

Nickademus
January 7th, 2018, 08:52
The position I set is literally off my screen. FG caps the movement to around 100 pixels from the edge I think. I figure if I were to design a ruleset, I'd just put a logo or something down there that doesn't need to be clicked on.

Nickademus
January 7th, 2018, 09:01
I forgot to mention, in order for the links in a formattedtextcontrol to work like this, you have to manually set their class to the windowclass of a custom link window. This can be done through lua code, by setting the value in a dragdata object. I simply drag normal links into the text, close FG, open the xml of the db file or modules file and manually change the class to the type of custom link I want.

Bidmaron
January 7th, 2018, 13:55
Now, if we could just sweet talk MW into changing onInit so that if you return a string value of "Close" or something like that that the engine aborts the window opening, then this would be the cliche-d cat's meow. (can't use false because it wouldn't be compatible with any other onInit out there). That way, you could fire the onInit of the window you really want and have the fake window abort itself once everything returned.

Oh, and just like to complement you on the ingenuity of this....

Gotta think on my own uses cases too....

Nickademus
January 7th, 2018, 15:14
Thanks. I use it for quite a few things. One of the most prominent is for opening a reference manual and 'turning' to the appropriate page.

Come to think of it, you don't have to have the fake window open any new window. So you can uses links embedded in formatted text as raw buttons. Click and something happens.

Bidmaron
January 7th, 2018, 16:02
Right. I am just trying to figure out use cases where you don't want to just use a button other than the one you describe. One thing you might consider on the reference manual page is remembering the scroll position within the page so a link would not only take you to the proper page but where you want to be on that page.

With this, a DM or player(?) could build a note with 'Stuff I forget all the time' that links to rules he wants to be able to get to quickly.

[OR] you could have a bookmarks extension that would let you record bookmarks in any reference (where was I when I was reading that module dang it?)

Ken L
January 7th, 2018, 20:10
@Nick, correct me if I'm wrong, but can't you just modify my example to handle onDragStart type events? The only thing would be that your target would be expecting a windowreferencecontrol as opposed to the alien object acting like one, but you can work some black magic with onDragEnd as that gets fired before the onDrop handler of the destination.

Nickademus
January 7th, 2018, 20:59
I don't entirely understand what you are talking about. You gave code for a new button that opens a window. The formatted text automatically creates a windowreferencecontrol inside the text when something it recognizes as a link is drug onto it. I don't see a way to get your control inside the formatted text.

Bidmaron
January 7th, 2018, 21:00
Ken he isn’t dragging anything so those events won’t fire.

Ken L
January 8th, 2018, 08:35
ah, I thought you were talking about link dragging.