how to add slider in tool mode? - slider

I'm trying to add a slider in tool mode like this:
code:
tool
extends Position2D
export(float) var CustomSlider = 0.1 setget changeSlider_x
func changeSlider_x(changed_val):
CustomSlider=changed_val

First of all, I want to point out that this variable:
export(float) var CustomSlider = 0.1
Is a variant. Even thought Godot shows it as a float on the inspector panel.
This is a float and Godot will also show it as float in the inspector panel:
export var CustomSlider := 0.1
Or if you prefer the type to be explicit, you can write it like this:
export var CustomSlider:float = 0.1
What you specify between parenthesis after export is to controls how it will be shown in the inspector panel.
I know the documentation is a little hard to find - because there are other things called "export" - but here it is: GDScript exports
Now, to get a (useful) slider, you have to either:
Specify a range of values:
export(float, 0, 10) var CustomSlider:
Specify a range of values, with snapping to a step size:
export(float, 0, 10, 0.1) var CustomSlider:
The snapping will be to a multiple of the step size. That is, the snapping is not offset by the minimum and maximum.
Specify an exponential slider, with a maximum greater than zero (the minimum will be zero):
export(float, EXP, 10) var CustomSlider:
With this the slider is not linear. You will find that at the half point the value is the square root of the maximum, not the half. And a third of the way, you find the cubic root of the maximum, and so on. As a result, number are more tightly packed near the maximum (e.g. for a range from 0 to 100, the half point is 10, so the first half goes from 0 to 10 and the second half goes from 10 to 100).
Specify an exponential slider, with a minimum and a maximum:
export(float, EXP, 10, 100) var CustomSlider:
This is similar to the behavior above, except it is offset so the minimum is not zero, but the one you specified.
Specify an exponential slider, with a minimum, a maximum, and snapping to a step size:
export(float, EXP, 10, 100, 2) var CustomSlider:
This creates an exponential slider similar to the previous case. Except this one will snap the value, similar to the snapping described before.
Aside from using export, there is another way to have something show in the inspector panel: use _get_property_list (requires a tool script), which would give us more control (some options are only available this way). Furthermore, we could call property_list_changed_notify to tell Godot to check again what it should show in the inspector panel, and that would allow you to have it change dynamically.
By the way, you can write your variable name in lower caps and with _, and Godot will capitalize it and replace the _ with spaces when it shows it in the inspector panel.

Related

Godot - Populate a screen with different sized panels

Hey I'm looking for some help.
I am trying to populate a screen with panels/2D Nodes of different set sizes. I'll be using 2 arrays to be able to do this but the issue I am coming across is that I'm not sure how to do this without causing gaps between the panels/Nodes.
So what I'm hoping to do is something like while avoiding empty spaces like (see the white square in the middle). I just don't have the technical know how to make this happen. I can always do these things manually but I am hoping to be able to just do it randomly.
I suppose the best way to think about it is like Tetris but it fills it out on it's own
If you require more information, I will be happy to provide but I don't think any else if needed in this instance.
Thanks for any help in advance
The result you want can be archived by partitioning the viewport area. You are going to need more constraints to get what you want (e.g. minimum width, minimum height). Which reminds me, I don't know how you want this to behave when the viewport is resized.
Anyway, the idea is to make a tree structure (and for that you can take advantage of the scene tree), where the root has the area of the viewport. It decides how to split it in two (either vertically or horizontally) using random, and then creates two children for those areas. The children do the same with the area they were given, until you get to a point where splitting would violate the constraints.
To decide where to divide, first figure out the valid range for an horizontal and vertical division. If the range is empty you can't do that division. If you can't do either horizontal or vertical division, then don't divide.
The range for a division goes from the minimum to the total minus the minimum. Something like this:
var range_min_x := minimum_width
var range_max_x := width - minimum_width
var can_divide_x := range_min_x < range_max_x
var range_min_y := minimum_height
var range_max_y := height - minimum_height
var can_divide_y := range_min_y < range_max_y
if can_divide_x and can_divide_y:
if randf() < 0.5:
divide_x(range_min_x, range_max_x)
else:
divide_y(range_min_y, range_max_y)
elif can_divide_x:
divide_x(range_min_x, range_max_x)
elif can_divide_y:
divide_y(range_min_y, range_max_y)
else:
# don't divide
pass
And then those functions look like this:
func divide_x(min:float, max:float):
var division := int(rand_range(min, max))
create_child(Rect2(0.0, 0.0, division, height))
create_child(Rect2(division, 0.0, width - division, height))
func divide_y(min:float, max:float):
var division := int(rand_range(min, max))
create_child(Rect2(0.0, 0.0, width, division))
create_child(Rect2(0.0, division, width, height - division)) ​
Using int is important to avoid one child rounding down and other rounding up, leaving a one pixel gap.
Then in the create_child function you would be creating and adding a child with the given dimension, which would then also be divided by the same means.
You are not going to have empty areas because you would always be adding pairs of children that make up the total of the parent area.

