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

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

Related

How do I make a script affect all its children in Roblox LUA?

I'm new to programming in LUA, although I've learned similar languages like JS. It's frustrating if I have to alter the same script in many parts in a group by replacing each script, and I don't know of an elegant way to do it. Instead, I decided to nest all the parts inside of the script. I've seen some examples and I've tried to adapt some of them, but they don't exactly apply to what I want to do and I can't get them to work.
In essence, what I'm trying to do is monitor all the bricks for a player to contact them. I took the original disappearing brick script that was nested inside each brick and modified it. If a part (brick) is touched, that should call the onTouch function, which will make the brick's transparency decrease over time until the in pairs loop is done, after which the brick disappears and CanCollide is turned off. After 2 seconds, it then returns back to normal. I think the problem is with the coding I used to monitor the parts as I don't really understand the right way to monitor multiple objects. Can someone please help? Thanks!
File structure:
function onTouched(brick)
local delay = .1 -- the delay between each increase in transparency (affects speed of disappearance)
local RestoreDelay = 2 -- delay before the brick reappears
local inc = .1 -- how much the brick disappears each time
-- All characters have a Humanoid object
-- if the model has one, it is a character
local h = script.Child:findFirstChild("Humanoid") -- Find Humanoids in whatever touched this
if (h ~=nil) then -- If there is a Humanoid then
h.Health = h.MaxHealth -- Set the health to maximum (full healing)
for x=0,1, inc do
script.Child.Transparency = x+inc
script.Child.CanCollide = true
wait(delay)
end
wait(delay)
script.Child.Transparency = 1
script.Child.CanCollide = false
wait(RestoreDelay)
script.Child.Transparency = 0
script.Child.CanCollide = true
else
end
end
while true do
local bricks=script:GetChildren():IsA("basic.part")
for x=1,brick in pairs(bricks) do
brick.Touched:connect(onTouched(brick)) -- Make it call onTouched when touched
end
end
end
For the most part, you've gotten it right, but you've got a few syntax errors where there are different conventions between JavaScript and Lua.
In JS, you would fetch an array of objects and then bee able to filter it immediately, but in Lua, there is limited support for that. So a JavaScript line like :
var bricks = script.GetChildren().filter(function(item) {
return item === "basic.part"
})
cannot be done all in one line in Lua without assistance from some library. So you'll need to move the check into the loop as you iterate over the objects.
Other than that, the only other thing to change is the onTouched handler's function signature. The BasePart.Touched event tells you which object has touched the brick, not the brick itself. But by creating a higher order function, it's easy to get access to the brick, and the thing that touched it.
-- create a helper function to access the brick and the thing that touched it
function createOnTouched(brick)
-- keep track whether the animation is running
local isFading = false
return function(otherPart)
-- do not do the animation again if it has already started
if isFading then
return
end
local delay = .1 -- the delay between each increase in transparency (affects speed of disappearance)
local restoreDelay = 2 -- delay before the brick reappears
local inc = .1 -- how much the brick disappears each time
-- All characters have a Humanoid object, check for one
local h = otherPart.Parent:FindFirstChild("Humanoid")
if h then
-- heal the player
h.Health = h.MaxHealth
-- start fading the brick
isFading = true
brick.CanCollide = true
for i = 0, 1, inc do
brick.Transparency = i
wait(delay)
end
-- turn off collision for the brick
wait(delay)
brick.Transparency = 1
brick.Anchored = true
brick.CanCollide = false
-- turn the part back on
wait(restoreDelay)
brick.Transparency = 0
brick.CanCollide = true
-- reset the animation flag
isFading = false
end
end
end
-- loop over the children and connect touch events
local bricks = script:GetChildren()
for i, brick in ipairs(bricks) do
if brick:IsA("BasePart") then
local onTouchedFunc = createOnTouched(brick)
brick.Touched:Connect(onTouchedFunc)
end
end

How can i change the character image non Ruby Gosu

