Shoes: Element.width return 0 - ruby

I don't understand why the width function is implemented on all elements if it returns 0 for non-zero width elements. The following returns 0 for me.
Shoes.app do
p = para "My width is: "
para p.width
end
Why is that? (app.width does not return 0)

The problem is that the size of the para object is determined dynamically when it is drawn. At the time you create the second para, nothing has actually been laid out yet, so a width hasn't been set. You can see that accessing the width after drawing works as expected:
Shoes.app do
p = para "My width is: "
#para = para p.width
button 'Get Width' do
#para.text = p.width
end
end
The way to get around this is to use the start method, which is called when the containing slot is drawn for the first time:
Shoes.app do
p = para "My width is: "
width = para p.width
start do
width.text = p.width
end
end

Related

Why is the code printing the character in the same positions, even though I have conditioned to move the position? I want to print the input like chat

Note: self.bitmap.draw_text(0,0,220+p,20, 'A', 1) where 220+p is the coordinates x, and 20 is y of screen
Why is the code showing the character in the same positions, even though I have conditioned to move the position? I tried to do it in another way and the 'A' always came ahead regardless of whether I added p+30. I want use it to create a chatbox with RGSS (Rpg Maker XP).
The result of this code works, I wrote this code, but it works not as intended. It Show the button that I pressed, but when I press A and B, the A is always in the first coordinates then came B: "AB" is showed but never "BA" even if I pressed B first.
class Sprite_Texto < Sprite
def initialize
super(nil)
self.bitmap = Bitmap.new(150,20)
self.ox = 100
self.z = 999
self.bitmap.font.size = 14
self.bitmap.font.bold = true #negrito
self.bitmap.font.name = "Verdana"
end
def escrever
self.bitmap = Bitmap.new(700,700)
p = 0
teste = Win32API.new("user32","GetAsyncKeyState",['i'],'i').call(0x10)
teste2 = Win32API.new("user32","GetAsyncKeyState",['i'],'i').call(0x41)
teste3 = Win32API.new("user32","GetAsyncKeyState",['i'],'i').call(0x42)
if teste2 > 0
p = p+30
self.bitmap.draw_text(0,0,220+p,20, 'A', 1)
else
if teste3 > 0
p = p+30
self.bitmap.draw_text(0,0,220+p,20, 'B', 1)
end
end
end
end

How do I put the width or height of an object in to a variable?

I am currently using VBScript in Qlikview and I ran into a problem. My code currently looks like this:
sub resize
set obj = ActiveDocument.GetSheetObject("TX05")
set fr = obj.GetFrameDef
set pos = fr.Rect
set WidthUser = ActiveDocument.Variables("vWidth")
' set OriginalWidth = pos.Width
' set OriginalHeight = pos.Height
' Ratio is 2.5
pos.Width = Cint(WidthUser.GetContent.String) * 2.5
' pos.Height = vPreferredWidth/vOriginalWidth * vOriginalHeight
pos.Height = 200 * 2.5
obj.SetFrame fr,true,dummy
msgbox("Changed Width to: " & pos.Width/2.5 & " " & Chr(13) & "Changed Height to: " & pos.Height/2.5)
End sub
vWidth is a variable where the user can input his desired width.
So what am I trying to achieve? I want the user to be able to type in his desired width of an object and then press a button called "resize". When the button is pressed, the object width should change to the desired width and the object height should also change in relation to the change in width.
For example, we start with an object that has a Width of 120 and a height of 200. The user then puts in his desired Width of 60 and then presses the button "resize". The object width should change to 60 and the object height should change to 100 (60/120*200=100). So in the end result the ratio width/height is still the same (120/200 vs 60/100).
The problem I am having is trying to capture the original width and height of my object. I tried using:
set OriginalWidth = pos.Width
set OriginalHeight = pos.Height
But that doesn't work at all. I tried all kinds of variations but nothing worked so far. What I don't understand is that when I type:
msgbox(pos.Width)
I do get a result, but when I use:
set OriginalWidth = pos.Width
msgbox(OriginalWidth)
I get nothing at all (I get thrown back into my script).
Can anyone help me figure this out? Would also love some feedback on the rest of the code, because I just started learning this.
Thanks in advance!
EDIT after help I changed my code to:
sub resize
' Ratio is 2.5
set obj = ActiveDocument.GetSheetObject("TX05")
set fr = obj.GetFrameDef
set pos = fr.Rect
set WidthUser = ActiveDocument.Variables("vWidth")
set HeightUser = ActiveDocument.Variables("vHeight")
OriginalWidth = pos.Width
OriginalHeight = pos.Height
DesiredUserWidth = Cint(WidthUser.GetContent.String)
pos.Width = DesiredUserWidth * 2.5
pos.Height = DesiredUserWidth / OriginalWidth * OriginalHeight * 2.5
obj.SetFrame fr,true,dummy
msgbox("Changed Width to: " & pos.Width/2.5 & " " & Chr(13) & "Changed Height to: " & pos.Height/2.5)
End sub
Read the docs for Set and from now on use it only when you assign an object to a variable.
set OriginalWidth = pos.Width
==>
OriginalWidth = pos.Width