JSX (Photoshop) - document resolution in dpi

I'm working with a jsx script in Photoshop that resizes images to a specific size. The resolution is set at 200 dpi. After running the script, I can check this under Image > Image Size.
Problem is, depending on the image, it initially tends to show the resolution in dots/cm instead of dots/inch. The number itself is correct either way, but I'd like to see it mentioned there as the latter. Is there a way to realize this in JSX?
Thanks!
J
The easy way is to open your Info Panel by going to Window > Info, and then click on the x/y coordinates dropdown in the Info Panel and select inches. The dropdown is the + toward the lower-left of the panel, with the little down arrow at the bottom right of the + symbol (The plus is actually an x axis and y axis representing a coordinate plane). After that, when you check under Image > Image Size, it should show you all information in inches instead of centimeters. This should also show you inches anywhere else you look in Photoshop's interface, too, such as the rulers.
An exception would be that when using selection tools, such as the marquee tool with a setting like "fixed size" selected, you can override the units setting by typing in another unit in the Width and Height sections at the top of the window. You can even mix and match units, making a precise selection that is, for example, exactly 250 pixels (px in the Width setting) by 30 points (pt in the Height setting). And when you check your image size, it should still show you results in inches.
And finally, to answer your question as it was asked, the following code will change your rulerUnits preference without opening the Info Panel.
#target Photoshop
preferences.rulerUnits = Units.INCHES;
Note that if you want to write other scripts, you can change the rulerUnits to whatever units the script calls for, and then at the end of the script put your units back the way you had them.
#target Photoshop
// Save the original rulerUnits setting to a variable
var originalRulerUnits = preferences.rulerUnits;
// Change the rulerUnits to Inches
preferences.rulerUnits = Units.INCHES;
//
// Do magical scripty stuff here...
//
// Restore the original setting
preferences.rulerUnits = originalRulerUnits;
// List of rulerUnits settings available
// Units.CM
// Units.INCHES
// Units.MM
// Units.PERCENT
// Units.PICAS
// Units.PIXELS
// Units.POINTS

Cannot change polygon 'size' every repeat in Builder

I'm using Builder v1.80.06
I can vary the position of a polygon every repeat easily enough
e.g. I have a Positions list
positions=[[1,1],[1.1,0.9],...]
and in the 'Position field' have :
$positions[0]
and then change it's value in a code block on each repeat.
BUT I want to vary the size in a similar manner with a $sizes list but get an error.
Looking at the generated code, the problem is at the object creation stage. the code generated is:
for a hard coded polygon (ie ok)
polygon_1 = visual.Rect(win=win, name='polygon_1',
width=[1.5, .2][0], height=[1.5, .2][1],
ori=0, pos=[0, -0.6],
lineWidth=1, lineColor=[1,1,1], lineColorSpace=u'rgb',
fillColor=[0,1,0], fillColorSpace=u'rgb',
opacity=1,interpolate=True)
for one populated by a variable (not working):
polygon_2= visual.Rect(win=win, name='polygon_2',
width=1.0[0], height=1.0[1],
ori=0, pos=[0,0],
lineWidth=1, lineColor=[1,1,1], lineColorSpace=u'rgb',
fillColor=[1,0,0], fillColorSpace=u'rgb',
opacity=1,interpolate=True)
It complains (rightly) that 1.0[0] makes no sense on the width and height parameters
Even though I have my sizes list instantiated in a code block right at the beginning of the experiment instead of reading $sizes[0] a default float value of 1.0 is used.
Any other suggestions for how to vary the polygon size dynamically at runtime using builder?
I could just take the generated code and drop it into coder I suppose and fix the problem but I want to hand this over to a researcher so would like for them to be able to maintain it.
thanks,
If you set size to be a tuple/list with a pair values [1.2,1.5] or [1,1] does that not fix it?
When you change attributes at runtime, just change the attribute of an existing stimulus instead of instantiating a full new stimulus. The latter is quite heavy on ressources, causing unreliable timing. So do
stim = visual.Rect(win) # instantiation, ressource heavy
stim.attribute = newValue # change attribute. lighter.
I can think of two ways you could do it in a pretty neat way. The first is to set width and height explicitly instead of the size attribute, but using a size-like value. So (removing all parameters not of interest):
polygon_2 = visual.Rect(win)
# Unpack the x,y-sizes to the stimulus .width and .height attributes
newSize = (1.5, 0.2)
polygon_2.width, polygon_2.height = newSize
The second, if the size attribute is really important to use, is to use the Polygin with edges=4 to make it a rectangle:
polygon_2 = visual.Polygon(win=win, edges=4, size=(1.5, 0.2))
# Setting size
polygon_2.size = (0.8, 0.4)
Do try Jon's suggestion first. But the idea with visual.Rect and visual.Circleis to use substitute Polygon's size and vertices for something more relevant. So size can do unexpected things if width/height etc. are not 1.

