ID:158329
 
mob
verb
buycards()
var/onoff=params2list(winget(src,"deckbuy","value"))
if(onoff[3]==1)
world<<"true"
winshow(src,"deckbuy",0)
else
world<<"false"
winshow(src,"deckbuy",1)


I just want to be able to click a button, which calls "buycards", and if the menu is already opened remove it, otherwise make it appear.



EDIT: Also, I'm trying to get the list of cards in to a grid window:

mob
verb
add_cards_to_window()
var/obj/card/list/c=new
c+=typesof(/obj/card/)
for(var/a in c)
var/n=new a
world<<n
winset(src,"deckbuy",n)
That's my best guess as to how to add cards to a grid...
Speedro wrote:
mob
> verb
> buycards()
> var/onoff=params2list(winget(src,"deckbuy","value"))
> if(onoff[3]==1)
> world<<"true"
> winshow(src,"deckbuy",0)
> else
> world<<"false"
> winshow(src,"deckbuy",1)

I just want to be able to click a button, which calls "buycards", and if the menu is already opened remove it, otherwise make it appear.

Do you mean this:
mob
verb
buycards()
if(winget(src, "deckbuy", "is-visible") == "true")
world<<"true"
winshow(src,"deckbuy",0)
else
world<<"false"
winshow(src,"deckbuy",1)
In response to Haywire
Yes. How might I find out what all the parameters of Winget etc are? They're not in the reference.


Also I updated my initial post, any ideas how to preform the second one?
In response to Speedro
Speedro wrote:
Yes. How might I find out what all the parameters of Winget etc are? They're not in the reference.


Also I updated my initial post, any ideas how to preform the second one?

winget returns the value of a parameter and the parameters are the same as winset.

winset 'sets' values to params and winget 'gets' the values from the params, so just look up winset.

For the second part you could read Lummox Jr's Skin Article which goes over this feature.
In response to Haywire
Ah thanks :)



After messing around with it for a bit, I decided I wanted each cell to contain not only the card, but perhaps a description of the card... I acheived that via:

            for(var/obj/card/a in ccreated)
var/q="\icon [a] [a.name] [a.info]"
winset(src,"deckgrid","current-cell=[cell_count++]")
winset(src,"deckgrid","cells=[cell_count]")
src<<output(q,"deckgrid")
winshow(src,"deckbuy",1)
Everything works as expected, but is there anyway to choose how large the icons are on the grid? 16 x 16 is too small, and I would much prefer the full size 32 x 32. I unchecked "small icons" in the grid. I checked the reference for \icon and found that they were automatically reduced to 16 x 16 icons. It said this could be changed using a "style sheet", but no such thing exists. Is there an easier way to display the image in full 32 x 32?