How can I make a VBS Message Box appear in a random place?

In VBS script, I have created a simple message box application. It currently stays in front of all windows until the user responds and uses very simple coding
X=MsgBox("Test Text" ,1+4069, "Test Title")
But it always appears in the same place. Is there any way of making it appear in a random place on the screen? Please help!
There is one type of box which allows you to position it on the screen: InputBox
Title = "Hello"
DefaultValueText = "Hello Stackoverflow !"
message = "Type something here"
XPos = 0
YPos = 0
Text = InputBox(message,Title,DefaultValueText,XPos,YPos)
XPos = 3000
YPos = 800
Text = InputBox(message,Title,DefaultValueText,XPos,YPos)
#Hackoo was almost there,
I used his and here is what I made out of it.
dim r
randomize
r = int(rnd*500) + 1
r2 = int(rnd*1500) + 1
Title = "Hello"
DefaultValueText = "Hello!"
message = "Type something here!"
XPos = r
YPos = r2
Text = InputBox(message,Title,DefaultValueText,XPos,YPos)

How to display blinking text over an image in Corona SDK?

I seem to have some serious problems here - I'm trying to display an image and transition it in, then have blinking text over it at the bottom.
function Splash()
local item = display.newImage("SplashImage.png")
item.x = display.contentWidth*0.5
item.y = display.contentHeight*0.5
item.alpha=0
transition.to(item, {time =1500, alpha=1, onComplete=Blink})
end
-- blinking text
function Blink()
text = display.newText("This is Blinking Text", 100, 100, "Arial", 22)
text.x = display.contentWidth/2
text.y = display.contentHeight/1.2
text.alpha=0
transition.to(text, {time =1500, alpha=1, onComplete=Blink2})
end
function Blink2()
if (text.alpha > 0) then [--THIS IS THE LINE THAT IS BROKEN APPARENTLY]
transition.to(text, {time=1500, alpha=0})
else
transition.to(text, {time=1500, alpha=1})
end
end
txt_blink = timer.performWithDelay(500, Blink2, 0)
Code breaks with error "Attempt to index upvalue 'text' (a nil value)"
I'm a total noob at this so be gentle!
Your problem is that, when Blink2() is called it looks for an object "text" which is not created in that time. So you should check first if there is an object called "text" or not. Here is the new blink2() function for you:
function Blink2()
if text ~= nil then
if (text.alpha > 0) then
transition.to(text, {time=1500, alpha=0})
else
transition.to(text, {time=1500, alpha=1})
end
end
end
Try this and see if it works for you.
--> Pre-declare the text variable
local blinkingText
--> Create the splash function
function Splash()
local item = display.newImage("SplashImage.png")
item.x = display.contentWidth*0.5
item.y = display.contentHeight*0.5
item.alpha=0
transition.to(item, {time =1500, alpha=1, onComplete=createBlinkingText})
end
--> Create the blinking text
function createBlinkingText()
blinkingText = display.newText("This is Blinking Text", 100, 100, "Arial", 22)
blinkingText.x = display.contentWidth/2
blinkingText.y = display.contentHeight/1.2
blinkingText.alpha=0
transition.to(blinkingText, {time =1500, alpha=1, onComplete=startBlinking})
end
--> Start the blinking
function startBlinking()
if (blinkingText.alpha > 0) then
transition.to(blinkingText, {time=1500, alpha=0, onComplete=startBlinking})
else
transition.to(blinkingText, {time=1500, alpha=1, onComplete=startBlinking})
end
end
--> Call the splash function
Splash()
I changed a couple variable names so you can better understand them.
The error indicates that your function Blink2 has been asked to access a variable "text" which has not been previously declared as a table/object. Put a:
local text = {}
at the top and it should solve your problem.