Objective C: Change Line Width Using UISlider

I have this code to change the stroke width of the line i'm using to draw on the screen.
- (IBAction)changeSize:(id)sender
{
if (Slider.value > 25.0)
{
Width += 3;
}
}
It's working but when i drag the slider thumb straight to the maximum it just adds a little size only but when i do it partly it's getting bigger each step.
Also, when i decrease it on the UISlider it still adds more... it's not decreasing...
How can i do resizing using UISlider??
It looks like you are telling it to increase the width by 3 when the slider is changed.
You would need to set the width equal to the slider value.
Well, you need to understand how sliders work. The Slider.value is your current slider value and it goes from Slider.minimumValue to Slider.maximumValue, witch you can set when creating the slider. You should set those to your minimum line stroke and to maximum line stroke.
In your changeSize method you should then only have 1 line: Width = Slider.value; What you are doing now, is that each time you move the slider and its value is larger then 25.0, you increase the stroke by 3.
As for the speed of slider movement effecting the stroke in your case: How many times the method changeSize will be called is time based, not value. So if you slide it faster, it will be called lesser times then if you slide it slowly, therefor increasing your Width lesser times by 3.

Zedgraph textobj X location depends on text length?

I have a Zedgraph textobj which I want to place always in the same x, y position (ASP.NET image). I noticed that the text doesn't always show in the same starting x position. It shifts depending on the text's length. I tried to have the text to have the same length by padding it with spaces. It helped a little but the result is not always consistent. I am using PaneFraction for coordType.
What's the proper method to have a piece of text to always show in the same x position. I am using textobj as a title because the native title property always shows up centered and I need my title be left aligned to the graph.
No, it does not depend on text lenght, however...
It depends on various other things:
Horizontal and vertical align of the text box (see: Location )
Current size of the pane. The font size is scaled dynamically to fit the changing size of the chart.
Counting proper positions to have TextObj (or any other object) always at the same place is quite hard. So you need avoid as much as you can any numbers/fractions in your location coordinates. ZedGraph sometimes calculates the true position in quite odd way then.
You haven't provided any code, so it's hard to tell if and where you made the mistake (if any). But, if I were you, I would do something like that:
TextObj fakeTitle = new TextObj("some title\n ", 0.0, 0.0); // I'm using \n to have additional line - this would give me some space, margin.
fakeTitle.Location.CoordinateFrame = CoordType.ChartFraction;
fakeTitle.Location.AlignH = AlignH.Left; // Left align - that's what you need
fakeTitle.Location.AlignV = AlignV.Bottom; // Bottom - it means, that left bottom corner of your object would be located at the left top corner of the chart (point (0,0))
fakeTitle.FontSpec.Border.IsVisible = false; // Disable the border
fakeTitle.FontSpec.Fill.IsVisible = false; // ... and the fill. You don't need it.
zg1.MasterPane[0].GraphObjList.Add(fakeTitle);
I'm using ChartFraction coordinates instead of PaneFraction (as drharris suggests) coordinates to have the title nicely aligned with the left border of the chart. Otherwise it would be flushed totally to the left side (no margin etc...) - it looks better this way.
But make sure you didn't set too big font size - it could be clipped at the top
Are you using this constructor?
TextObj(text, x, y, coordType, alignH, alignV)
If not, then be sure you're setting alignH to AlignH.Left and alignV to AlignV.Top. Then X and Y should be 0, 0. PaneFraction for the coordType should be the correct option here, unless I'm missing your intent.
Alternatively, you can simply download Zedgraph code, edit it to Left-align the title (or even better, provide an option for this, which should have been done originally), and then use it in production. Beauty of open source.