EDIT: and then I tried this (which also doesn't work :p)

            for(var/obj/card/a in ccreated)
var/list/q=new
q += a
q += a.cost
winset(src,"deckgrid","current-cell=[cell_count++]")
winset(src,"deckgrid","cells=[cell_count]")
src<<output(list2params(q),"deckgrid")
winshow(src,"deckbuy",1)
In response to Speedro
Speedro wrote:
After messing around with it for a bit, I decided I wanted each cell to contain not only the card, but perhaps a description of the card... I acheived that via:

You know that you can have as many cells as you want on one row in a grid. So you don't have to squeeze everything you want to display in the row (e.g. card info) in a single cell if you don't want to.
Grids support native atom display (that takes up a whole cell) that you can use by giving an atom reference instead of text in output(). This works the same as statpanels' native display of atoms, so the display will update when the atom changes appearance (its name will also be displayed, but you can turn that off).
What you have done is taking advantage of the fact you can use BYOND's HTML in the grid control and manually displayed the atom's graphic using an <IMG> tag (that's what the \icon text macro does) - nothing particularly bad about it, but in that case it's a static image, so choose either of the two that suits you more.

Everything works as expected, but is there anyway to choose how large the icons are on the grid? [...] I checked the reference for \icon and found that they were automatically reduced to 16 x 16 icons. It said this could be changed using a "style sheet", but no such thing exists.

It exists.

Is there an easier way to display the image in full 32 x 32?

This post should explain both ways: how to use a style sheet and a class and how... not to do so, aka "the easier way": [link]
In response to Speedro
You would edit the Style property of the grid. See: icon text macro.

Also: you do not need to set the current-cell property each time you output. Instead, you can just send output to "deckgrid:[cell_count++]", which will save you a winset. I also suggest only setting the cells property once, rather than for each card.
In response to Kaioken
Kaioken wrote:

You know that you can have as many cells as you want on one row in a grid. So you don't have to squeeze everything you want to display in the row (e.g. card info) in a single cell if you don't want to.

I knew it was possible, but I'm not sure how to do this.
In response to Garthor
Garthor wrote:
You would edit the Style property of the grid. See: icon text macro.

Also: you do not need to set the current-cell property each time you output. Instead, you can just send output to "deckgrid:[cell_count++]", which will save you a winset. I also suggest only setting the cells property once, rather than for each card.


So more like this?
            winset(src,"deckgrid","current-cell=[cell_count++]")
for(var/obj/card/a in ccreated)

var/q="<BIG>\icon[a]</BIG> [a] cost: [a.cost] credits"
src<<output(q,"deckgrid:[cell_count++]")
winshow(src,"deckbuy",1)
winset(src,"deckgrid","cells=[cell_count]")
In response to Speedro
You should winset() the number of cells before you output. Because you're just grabbing from a list, you can instead use ccreated.len to figure out the number of cells you need.

If you want to set up columns for the information, you'd want to set the number of columns to 3 (icon, name, cost) in the interface editor, and then at runtime set the rows to ccreated.len, like so:

winset(src,"deckgrid","rows=[ccreated.len]")
for(a in ccreated)
src << output(icon,"deckgrid:[cell_count],1)
src << output(name,"deckgrid:[cell_count],2)
src << output(cost,"deckgrid:[cell_count],3)
cell_count++
In response to Garthor
But then I need to uncheck the "flexible list of entries" option, meaning it no longer accepts list entries?
In response to Speedro
"Flexible list of entries" simply means you can add to the list without having to fiddle with the number of rows or columns. In this case, it's probably easier for you to manage the rows and columns yourself than to wrestle with the automatic functions.
In response to Garthor
Unfortunately what I mean though is that once this option is unchecked, nothing is displayed in the window. :(

EDIT: Although I think it may have something to do with the way I'm specifying columns?

To set rows, I've been using the method you described:
src<<output(a.info,"deckgrid: [rows]")


However, I'm not sure how to use this method to describe column. I tried things such as:
src<<output("<BIG>\icon[a]</BIG>","deckgrid:[rows],1")
however that doesn't work.
In response to Speedro
To set the number of rows, you need to use winset:

winset(src,"deckgrid","rows=[ccreated.len]")


Only after you do that will you be able to output to cells, if it's not a flexible list.
In response to Garthor
EDIT: Posted in code problems...
In response to Speedro
Code

mob
verb
buycards()
src<<"\red please wait, generating cards..."
var/obj/card/list/c=new
c+=typesof(/obj/card/)
var/obj/card/list/ccreated=new
for(var/a in c)
var/n=new a
world<<n
ccreated+=n
var/cell_count = 1


winset(src,"deckgrid","rows=[ccreated.len]")
for(var/obj/card/a in ccreated)
src<<output("<BIG>\icon[a]</BIG>","deckgrid:[cell_count],1")
src<<output(a.name,"deckgrid:[cell_count],2")
src<<output(a.cost,"deckgrid:[cell_count],3")
cell_count ++
winshow(src,"deckbuy",1)
winset(src,"deckgrid","cells=[cell_count]")
I can't see what's wrong... I've made sure the deckgrid's flexible list is unchecked. It also has 3 columns specified, and 1 row. (Of course the rows change on runtime)

In response to Speedro
Speedro wrote:
I can't see what's wrong... I've made sure the deckgrid's flexible list is unchecked. It also has 3 columns specified, and 1 row. (Of course the rows change on runtime)

You never said what the problem was, which is kind of important when asking for someone to fix your problem.

Among many other things, you only increment cell_count once (you probably should indent it into the for() loop).

Your list types are invalid, there is no var/obj/card/list. You just use var/list. So: var/list/c and var/list/ccreated.

Your call to typesof(/obj/card) will return a list of all sub-types and the type /obj/card itself, so you probably want to remove /obj/card from the list.

Finally, I don't think the last call to winset is necessary, but if it is it should probably be done right after you finish building your ccreated list (around your var/cell_count = 1 statement), and should look like this: winset(src, "deckgrid", "cells=3x[ccreated.len]")
In response to Kuraudo
Woopie, I guess it was apparently that var/obj/list is invalid... I also realized that the cell count and column needed to be switched in order for it to display properly... Thanks! :)

A final question: How would I make the card clickable in the grid? E.G.: obj/card/Click()


How could I get it to call the card in grid's click? I tried actually outputting the card itself into the grid, but clicking that doesn't seem to work.
In response to Speedro
Speedro wrote:
A final question: How would I make the card clickable in the grid? E.G.: obj/card/Click()

Yes. However, to do that, you need to actually have a /obj/card object in existence and displayed - obviously - so the Click() procs can be called for it. So you must indeed display an actual atom in the grid by outputting it directly, displaying a plain icon or image (like you've been doing with \icon) won't work.

How could I get it to call the card in grid's click? I tried actually outputting the card itself into the grid, but clicking that doesn't seem to work.

And here comes a second issue related to the above point: for clicking the atom to work, it must actually still be in existence at the time of the click, as mentioned above. In your case, and it's kind of a common beginner error, the atom is immediately deleted by the garbage collector as soon as the procedure (in this case verb) ends, meaning it's deleted soon after it's displayed.
Because grids don't automatically update themselves periodically (like statpanels for instance), once the object is deleted its display will actually just stay there for the player until that cell is updated, though worse can happen; if a new atom is created that uses the internal ID of the now-deleted displayed atom, the players that are viewing the ghost of the deleted atom could actually end up viewing the other, unrelated atom instead.
This is mentioned in the Skin Reference:

Very important: If you send an atom to a grid like you would with a statpanel, keep that object in a list or make sure it actually exists somewhere in the world. Do not use a temporary object that will be deleted when the proc ends, or it can disappear/change in the grid when a new object is created. Statpanels don't have this problem because of the way they update, but it's a good idea even there not to use temporary atoms.

Moral of the story? You need to make sure atoms you display in grids aren't deleted afterward, even if you don't need them to be clickable. Since you just need the garbage collector to skip those objects you could do this with many methods, but it seems just having the list housing those objs in a global var would suit you. That way the list and objs only have to be generated once and can be used by all players without the need to generate them each time.


Note you could actually sneakily use an alternate method to pull off the clicking, which doesn't (by default) involve Click() though by displaying an image again instead of an atom, and simply making that image a link to a topic URL which in turn would report the click to Topic() (and you could even call client/Click() or your own clicking proc from there). Only left-clicks would work with this method (BYOND's clicking system also supports right and middle clicks).