im building a basic game in the style of the original pokemon games using the ruby gosu library. Ive managed to figure out how to move the originally loaded sprite about but i cant figure out how to clear that sprite and draw the new sprite e.g. back view in its place.
Ive been looking throught the documentation and came across the "insert" method, although im not sure if this is what i want. Any help?
im creating the var in the initialize method then drawing it later on like so:
def initialize
#character_image = Gosu::Image.new("media/images/char.png", :tileable => false)
end
def draw
#character_image.draw(#character_location_X, #character_location_Y, 1)
end
You need to make a class for your character, which needs an update and draw function. In the update function, when input such as WASD is received you can switch the image of the sprite. If you don't have a sprite sheet, you'll have to load multiple images and switch between them.
Here's some ruby pseudocode to help you:
#back_image = Gosu::Image.new("media/images/back.png")
#front_image = Gosu::Image.new("media/images/front.png")
#left_image = Gosu::Image.new("media/images/left.png")
#right_image = Gosu::Image.new("media/images/right.png")
current_image = front_image
This goes in your update function:
if up
current_image = back_image
elsif down
current_image = front_image
elsif right
current_image = right_image
elsif left
current_image = left_image
end
Then in your draw function all you need to do is
def draw
#current_image.draw(#character_location_X, #character_location_Y, 1)
end
This is a pretty basic way, but if you use a sprite sheet, you can create your own animation class that Gosu can use that allows you to select between certain ranges of frames of your character spritesheet.

How to create a walking animation in LOVE 2D

So I was wondering how to change an image of character I've created depending on the key I've pressed/am pressing?
My ultimate going to to have a walking animation occuring when "d" (or any of the wasd keys) is pressed but then he stands still when the "d" key has just been pressed etc. All images have been created already.
I've tried this but it didn't work out:
function love.load()
if love.keyboard.isDown("a") then
hero = love.graphics.newImage("/hero/11.png")
elseif love.keyboard.isDown("d") then
hero = love.graphics.newImage("/hero/5.png")
elseif love.keyboard.isDown("s") then
hero = love.graphics.newImage("/hero/fstand.png")
elseif love.keyboard.isDown("w") then
hero = love.graphics.newImage("/hero/1.png")
end
function love.draw()
love.graphics.draw(background)
love.graphics.draw(hero, x, y)
end
You must understand how LÖVE works. It (very basically) does this:
love.load() -- invoke love.load just once, at the beginning
while true do -- loop that repeats the following "forever" (until game ends)
love.update(dt) -- call love.update()
love.draw() -- call love.draw()
end
This schema is so frequent that the loop itself has a name - it's called The Game Loop.
Your code does't work because you are using love.load() as if it was part of the game loop, but it isn't. It's called at the beginning, during the first millisecond or so of your program, and never again.
You want to use love.load do load the images, and love.update to change them:
function love.load()
heroLeft = love.graphics.newImage("/hero/11.png")
heroRight = love.graphics.newImage("/hero/5.png")
heroDown = love.graphics.newImage("/hero/fstand.png")
heroUp = love.graphics.newImage("/hero/1.png")
hero = heroLeft -- the player starts looking to the left
end
function love.update(dt)
if love.keyboard.isDown("a") then
hero = heroLeft
elseif love.keyboard.isDown("d") then
hero = heroRight
elseif love.keyboard.isDown("s") then
hero = heroDown
elseif love.keyboard.isDown("w") then
hero = heroUp
end
end
function love.draw()
love.graphics.draw(background)
love.graphics.draw(hero, x, y)
end
The code above has certain repetitiveness that can be factored out using tables, but I've left it simple on purpose.
You will also notice that I have included the dt parameter in the love.update function. This is important, since you will need it to make sure that animations work the same in all computers (the speed at which love.update is called depends on each computer, and dt allows you to cope with that)
Nevertheless, if you want to do animations, you will probably want to use this Animation Lib or my own.

MATLAB: Modify getline() to remove 'end input on double-click' functionality

