Text Window Drag and Drop Words

Started by Tonal, Tue 10/09/2024 21:18:11

Previous topic - Next topic

Tonal

Hello, I have searched the forums for a related post but I could not find anything.

Is it possible to add drag and drop functionality for text/words from GUI Text Windows through AGS Scripts or would this have to be added through a plugin?

What I would like to be able to do is to drag a word from a character's Text Window and then have that word dropped as a button in a list box which can then be selected for more conversation prompts with the character.

I have had a look in the manual but I could not see anything that would make this possible. I have also searched the modules and plugins but could not see anything similar. Just some posts on dragging and dropping objects.


Crimson Wizard

#1
If I understand your question correctly, you like to drag words from character's speech text to a listbox?

Drag and drop is not present in the standard AGS functionality, and  "words" from a speech text are not real objects in AGS. That's why you will have to either script this completely yourself, or use some existing drag module and accommodate it for your case.

You can use my DragDrop module as a start. The DragDrop module was designed to also let drag "custom objects" or "imaginary objects", but this will require extra scripting from your side. This is explained in its documentation:
https://github.com/ivan-mogilko/ags-script-modules/wiki/Drag-&-Drop-module


In simple terms, you would have to script:
- detection of a "draggable object" below the cursor. Because the module does not recognize "words" in text, you will have to tell it when the cursor is above one.
- create image of a dragging object (probably with a text on it).
- detection of a valid dropping place below the cursor (particular list box?).
- handle "after drop" action, where you add this word to the listbox contents, and maybe something else.

In practice that will be more complicated than that. But I do believe that's possible.
It looks like the toughest part will be word detection. For that you'll likely have to parse displayed text and calculate its structure, so that you could know each word's coordinates. This is going to be a separate problem of its own, unrelated to drag'n'drop action.

Such complex tasks are better solved step by step.

I suggest start by learning how DragDrop module works, read its documentation, in particular the part where it explains how to script dragging an object from scratch, and study the Demo Game, which illustrates dragging "imaginary" things too, among other things.
Perhaps, make a experiment by scripting dragging and dropping something unusual in a test game.


PS. This is in no way a "Beginner's technical question", it's rather a advanced topic, perhaps it would make sense for mods to move it into appropriate forum section?

Khris

How dead-set are you on this exact mechanic?

Is this primarily about implementing the exact thing you're describing? Or is the more important thing the general ability to ask characters about specific words they mentioned?
Because AGS already natively supports adding a textbox to the dialog options.

Are you planning on releasing the game for touchscreen devices? Or is the drag-and-drop thing just incidental?

Tonal

@Crimson Wizard Great, thank you. Some really useful advice. I will have a look at your module first and go from there.

@Khris Pretty dead set.

In fact, it is imperative to the type of game I want to make.

Basically I am looking to make a detective game. Detective games I have played either provide the text prompts automatically in a notebook, like Lamplight City, or the Blackwell Series, or have a text parser, like the Crimson Diamond, or the Laura Bow games.

The text prompts I find a bit rigid and guides you a bit much through detective games whereas the text parser has more freedom but does not have the organisation of the text notebook.

The way I would like to do it would be sort of a high-bred of the two, along with drag'n'drop interface of The Case of the Golden Idol. This would allow you to drag and drop keywords from clues found in items and the environment, as well as conversations with suspects, which you can then use to question suspects further. I think this would allow the developer to create a detective story with different outcomes to a multi-layered mystery depending on which keywords they find and follow. I think it could be good.

Crimson Wizard

I do recommend also check out another recent module, which allows to draw individual words in different style (color, font), made by @eri0o:
https://www.adventuregamestudio.co.uk/forums/modules-plugins-tools/module-fancy-0-1-0/

It does the word splitting itself, so may be capable of reporting their positions on screen too.
I don't remember if it has this in its commands, but even if not it might be possible to add that.

Maybe combining these two modules will get you what you want.

eri0o

#5
Just to confirm, you want to make this game: https://branegames.itch.io/we-suspect-foul-play ?

And yeah, there's definitely some way to code a way to retrieve giving a position, which token is there - and then you can add a new tag, say "label" or "region" (need to figure a name) and then you can check to which label/region the token would belong, assuming you mark the interesting things using that. You still would need to handle the drag and drop separately, you would just render that token when it would be there - say there's a "visible" tag you could pass 0 to not render that text after the player had dragged off the text.

Tonal

@Crimson Wizard Smashing, another good lead. I will have a look, thanks. I had quick look through the AGS documentation to see if I could find out how it writes the text in the GUI Text Windows. This may help.

@eri0o That's not quite what I had in mind. That is a bit more towards the Golden Idol game play where you drag'n'drop key words to complete sentences.

