How to get buttons working on Badger2040 in Tinygo - rp2040

I've been trying to access the Badger2040 buttons through Tinygo and not having any luck (I have succeeded in CircuitPython before).
When I try to change the led state based on Button A, the led is switched on and never switches off:
package main
import (
"machine"
"time"
)
func main() {
led := machine.LED
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
button_a := machine.BUTTON_A
button_a.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
for {
led.Set(button_a.Get())
time.Sleep(time.Second / 4)
}
}
If I change the led.Set to pass in !button_a.Get() then the led is always off.
It appears that button_a.Get() is always returning true.
Does anyone have any ideas please?

I based this on the included TinyGo examples (not for the Badger2040) - which used PinInputPullup - but it turns out the Badger2040 needs to use PinInputPulldown, i.e. configure the button like this:
button_a.Configure(machine.PinConfig{Mode: machine.PinInputPulldown})
Note that this works for the up/down/a/b/c buttons. The user button also toggles, but is inverted, i.e. returns true when not pressed.

Related

Only show title bar on floating windows

In awesome 4.0, is there a way to only display the titlebar on floating windows?
Looking at the docs, there doesn't seem to be an option out of the box.
To specify; I'm looking for a solution that work when I dynamically switch windows between tiling and floating.
A bit late, but I wanted to do this too and I got it mostly working. It doesn't cover all the cases when you'd expect a client to show or hide its titlebar, but it's close enough for my use case.
It's rather simple, first you need to disable titlebars for every client, so add titlebars_enabled = false in the properties of the default rule matching all clients.
Then, when a client becomes floating you need to toggle on his titlebar, and toggle it off when it stops floating.
I wrote this little helper function to make the code clearer. It's rather simple, if s is true then show the bar, hide it otherwise. But there's a catch, in our case the windows never had a titlebar so it isn't created yet. We send the signal to have one built for us if the current one is empty.
-- Toggle titlebar on or off depending on s. Creates titlebar if it doesn't exist
local function setTitlebar(client, s)
if s then
if client.titlebar == nil then
client:emit_signal("request::titlebars", "rules", {})
end
awful.titlebar.show(client)
else
awful.titlebar.hide(client)
end
end
Now we can hook the property change:
--Toggle titlebar on floating status change
client.connect_signal("property::floating", function(c)
setTitlebar(c, c.floating)
end)
But that only applies to clients that changes states after being created. We need a hook for new clients that are born floating or in a floating tag:
-- Hook called when a client spawns
client.connect_signal("manage", function(c)
setTitlebar(c, c.floating or c.first_tag.layout == awful.layout.suit.floating)
end)
And finally, if the current layout is floating, clients don't have the floating property set, so we need to add a hook for layout changes to add the tittlebars on clients inside.
-- Show titlebars on tags with the floating layout
tag.connect_signal("property::layout", function(t)
-- New to Lua ?
-- pairs iterates on the table and return a key value pair
-- I don't need the key here, so I put _ to ignore it
for _, c in pairs(t:clients()) do
if t.layout == awful.layout.suit.floating then
setTitlebar(c, true)
else
setTitlebar(c, false)
end
end
end)
I didn't want to spend to much time on this so it doesn't cover cases where a client gets tagged in a floating layout, or when a client is tagged multiple times and one of those tag is floating.
Change
{ rule_any = {type = { "normal", "dialog" }
}, properties = { titlebars_enabled = true }
},
to
{ rule_any = {type = { "dialog" }
}, properties = { titlebars_enabled = true }
},
Niverton's solution works very well for simply switching from tiling to floating modes; however, floating windows will lose their titlebar when maximized and then unmaximized. To fix this, a better solution would be to replace
client.connect_signal("property::floating", function(c)
setTitlebar(c, c.floating)
end)
with
client.connect_signal("property::floating", function(c)
setTitlebar(c, c.floating or c.first_tag and c.first_tag.layout.name == "floating")
end)
This should fix the issue so that windows can be properly maximized without having to switch to tiling mode and back to get the titlebars again.
I found this general idea on a reddit post about the subject, provided by u/Ham5andw1ch. I have just simplified the code using Niverton's proposed function and some short-circuit logic.