Create a title with two colors in RMagick

I need to create a caption for a picture using two colors, all the words are in black except one in other color...
I've been reading the docs of RMagick I can't find a way of doing this... What I'm using right now to create the text is:
txt_name = Draw.new
image.annotate(txt_name, 0,0,0,0, "This RED has to be in red") do
self.gravity = Magick::NorthGravity
self.pointsize = 20
self.fill = '#000000'
txt_name.font_weight = 100
self.font_family = 'Arial'
end
Any idea?? Or something to read so I can make this work??
Thanks!
Something like the following should work for you. (Please note that this is just to show you the process; I wouldn't recommend putting code like this into production. This is begging to be put in its own class EDIT: see below):
draw = Magick::Draw.new
Set all of the text attributes on the draw object:
draw.pointsize = 20
draw.fill = '#000000'
draw.gravity = Magick::NorthGravity
draw.font_weight = 100
draw.font_family = "Arial"
draw.font_style = Magick::NormalStyle
Get your image object (this one is just a new blank image):
image = Magick::Image.new(300,200)
Set up the strings and measure them with get_type_metrics:
black_text = "This "
red_text = "RED"
remainder = " has to be in red"
black_text_metrics = draw.get_type_metrics(black_text)
red_text_metrics = draw.get_type_metrics(red_text)
remainder_metrics = draw.get_type_metrics(remainder)
Annotate with the black text:
draw.annotate(image,
black_text_metrics.width,
black_text_metrics.height,
10,10,black_text)
Change the color to red and add the red text:
draw.fill = "#ff0000"
draw.annotate(image,
red_text_metrics.width,
red_text_metrics.height,
10 + black_text_metrics.width, # x value set to the initial offset plus the width of the black text
10, red_text)
Change the color back to black and add the remainder of the text:
draw.fill = "#000000"
draw.annotate(image,
remainder_metrics.width,
remainder_metrics.height,
10 + black_text_metrics.width + red_text_metrics.width,
10, remainder)
Edit: This may give you an idea of how you could structure this a bit nicer:
TextFragment = Struct.new(:string, :color)
class Annotator
attr_reader :text_fragments
attr_accessor :current_color
def initialize(color = nil)
#current_color = color || "#000000"
#text_fragments = []
end
def add_string(string, color = nil)
text_fragments << TextFragment.new(string, color || current_color)
end
end
class Magick::Draw
def annotate_multiple(image, annotator, x, y)
annotator.text_fragments.each do |fragment|
metrics = get_type_metrics(fragment.string)
self.fill = fragment.color
annotate(image, metrics.width, metrics.height, x, y, fragment.string)
x += metrics.width
end
end
end
and a usage example:
image = Magick::Image.new(300,200)
draw = Magic::Draw.new
draw.pointsize = 24
draw.font_family = "Arial"
draw.gravity = Magick::NorthGravity
annotator = Annotator.new #using the default color (black)
annotator.add_string "Hello "
annotator.add_string "World", "#ff0000"
annotator.add_string "!"
draw.annotate_multiple(image, annotator, 10, 10)

Resources