I have more of a traditional point'n'click adventure game where you have a playable character that explores the rooms and talks to characters. The drag'n'drop element is to pull keywords from conversations/objects/environment and place them on a list, like the lists in Lamplight City or the Blackwell Series, to use in conversations with other characters. These keywords are kinda like the ones you would find in text parser games but you would click them from the list rather than type them in the parser. Hope that's a bit clearer on what I am aiming for.

Tonal

@eri0o Are you able to offer some advice on font, please? Do font characters have a standard width? If not, is there a way to determine the width of characters passed to the screen by a function in AGS? I cannot find one in the manual.

I am using Overlay.Textual to write to the screen but in order to find out which word is passed to the screen at which coordintate I would need to know the character width.


Crimson Wizard

#8
Quote from: Tonal on Sat 12/10/2024 18:09:21Do font characters have a standard width? If not, is there a way to determine the width of characters passed to the screen by a function in AGS? I cannot find one in the manual.

Fonts may be monospace or variable width, so you should not rely on characters being same width.
AGS provides GetTextWidth which calculates a width of a string. It may be used to calculate width of individual characters as well.
Also there's GetTextHeight that calculates how much height the wrapped text will occupy:
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_General.html#gettextwidth
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_General.html#gettexteight

Other two functions that may be helpful for calculating text position:
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_General.html#getfontheight
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_General.html#getfontlinespacing

eri0o

What CW said are the functions that are at disposal.

Just was thinking about my previously mentioned module... If you want to try hacking around at it.

Looking at my fancy module, I think the module has an idea of position of tokes in it's draw method here. It looks like it's possible to create an additional function that can test given an x, y position, in which token it is.

But API wise I have zero idea how to have this work in this module, I guess it would be something in either FancyTextBase or FancyTextBox and have some tag to mark something in the text, but I unsure of which would be the best way to handle there.

Tonal

Ok, I'll have another look through your fancy code, see if I can dig anything up. I think I might be able to cobble something together with one of Crimson's suggestions, gettextwidth, along with String.chars and string.format. Or maybe String.substring. I'll have a play around.

Thanks both for your help.


Snarky

My TextField module lets you position the text cursor (caret) by clicking in a String, and make selections using dragging gestures.

You could have a look at that code (it's the PositionCaret function), but the basic idea is that you figure out which character index within the string a coordinate corresponds to by calculating the width of substrings of the string using GetTextWidth. (If you need it for a multi-line control you first need to figure out which line it is on.)

The simplest approach (used in this module) is a linear search where you just add one character at a time until the width of the string reaches the coordinate you're looking for. However, calls to GetTextWidth are somewhat expensive in terms of processing, and should ideally be kept to a minimum. Using a binary search algorithm can greatly improve efficiency, and making an initial guess based on assuming all characters have equal width  (as a simple estimate) improves that further for typical strings. The StringWrap module uses this approach.

Tonal

@Snarky Great, thanks. That will be useful, I'll definitely have a look.

I have come up with something myself but I am doing a little debugging which I'm going to ask Crimson regarding as he has seemed to have discussed the problem in a previous thread. Just checked the thread again and it looks like it was helpful for you as well. Will defo look at yours as well though as you may have a better way of calculating character position on lines.

@Crimson Wizard Hi Crimson, this maybe pointless after I have had a look at Snarky's module but it can't hurt to ask just in case.

I was having issues getting the correct lines when clicking on the text. I searched the forum and I came across this thread:

https://www.adventuregamestudio.co.uk/forums/engine-development/incredibly-annoying-gettextwidth-vs-auto-line-split-behavior/msg636554187/#msg636554187

You mention padding for the overlay.createtextual function. Is this padding ubiquitous across all fonts and game resolutions? The padding on mine is 6 pixels, 2*3 pixel padding. Will this be the same across all fonts and game res?

Crimson Wizard

Quote from: Tonal on Sun 03/11/2024 19:23:34You mention padding for the overlay.createtextual function. Is this padding ubiquitous across all fonts and game resolutions? The padding on mine is 6 pixels, 2*3 pixel padding. Will this be the same across all fonts and game res?

Afaik the standard padding is hardcoded and does not depend on anything.

If you're using Textwindow GUI to make textual overlays, then IIRC it will use the GUI's Padding setting instead (and that padding is 3 pixels by default too).

Tonal

Hi everyone, I have finally got something together and it is working!

Thanks for your help and input with this. It took a while but I am new to this and have been doing this in my spare time.

If you are interested in what I had in mind I have made a little video with it working. Of course the graphics are all placeholders for testing but it shows the funtionality I had in mind.


I want to add charcter/object pictures so it is more obvious who is talking or what is being examined but this is the bare bones of the drag'n'drop note interface.

Now to use this to make a little whodunit murder mystery!


SMF spam blocked by CleanTalk