How to keep TYPO3's RTE from adding an empty line before <ul>s

In TYPO3 4.5 as well as 6.1, whenever I add an unordered list element, RTEhtmlarera (or some of its many processing routines) will add an extra
<p> </p>
before the ul tag on saving the content element.
This happens only once, when the ul is inserted first. When the p tag is removed and the content element is saved again, it won't happen again.
How can this erroneous behaviour be removed?
Hi try set encapsLines to zero..
Setup typoscript:
tt_content.stdWrap.dataWrap >
lib.parseFunc_RTE.nonTypoTagStdWrap.encapsLines >
Not a real solution but maybe a hint in the right direction.
If you write down your list, do not press enter before the first list entry but shift+enter.
Example:
Here comes the list: <<-- AT THIS POINT PRESS SHIFT+ENTER
- a <<-- Here it does not matter if you press enter or shift+enter
- b
- c
- ...
This works for me as a workaround. I've done a lot of research in sysext:rtehtmlarea but nothing worked. So this looks for me like some kind of mysterious bug/feature connected with the "BR to P" (or vice versa) configuration you can define in pageTS or Setup. BTW: I never fully understood this conversion-thing :)
For me with 6.1 this worked:
lib.parseFunc_RTE {
externalBlocks = table, blockquote, ol, ul, div, dl, address, hr
externalBlocks {
ol.stripNL=1
ol.stdWrap.parseFunc = < lib.parseFunc
ul.stripNL=1
ul.stdWrap.parseFunc = < lib.parseFunc
# i have also seen this setting, but didnĀ“t test it:
# blockquote.stripNLprev = 1
# blockquote.stripNLnext = 1
}
}
I removed many lines for this example, be aware that you overwrite previous settings by using {} ..

World of Warcraft Lua - Changing frame:SetAttribute()

I'm working on an addon for World of Warcraft that completely overhauls the interface to adapt to my play style.
In this addon, I would like to have a large button that acts as a "main dps rotation" for my mage. I would like it to change what spell it casts based on what is optimal at any given time. It doesn't cast the spell automatically, it just presents the next best option for the user.
Here is my code so far:
print "Interface Overhaul : LOADED"
heatingUpIsActive = false
print(heatingUpIsActive)
local Button = CreateFrame("Button", "MyButton", UIParent,"SecureActionButtonTemplate")
Button:SetWidth(256)
Button:SetHeight(256)
Button:SetFrameStrata("HIGH")
Button:SetPoint("LEFT")
Button:SetText("Main Rotation")
Button:RegisterForClicks("AnyUp")
Button:SetAttribute("type", "spell")
Button:SetAttribute("spell", "Fireball")
Button:RegisterEvent("UNIT_AURA");
local function auraGained(self, event, ...)
if (UnitAura("player", "Heating Up")) then
if (heatingUpIsActive == false) then
heatingUpIsActive = true
print (heatingUpIsActive)
print ("Heating Up is active!")
Button:SetAttribute("spell", "Inferno Blast")
end
else
heatingUpIsActive = false
print("Heating Up is NOT active.")
print(heatingUpIsActive)
end
end
Button:SetScript("OnEvent", auraGained);
local tex = Button:CreateTexture("ARTWORK");
tex:SetPoint("LEFT")
tex:SetWidth(256)
tex:SetHeight(256)
tex:SetTexture("Interface\\AddOns\\InterfaceOverhaul\\Button2")
If heatingUpIsActive == true, I would like the button to cast ("spell", "Inferno Blast") instead of ("spell", "Fireball"), but it doesn't work if I place that into the correct part of the if statements.
Any thoughts?
As Mud said, you cannot rebind buttons in combat anymore. Blizzard made this change to prevent bots from being able to automate combat. Notably, in order to cast a spell you need to use one of the secure templates, and these secure templates only allow modification of the attributes that control what they do when you're not in combat. So you cannot have one button change spells mid-combat. Similarly, they also prevent you from modifying attributes like their position or visibility, so you cannot move buttons under the mouse either.
The best you can do is display a visual indicator of what spell should be cast, but rely on the user to actually press the correct button.