The matlab function getline (image processing toolbox) returns the position of a polyline (which has previously been defined with the cursor) either on a double-click or on pressing the return key or spacebar.
Due to my butter-fingers and accidentally double-clicking I want to remove the ability to end on a double-click.
What part do I need to change, or what functions should I be looking out for, I can't find out how a double click is even defined in matlab.
Cheers!
MATLAB associates "callback" functions with graphics objects, which define what to do when the mouse is clicked, keys are pressed, etc.. In getline(), the section to look at is the NextButtonDown() subfunction. This is the callback that is associated with subsequent mouse presses after the first mouse press to initiate the line. The key is that is checks the SelectionType figure property, which will be open for a double click. When that is the case, it closes the figure. So, to disable that functionality, just remove the extra case and checking logic. Here is the diff for my r2009b version:
306,310d305
< selectionType = get(GETLINE_FIG, 'SelectionType');
< if (~strcmp(selectionType, 'open'))
< % We don't want to add a point on the second click
< % of a double-click
<
322,328d316
<
< end
<
< if (~strcmp(get(GETLINE_FIG, 'SelectionType'), 'normal'))
< % We're done!
< set(GETLINE_H1, 'UserData', 'Completed');
< end
The answer provided by #JohnColby solves your problem by editing the GETLINE.m function file. Basically you comment out every line that check if a double-click was performed. This information is obtained by querying the 'SelectionType' figure property.
Alternatively, if you are like me and you hate making changes to built-in functions, then consider the following solution that doesn't involve changing any existing functions. Here is an example of how we use it:
h = addlistener(handle(gcf), 'WindowButtonDownFcn', 'PostSet', #changedWBDFcn);
[x,y] = getline();
delete(h)
plot(x,y, 'Color','r')
The idea is to create an event listener that gets triggered when the 'WindowButtonDownFcn' figure property changes. We use it to insert a function that gets called just before the previously set callback function (actually we replace the callback with our own function that calls the old one at the end).
This allows us to insert a section that checks if the call was triggered by a double-click, and simply skip such event.
This had to be done twice, because GETLINE first calls FirstButtonDown on first click, which sets NextButtonDown to be called on subsequent clicks, thus the use of the flag variable to differentiate between the two cases.
The code for the above event listener function:
function changedWBDFcn(src,ev,flag)
hFig = ev.AffectedObject; %# figure handle
currFcn = ev.NewValue; %# current callback function
delete(src); %# delete event listener
if nargin < 3, flag = false; end %# determine flag
%# hijack WindowButtonDownFcn function
set(hFig, 'WindowButtonDownFcn',{#wbdFcn,currFcn,flag})
%# callback function
function wbdFcn(o,e,currFcn,flag)
%# skip anything but single-clicks
if ~strcmpi(get(hFig,'SelectionType'),'normal')
return
end
%# evaluate previous callback function
hgfeval(currFcn) %# getline('FirstButtonDown'),getline('NextButtonDown')
%# repeat process after first click
if flag
addlistener(handle(hFig), 'WindowButtonDownFcn', ...
'PostSet', {#changedWBDFcn,true});
end
end
end

Smooth transition (optical effect) between uitabpanels in Matlab

I have designed a group of three uitabpanels objects.
htab = uitabgroup('v0');
th1 = uitab('v0',htab,'title','Panel 1','ButtonDownFcn',...
#th1_ButtonDownFcn);
th2 = uitab('v0',htab,'title','Panel 2','ButtonDownFcn',...
#th2_ButtonDownFcn);
th3 = uitab('v0',htab,'title','Panel 3','ButtonDownFcn',...
#th3_ButtonDownFcn);
My intention is having a smooth transition between them when I change the selected uipanel through the mouse click. I pretend to achieve it changing the 'Visible' property of the elements contained inside them using the ButtonDownFcn function ( I got this idea based on the description section of this page).
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','off');
...
function th1_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','on');
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','off');
guidata(fh,handles);
end
function th2_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','off');
set(handles.th2,'Visible','on');
set(handles.th3,'Visible','off');
guidata(fh,handles);
end
function th3_ButtonDownFcn(hObject, eventdata)
handles = guidata(fh);
set(handles.th1,'Visible','off');
set(handles.th2,'Visible','off');
set(handles.th3,'Visible','on');
guidata(fh,handles);
end
where
fh: handle of the figure where they are contained the uitabpanels.
handles.th1, handles.th2, handles.th3: handles of the elements contained into each uitabpanel respectively.
However, it has not worked (I click on each one of uitabpanel's tabs and the visibility of them do not change) and I do not understand why.
In conclusion, the ButtonDownFcn and SelectionChangeFcn functions of an UITAB are already active when you click in the tab´s label. So it is not possible to achieve the desired target (smooth optical transition) because the obtained result (modifying the mentioned functions) is the same that doing nothing.

Resources