Terminal dashboard in golang using "termui" - go

I am working on drawing graphs on the terminal itself from inside a go code.I found this (https://github.com/gizak/termui) in golang. And used this(https://github.com/gizak/termui/blob/master/_example/gauge.go) to draw graph in my code.
Problem is this , as we can see in the code( https://github.com/gizak/termui/blob/master/_example/gauge.go ), they are passing g0,g1,g2,g3 all together in the end "termui.Render(g0, g1, g2, g3, g4)".
In my case I don't know how many gauges to draw before hand so I used a list to store gauge objects and then tried to pass list to render.
termui.Render(chartList...)
But it creates only one gauge.
This is how I am appending elements in the list.
for i := 0; i < 5; i++ {
g0 := termui.NewGauge()
g0.Percent = i
g0.Width = 50
g0.Height = 3
g0.BorderLabel = "Slim Gauge"
chartList = append(chartList, g0)
}
what I am getting is a gauge for i=4 only. when I am doing termui.Render(chartList...)
Am I doing something wrong?
PS - I have modified question based on the answer I got in this question.

Here is a good read on Variadic Functions
Take a look at the function signature of Render, https://github.com/gizak/termui/blob/master/render.go#L161
func Render(bs ...Bufferer) {
All you need to do is
termui.Render(chatList...)
assuming chartList is a []Bufferer
Edit
You are only seeing one because they are stacking on top of one-another. To see this add
g0.Height = 3
g0.Y = i * g0.Height // <-- add this line
g0.BorderLabel = "Slim Gauge"
From a quick review of the project, it appears there are ways for auto-arranging that have to do with creating rows (and probably columns). So you might want to explore that, or you will need to manually position your elements.

Related

How to change the XFade on a transition node in script?

I'm currently learning Godot and my textbook seems to be a bit out of date as it still uses the deprecated AnimationTreePlayer. So I've had to figure out AnimationTree on my own. The exercise for this lesson talks about changing the XFade for the transition node to a random value when the player presses the "up" key but I cannot for the life of me figure out how to do it. I see in the documentation that AnimationNodeTransition has a set_cross_fade_time(value) method but how do I get to it? How do I even access the tranisition node in the script? I've tried things like $AnimationTree/Transition and $AnimationTree["parameters/Transition"] but nothing I've tried works.
My script is currently on the root node and the node tree looks like this:
Sprite [script is here]
AnimationPlayer
AnimationTree
Let us say you have your AnimationTree with the AnimationPlayer set on the anim_player property. And the tree_root of the AnimationTree is an AnimationNodeBlendTree, where - among other nodes - you have an AnimationNodeTransition.
As you are aware, we can get some "paramters" of the AnimationTree, they should appear in the Inspector Panel. And there you should find this one:
$AnimationTree.get("parameters/Transition/current")
Where "Transition" is the name of the node in the AnimationNodeBlendTree. But there isn't a parameter for the xfade_time.
Instead we will get the root of the AnimationTree (in other words, the AnimationNodeBlendTree) like this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
Then we can get the nodes like this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var node := blend_tree.get("nodes/NodeName/node")
By the way, if you change "/node" to "/position" you get a Vector2 with the position of the node on the editor.
So, let us say we want a node called "Transition", which is our AnimationNodeTransition. We do this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var transition := blend_tree.get("nodes/Transition/node") as AnimationNodeTransition
And finally we can access xfade_time. Set a random value you said? This should do:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var transition := blend_tree.get("nodes/Transition/node") as AnimationNodeTransition
transition.xfade_time = rand_range(0.0, 120.0)
Or as a one line:
$AnimationTree.tree_root.get("nodes/Transition/node").xfade_time = rand_range(0.0, 120.0)
Be aware that the value of xfade_time is the number of seconds for the transition. So setting 120 give you a two minutes transition.

Divide an image into non-overlapping blocks and applying the 2D DWT on each block

I am working on creating an image splicing detection software so I need to divide the image into non-overlapping blocsk and apply Discrete Meyer Wavelet Transform on each block of the image
I have tried the blockproc function to do that but I got no result:
I = imread('pears.png');
fun = #(block_struct)...
dwt2(block_struct.data,'dmey');
C = blockproc(I,[64 64],fun);
So how can I access the [cA,cH,cV,cD] of dwt2 using the above code?
blockproc assumes that you are outputting an actual image. You cannot use this for multiple outputs. If you truly want this to work with blockproc, you will unfortunately need to call blockproc four times, with each time extracting the different set of coefficients for the directions. Also note that the 2D DWT only works for grayscale images, so you need to convert to grayscale before actually doing any processing. The pears image you've chosen is a colour / RGB image.
I'd like to reference this post on how to select the Nth output given an input function: How do I get the second return value from a function without using temporary variables?. You will need to save this code to a file called nth_output.m, which allows you to programatically extract all output variables from a function and choose only one output.
function value = nth_output(N,fcn,varargin)
[value{1:N}] = fcn(varargin{:});
value = value{N};
end
Simply omitting the extra output arguments when you call the function only gives you the first output, which is what your blockproc code is doing. Once you do that, it's a matter of creating 4 anonymous functions to capture each output from dwt2, and running blockproc 4 times. Make sure you specify which output you want for each of the anonymous functions, so 1 up to 4 and you simply provide a handle to the function you want to run in addition to the input arguments that go into the function.
Therefore, try something like this:
I = rgb2gray(imread('pears.png'));
fun1 = #(block_struct) nth_output(1, #dwt2, block_struct.data,'dmey');
fun2 = #(block_struct) nth_output(2, #dwt2, block_struct.data,'dmey');
fun3 = #(block_struct) nth_output(3, #dwt2, block_struct.data,'dmey');
fun4 = #(block_struct) nth_output(4, #dwt2, block_struct.data,'dmey');
I = rgb2gray(I);
cA = blockproc(I,[64 64],fun1);
cH = blockproc(I,[64 64],fun2);
cV = blockproc(I,[64 64],fun3);
cD = blockproc(I,[64 64],fun4);
cA, cH, cV, and cD contain the DWT coefficients you need for each set of directions.

How to move an image in Lua?

I am new to Lua programming and I am having problems while trying to move an image from a set of coordinates to another.
What I am trying to create is to be used with the X-Plane flight simulator. There is a library called SASL (www.1-sim.com), that was created to make plugins (for X-Plane) creation easir, since the default language is C++ and many people find it difficult.
In general, SASL works as a bridge between Lua and X-Plane, in general lines, the scripts you write reads some data straight from X-Plane (DataRefs) while it is running and depending on the code you wrote its execute commands or many other things that it is possible.
So, when using SASL to create cockpit/panel gauges it uses a base file, named 'avionics.lua' that works as a class and loads all gauges you create for the specific aircraft you are working on. For example my avionics.lua file looks like this:
size = { 2048, 2048 }
components = {
flaps {};
};
where, 'size' is the size that will be used for things to be drawn and components is an array of gauges, in this case the flaps gauge.
The rest of the work is to create the gauge functionality and this is done in a separate file, in my case, called 'flaps.lua'.
Within flaps.lua, is where I need to code the flaps indicator functionality which is to load 2 images: one for the back ground and the second one for the flaps indicator.
The first image is a fixed image. The second one will move throught the 'y' axis based on the flaps indicator DataRef (flapsDegree property below).
The code below when X-Plane is running displays the background image and the flaps indicator on its first stage which is 0 as you can see on the image.
size = {78,100}
local flapsDegree = globalPropertyf("sim/cockpit2/controls/flap_ratio")
local background = loadImage("gfx/Flaps.png")
local indicator = loadImage("gfx/Flaps_Indicator.png")
local flaps = get(flapsPosition)
components = {
texture { position = {945, 1011, 60, 100}, image = background},
texture { position = {959, 1097, 30, 9}, image = indicator},
}
Image
Now, the problem comes when I need to implement the logic for moving the 'indicator' image through the 'y' axis.
I have tried this code without success:
if flaps == 0.333 then
indicator.position = {959, 1075, 30, 9}
end
So how could I accomplish that?
I am not familiar with the SALS library. I just had a quick look into it.
Everything you need to know is in the manuals on the website you linked.
In particular http://www.1-sim.com/files/SASL300.pdf
Everytime your screen is updated each components draw() function will be called.
So if you want to change something dynamically you have to put that into the component's draw function.
If you open the SALS sources you'll find basic components which show you how to use that stuff. One of them is needle.lua:
-- default angle
defineProperty("angle", 0)
-- no image
defineProperty("image")
function draw(self)
local w, h = getTextureSize(get(image))
local max = w
if h > max then
max = h
end
local rw = (w / max) * 100
local rh = (h / max) * 100
drawRotatedTexture(get(image), get(angle),
(100 - rw) / 2, (100 - rh) / 2, rw, rh)
end
If you check the manual you'll find that there is not only a drawRotatedTexture function but many other functions for drawing stuff. Just play around. Try drawTexture for your purpose.
If you don't know what you have to program, open every single lua file in the library and read it together with the Lua reference manual and the SALS documentation until you understand what is going on. Once you understand the existing code you can extend it with ease.

How to save 3d arrays in Matlab that are generated in a loop?

I'm reading in 3d arrays, subtracting all of them from one of them, and trying to save the results as the same type of arrays. They are all equal sizes to each other, 1888x3520x6.
Here is the piece of code that I have:
[FileName,PathName,FilterIndex] = uigetfile('*.x3d*','MultiSelect','on');
numfiles = size(FileName,2);
FileName{1}
entirefile1 =fullfile(PathName,FileName{1})
Im1 = x3dread(entirefile1);
for j = 2:numfiles
FileName{j}
entirefile2 =fullfile(PathName,FileName{j})
Im2 = x3dread(entirefile2);
J = num2str(j);
strcat('ImDelta', J);
ImDelta = imsubtract(Im1, Im2);
end
I see that I'm creating a character sring by using strcat. But I'm not making it into a new file name. Only one file is resulting at the end of the loop.
(x3dread function is similar to "load" for working with images, only it is specifically written to handle the type of the 3dimention files that I have.)
Any help is appreciated. I'm just a beginner.

Want to move a slider and all the others update in Matlab?

I have GUI in Matlab that I have made using the Programmatic approach. It has 6 sliders and I want to be able to move one of them and have the others update as if i clicked them again but to stay in the same place. I am guessing I will need to use the set() function. Is there some function to do this in matlab already? I have been looking around. Any suggestions or something to point me in the right direction?
If you are using guide, you can access the other sliders from the handles variable that is available in each callback.
Set the Value property for them.
function Slider1_CallBack(hObj,evt,handles)
set(handles.Slider1,'Value',10);
set(handles.Slider2,'Value',10);
% etc..
end
In case you are using it programmaticaly, you can store the handles manually.
function main
handles.Figure1 = figure(..);
handles.Slider1 = uicontrol(...);
handles.Slider2 = uicontrol(...);
guidata(handles.Figure1,handles);
end
And your slider callback should be:
function Slider1_CallBack(hObj,evt)
handles = guidata(hObj);
set(handles.Slider1,'Value',10);
set(handles.Slider2,'Value',10);
% etc..
end
Edit A good practice in writing UI is separating the GUI logic from the actual data. You always change the data, and call updateGUI routine.
Therefore, you can write your program like this:
function main
handles.gui.Figure1 = figure(..);
handles.gui.Slider1 = uicontrol(...);
handles.gui.Slider2 = uicontrol(...);
handles.data.x = 1;
guidata(handles.Figure1,handles);
end
function UpdateGui(handles)
%Based on the data, update the GUI
set(handles.Slider1,'Value',handles.data.x);
set(handles.Slider2,'Value',handles.data.x+1);
end
And the callback should look like:
function Slider1_CallBack(hObj,evt)
handles = guidata(hObj);
handles.data.x = handles.data.x + 1;
UpdateGui(handles);
guidata(hObj,handles);
% etc..
end

Resources