Simulating mouse events in Actionscript 3

Given stage coordinates (x,y), I want to make my flash app behave just as if the user clicked at position (x,y). That is, something like
function simulateClick(x:Number, y:Number):void{
var e:MouseEvent = new MouseEvent(MouseEvent.CLICK, true, false, x, y)
stage.dispatchEvent(e);
}
I've found a bunch of pages talking about this kind of thing, and they all give solutions similar to the above. However, this isn't equivalent to the user clicking at (x,y). There are two problems:
The first is that e.stageX and e.stageY are both 0. I can't set them directly. The documentation says they are calculated when e.localX and e.localY are set, but this isn't happening when I set e.localX before dispatchEvent, nor in the event listener.
I could rewrite all of my event listeners with something like this:
var p:Point = e.target.localToGlobal(new Point(e.localX, e.localY));
Is this the only option?
The second problem is that my event listeners are registered with children of stage, not stage itself. So I need to find out what target to call dispatchEvent on. Clearly Flash is capable of determining what the target should be, ie which object owns the topmost pixel visible at position (x,y), because it does so when the user actually clicks. Is there an easy way to get at this information, or should I just write my own recursive function to do the same thing? I'm using DisplayObjectContainer.getObjectsUnderPoint at the moment, but it's not quite right.
I'm writing in FlashDevelop, if that makes any difference.
e.stageX/Y is populated correctly for me... also getObjectsUnderPoint() seems to work fine. I'm assuming that the x/y values passed to simulateClick are global coordinates?
edit: as pointed out in the comments, the mouse event must be dispatched on InteractiveObject instances... modified the code accordingly.
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;
public function simulateClick(x:Number, y:Number):void
{
var objects:Array = stage.getObjectsUnderPoint(new Point(x, y));
var target:DisplayObject;
while(target = objects.pop())
{
if(target is InteractiveObject)
{
break;
}
}
if(target !== null)
{
var local:Point = target.globalToLocal(new Point(x, y));
var e:MouseEvent = new MouseEvent(MouseEvent.CLICK, true, false, local.x, local.y);
target.dispatchEvent(e);
}
}
public function addedToStage():void
{
var parent:Sprite = new Sprite();
stage.addChild(parent);
var child:Sprite = new Sprite();
child.name = 'child 1';
child.graphics.beginFill(0xff0000, 1);
child.graphics.drawRect(0, 0, 200, 200);
child.graphics.endFill();
var child2:Sprite = new Sprite();
child2.name = 'child 2';
child2.graphics.beginFill(0xff00ff, 1);
child2.graphics.drawRect(0, 0, 100, 100);
child2.graphics.endFill();
child2.x = 150;
child2.y = 150;
var bmpData:BitmapData = new BitmapData(80, 80, false, 0x00ff00);
var bmp:Bitmap = new Bitmap(bmpData);
bmp.name = 'bitmap';
child2.addChild(bmp);
parent.addChild(child);
parent.addChild(child2);
child2.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void
{
trace('target: ' + e.target.name);
trace('localX: ' + e.localX);
trace('localY: ' + e.localY);
trace('stageX: ' + e.stageX);
trace('stageY: ' + e.stageY);
});
simulateClick(190, 190);
}
Output:
target: child 2
localX: 40
localY: 40
stageX: 190
stageY: 190
For question 1: After you create the MouseEvent (assigning it a local x,y) you should be able to directly reference e.stageX and set it to what you want prior to dispatching the event. It's just a property of the MouseEvent instance.
For #2, currentTarget is always the thing that is topmost under the mouse, while target is the thing that is dispatching the event -- assuming the event is genuinely being dispatched by mouse interaction. In your case, you can set the target to be whatever object you have dispatching the event, and set the currentTarget arbitrarily. The question really is whether this is the most efficient way to deal with what's under the mouse right now; and the answer is, probably not. You'd be a lot better off using a MOUSE_OVER event to keep tabs on what the mouse is over right now, store that as a variable you can use when you want to call this, and don't try to iterate the whole display chain all the time (because Flash natively does that much faster than you can do it in a loop). If you put a mouseOver on the stage, and just check the currentTarget, you'll be getting whatever the topmost item is under the mouse on every frame where it changes.
You should be aware that (to prevent some obvious nasty scripts), certain actions cannot be triggered by mouse events that are generated dynamically by actionscript. These include opening a file reference and going fullscreen.
I have faced this issue too, gave me a bit of a headache.
In my situation I was creating the event, performing a bit of complex computations, but I couldn't retrieve global coordinates even though I had already set local coordinates.
Actually the solution was quite obvious in my case...
Global coordinates are populated only AFTER the event is dispatched, otherwise how can the event know how to translate local to global?
This is another pitfall, on top of not checking for the object used to dispatch event being an InteractiveObject.
I post this because someone else may face this issue due to both pitfalls. A quick answer easy to read.

apply new layer to a slice of a volume webgl

i have two volumes (.nrrd) of different qualities. the user can browse through the layers. if a key is pressed
i want to load the slice of the volume with better quality.
my volume is similar to this one: lesson 10 xtk
i've found:
volume.children[2].children[0].children[0].texture.file = "http://path/to/file.ext";
but if i apply some kind of file (.jpg, .dcm) nothing happens.
is this the right approach to change the slice to go inside the children and change the texture?
or shall i load the selected slice seperate as an object and apply it to the "lower-quality-volume" somehow?
edit:
this is what i tried so far (i get errors with dcms but not with jpgs):
if (event.keyCode == 83) { // "s"-button
volume.children[2].children[0].children[0].texture.file = "http://localhost:3000/112.jpg";
volume.children[2].children[0].children[0].modified();
r.render();
}
edit2: this is whats in my r.onShowtime = function() {}
volume.children[2].children[0].texture.file = 'http://localhost:3000/112.jpg';
volume.children[2].children[0].visible = true; // to activate the first layer
volume.children[2].children[0].modified();
console.log(volume.children[2].children[0].visible +" "+ volume.children[2].children[0].texture.file);
it outputs "true hostname/112.jpg"
when i inspect the .jpg in firebug the header is ok but the answer is "null"
when i inspect console.log(volume.children[2].children[0]); with firebug
.texture.file is set to hostname/112.jpg
when i go to "network" the .jpg has been transfered successfully
please notice that 112.jpg and level.jpg are the same. the first one is getting loaded in r.onShowtime and the other one is loaded at a keypressed event.
EDIT 3: volume.children[2].children[0] is of the type "X.slice", isn't it?
here is my approach: jsFiddle
and this is my actual issue and still not working: jsFiddle
Mhh..
I think a call to object.modified() is missing in the file setter (and in others setters from inject classes). Let's see when Haehn will come if he wants to change something internaly, but for the moment could you try to call it by yourself ?
You can try to add after the modification of texture :
volume.children[2].children[0].children[0].modified();
And if it doesn't work, in addition :
renderer.render();
Edit :
It's strange, I did a similar code and it did something. Can you please try something like that with opening your javascript console (Firefox, Chrome,... has one) and tell me the error you get ?
renderer.onShowtime = {
for (var i=0 ; i< volume.children[2].children.length ; i++) {
volume.children[2].children[i].texture.file="myimage.jpeg";
volume.children[2].children[i].modified();
}
}
It is important you call it in the onShowtime, because before the volume is not loaded, and so slicesX, slicesY... don't exist.
Edit2 :
Hey,
Thanks to the informations you added I think I've got the point ! In the render() method of our renderer3D there is a test on texture._dirty flag, that you cannot change from outside the framework. In addition the 1st rendering with a texture make that flag false, and loading a new texture doesn't seem to set that flag back to true in the current XTK. So, I think, we have to add it in the loader.load(texture, object) method. I'll make an issue on Github and see what Haehn thinks of it !

Resources