SciLab checkbox UIControl value not changing with state? - matlab

I'm trying to design a GUI in SciLab that updates it's properties depending on a checkmark. For example: A checkbox might enable and change the backrounds of several text boxes during a callback; or a pushbutton may require a certain number of checkboxes to be selected.
My problem is that I can't seem to develop a flow control statement for running instructions depending on the checkboxes state during a callback. My current UIControl element looks like this:
handles.chkS11En=uicontrol(f,'unit','normalized','BackgroundColor',[0.8,0.8,0.8],'Enable','on','FontAngle','normal','FontName','helvetica','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[0,0,0],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.02140625,0.791119360625398,0.0803125,0.0369667],'Relief','flat','SliderStep',[0.01,0.1],'String','S11','Style','checkbox','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','chkS11En','Callback','chkS11En_callback(handles)')
And my callback that runs when I check the checkbox is this:
cS11En = findobj('tag', 'chkS11En'); // checkbox option
tS11MagUpperBound = findobj('tag', 'txtS11MagUpperBound'); //edit box that is controlled
mprintf("%d\n",cS11En.Value);
if cS11En.Value == [1] then
mprintf("Checked = on \n");
set(tS11MagUpperBound,'BackgroundColor',[1,1,1]);
set(tS11MagUpperBound,"Enable",'on');
set(cS11Save,"Enable",'on');
elseif cS11En.Value == [0] then
mprintf("Checked = off \n");
set(tS11MagUpperBound,'BackgroundColor',[0.8,0.8,0.8]);
set(tS11MagUpperBound,'Enable','off');
set(cS11Save,"Enable",'off');
end
The problem with this code seems to be that the second path (Value = 1) never seems to run, even when i continually toggle the checkbox. I get an output like so:
0
Checked = off
0
Checked = off
0
Checked = off
0
Checked = off
Is there something I'm doing wrong in order to reload checking the element? I want to be able to run both paths, however I can never seem to get a value of 1 from the checkbox element. Does anyone have a solution to this? Thanks!

IF anyone is wondering and finds this through the googles or something, this is how I fixed it:
It turns out that SciLab sometimes doesn't clear all UI variables when the form is closed and a script is running.
The solution is to add a few lines in the top of each of your program that clears all variables, closes all forms, and initializes your variables.
Basically, add this:
// /////////////
// Lemon Pledge
// /////////////
mprintf("\n!!!!!!!!!!!!!!!!!!!\nCLEARING ALL VARIABLES\n!!!!!!!!!!!!!!!!!!!\n")
xdel(winsid());
clear;
clearglobal;

Another less complex solution would be:
Using the same checkbox I left the last attribute in blank.
handles.chkS11En=uicontrol(f,'unit','normalized','BackgroundColor',[0.8,0.8,0.8],'Enable','on','FontAngle','normal','FontName','helvetica','FontSize',[12],'FontUnits','points','FontWeight','normal','ForegroundColor',[0,0,0],'HorizontalAlignment','center','ListboxTop',[],'Max',[1],'Min',[0],'Position',[0.02140625,0.791119360625398,0.0803125,0.0369667],'Relief','flat','SliderStep',[0.01,0.1],'String','S11','Style','checkbox','Value',[0],'VerticalAlignment','middle','Visible','on','Tag','chkS11En','Callback','')
Then I make the callback
function chkS11En_callback(handles)
if handles.chkS11En.Value == [1] then
mprintf("Checked = on \n");
set(tS11MagUpperBound,'BackgroundColor',[1,1,1]);
set(tS11MagUpperBound,"Enable",'on');
set(cS11Save,"Enable",'on');
else
mprintf("Checked = off \n");
set(tS11MagUpperBound,'BackgroundColor',[0.8,0.8,0.8]);
set(tS11MagUpperBound,'Enable','off');
set(cS11Save,"Enable",'off');
end
And voilĂ , no need to clear your workspace.

Related

unexpected frame appears onto another frame after an event

I'm using a character application. In the first page, there is a frame f-selection where the search fields are entered. When I search for something and open some other frames in that search, then I press F10 which is for opening another frame, the new frame opens but f-selection also appears on it. I'm suspecting this code makes it pop up again:
else assign ll-lgst-key1:SENSITIVE in frame f-selection = TRUE
ll-lgst-key2:SENSITIVE in frame f-selection = FALSE
because when I comment these lines, the frame doesn't pop up. But then I can't use these fields at the first frame where I should, too. I don't know why this code is called again; but is there anything else I can do to fix this issue? I tried to write hide frame f-selection everywhere possible but it doesn't work.
That snippet of code is making "key1" of your frame sensitive. In order to be sensitive it needs to pop up...
So the issue is why is that block of code executing? You say "I don't know why this code is called again". Neither will anyone else because you have shared such a tiny little bit of the overall code. Apparently the flow of control is taking you through that block so you should work on understanding why that is. You might try using the debugger to step through the code execution or you could insert some old fashioned MESSAGE statements to get to the bottom of it.
If you want to kludge around the problem you could wrap that bit of code in conditional logic. Define and set a variable that determines the desired state of the f-selection frame and use that to control the sensitivity logic:
define variable f-shouldBeVisible as logical no-undo.
if .... then
f-shouldBeVisible = yes.
else
f-shouldBeVisible = no.
...
else
do:
if f-shouldBeVisible then
assign ll-lgst-key1:SENSITIVE in frame f-selection = TRUE
ll-lgst-key2:SENSITIVE in frame f-selection = FALSE
.
end.
Of course that looks kind of silly -- but it is just an example with grossly over-simplified logic.
OTOH if you know enough to set the variable you ought to be able to figure out why the ELSE branch is executing. But maybe it is a useful first step.

How to deselect cells in uitable / how to disable cell selection highlighting?

I created the following uitable:
actually every single row is an indpendent uitable, so the figure shown contains 5 uitables besides the header. Why I'm doing that was the issue of my last question, resulting in the shown table. Fully executable code you can find in the answer here (or a minimal example below). Solutions using a general GUI are also there, but it would blow up the code too much, and actually it just seems to be a kind of bug.
It can be seen that everytime I jump to the next row, therefore to another uitable, the last selection remains highlighted, which looks stupid, though it doesn't matter for the functionality.
There is the 'SelectionHighlight' property for uitables, sounds like a solution, but it is not changing anything. I used it as following:
set(src,'SelectionHighlight','off') %where src is the handle of the current uitable
at various places: at the end of a 'CellSelectionCallback', at the end of a 'CellEditCallback' and as global property. But everytime the last cell remains selected. Actually I don't need selection at all.
How can I disable the whole selection or selection highlighting property for all my uitables?
How do I have to use this property, that it has an effect?
Alternatively: how can I change the "highlighting" color (and therefore text-color) so the highlighting is just not visible anymore?
Apparently this issue appears also in other contexts.
I created a minimum executable example, where one can select a number between 1 and 3 in every row.
function minimalTable
%basic properties
line_height = 21.32;
table_height = 3*line_height;
lh = line_height/table_height;
h = figure('Position',[200 100 202 table_height],'numbertitle','off','MenuBar','none');
% addrow(figurehandle,number of row, percentage lineheight)
% every function call creates a new row, later dynamically
addRow(h,1,lh);
addRow(h,2,lh);
addRow(h,3,lh);
end
function modifySelection(src,~)
set(src,'SelectionHighlight','off')
waitfor(src)
end
function [th] = addRow(fh,k,lhp)
selector = { '1'; '2' ; '3' };
defaultData = {'select number...'};
columnformat = { {selector{:}} };
columneditable = true;
th = uitable(fh,'Units','normalized','Position',[0 1-k*lhp 1 lhp],...
'Data', defaultData,...
'ColumnName', [],...
'ColumnWidth', {200},...
'ColumnEditable', columneditable,...
'ColumnFormat', columnformat,...
'RowName',[],...
'SelectionHighlight','off',...
'CellEditCallback',#modifySelection);
end
results in:
After some deeper research I found out, that the Matlab Support comes out with the following solution:
%overwrite data with a dummy and restore the old data afterwards, to force deselection
function modifySelection(src,~)
...
temp = get(src,'Data')
set(src,'Data',{ 'dummy' });
set(src,'Data', temp );
end
Doing this the blue highlighting is gone, BUT the dotted line around the last selected cell remains!
But I found a solution resolving this, which also makes the first part dispensable.
function modifySelection(src,evt)
...
fh = get(src,'parent'); % get parent figure handle
copyobj(src,fh); % copy uitable to parent figure
delete(src); % delete current uitable
end
Which results in the desired behaviour:
Drawback of the second solution: it lags a little (probably just on slow machines), because of the creation of a new object.
Allright, I found a solution for deselecting cells:
First of all, this requires some Java. But dont worry, it will still look like Matlab :)
1. You will need the script findjobj by Yair Altman: TMW File-Exchange: findjobj
2. You need the handle of your table, lets call it mtable. Then you need the underlying Java-table and do some stuff to get the right objects and set some properties. You can do this by:
jscroll=findjobj(mtable);
h=jscroll.getComponents;
viewport=h(1);
a=viewport.getComponents;
jtable=a(1); %com.mathworks.hg.peer.ui.UITablePeer
jtable.setRowSelectionAllowed(0);
jtable.setColumnSelectionAllowed(0);
3. Now the more tricky part (at least it was for me): If you have some Callback for CellSelectionChanged, but you dont want to excecute this now, you have to turn it off temporary:
set(mtable, 'CellSelectionCallback', []);
Now you can change the selection by:
jtable.changeSelection(row-1,col-1, false, false);
%Java-> zero ^= one <-Matlab
And now, I was expecting, when setting the CellSelectionCallback back to its original function, everything would be fine. Nope, it was excecuting the Callback. I still dont know the exact reason, but it seems to me, that calling jtable.changeSelection() the selection changes and then is calling the specified Callback, but the caller function is not waiting while this process is running. So what I tried (and I dont know if this is the best way to do it, but it is working very well) is to just pause for a second and then set the Callabck back:
pause(1)
set(mtable, 'CellSelectionCallback', #myOriginalFunction);
4. Now just one more thing: My purpose was just to change the selection to some other cell. Yours is to deselect. I dont know anything about the Java components, but I succeeded by just setting the row/column parameter to -1:
jtable.changeSelection(-1,-1, false, false);
Finally I managed to solve this problem by using many things explained on undocumentedmatlab.com and other posts. I am not sure if all the lines are necessary to call. Note, that this will only be available for the documented Matlab-uitable which appears first in Version 2008 (a or b, I'm not sure about that).
EDIT there are a lot of other functions/parameters etc. you can use, that are undocumented. Just to see what is possible, you can take a look with the autocomplete. Just use it on the jtable. and Tab will display them. For a documentation on those elements you should probably search for a Java-doc.
Just a small "dynamic" minimal example (wait 3 seconds to see a change ;-) ):
function startUitable()
xDat=ones(5,3);
h=figure('Tag','TestFigure');
mtable=uitable('Tag','TestUITABLE');
rowField=uicontrol('units','normalized','Style','edit','Position',[0.4 0.9 0.1 0.1],'parent',h,'Tag','rowField');
colField=uicontrol('units','normalized','Style','edit','Position',[0.6 0.9 0.1 0.1],'parent',h,'Tag','colField');
set(mtable, 'Units','normalized','Position',...
[0.01 0.01 0.8 0.8], 'Data', xDat,...
'ColumnEditable', [false, false,false],...
'ColumnWidth', 'auto')
myButton=uicontrol('units','normalized','Style','pushbutton','parent',h,'Position',[0.04 0.9 0.3 0.1],'String','change Selection')
set(myButton,'Callback',#changeSelection)
end
function changeSelection(~,~,~)
mtable=findobj('Tag','TestUITABLE');
jscroll=findjobj(mtable);
h=jscroll.getComponents;
viewport=h(1);
a=viewport.getComponents;
jtable=a(1); %com.mathworks.hg.peer.ui.UITablePeer
% jtable.setRowSelectionAllowed(0);
% jtable.setColumnSelectionAllowed(0);
row=str2num(get(findobj('Tag','rowField'),'String'));
col=str2num(get(findobj('Tag','colField'),'String'));
jtable.changeSelection(row-1,col-1, false, false);
end

Uitable, cellSelectionCallback and modifying dataset

My code is really too long to be posted here, even by little portions. So I will just ask for one or two things :
It appears to me that when modifying the 'Data' property of an uitable 'ht' :
set(ht, 'Data', something);
that the "cellSelectionCallback" routine is triggered (as the selection is very likely to have changed, indeed), but not immediatly after the dataset is modified.
Is this true ?
Is there any way to prevent such a behavoir ?
Thanks !
I have code using a uitable, e.g:
tbl = uitable('Parent', fh, 'CellSelectionCallback',{#cell_select_callback fh});
I did a quick experiment and when using set(tbl,'Data',my_data) the callback is triggered only if the set causes the selected cell(s) to change, and this happens immediately (as far as I can tell - I saw no appreciable delay).
To stop that happening you could just unset the CellSelectionCallback property, change the data, and then reset CellSelectionCallback.
I had the same issue. Was getting index out of bounds warnings. To get rid of those I used this in my CallSelectionCallback:
if ~isempty(eventdata.Indices)
// all the code
end
When the set command triggers the CallSelectionCallback the eventdata.Indices is empty.
A similar possibility to Sebastien's answer is to put this in your cellselectioncallback function:
function output = mycellselection(source,event)
if isempty(event.Indixes)
output = [];
return
end
% rest of your code for cell selection
end
If you don't have any output needed, you can just remove it. I just put it in there to remind you that you have to assign a value to any outputs.

Messagebox.show fires twice after button click (MVVM)

I am using Galasoft MVVMLight. I have a button bound to a command which sends a message to the view to display a messagebox asking for confirmation. If I click either the Yes or No on the messagebox it performs the necessary actions then shows up again. However if I step through the program instead I only get the messagebox once. Is this a bug or is something else going on?
EDIT: I modified the messagebox.show line by adding an Icon and default result and now I can't reproduce this behavior... I'm stumped... if it happens again I'll try a counter like airplaneman19 suggested.
Try tracking the amount of times the MessageBox shows up with an integer, like so:
int counter = 0;
if(counter == 0){
MessageBox.Show();
counter++;
}
else if (counter == 1)
/*Do something that won't alter the program just to escape the if....else statement
like "x++";
I had a similar problem once, I mean, with MessageBox firing twice. It was due to focus changes, and ListView in WinForms fired another selection changed event when running the app; but when debugging - some focus change was missing, and there was no bug :)
I hope this atleast gives you some ideas...

Scriptaculous Slider handle doesn't move when slider is above a multimap

I have a Scriptaculous Slider showing in a modal-dialog window above a Multimap. The problem that I'm having is that on this page the slider handle doesn't move if you try to drag it. If I click on the slider track, the handle correctly jumps to that point and you can then use the handle to drag correctly.
Clicking on the handle successfully registers the click as I can console.log() the value of the slider at that point. Trying to drag the slider around by it's handle just keeps logging that same value and the handle doesn't move.
The slider works correctly on any page that doesn't have the multimap on it.
There are no other JS frameworks on the pages (just Prototype and Scriptaculous).
I'm really not sure that the problem is though. If the slider wasn't registering anything then that would make sense that the map was ontop somehow or stealing the click event. But the clicks are obviously being recorded. I also don't understand why clicking on the slider track fixes the issue completely.
Can someone point me in the right direction (either with a fix, or a path to take to debug the issue myself).
Things I have tried:
Setting the z-index of the handle.
Making the modal-dialog visible to begin with (as it is hidden to start with - I thought it might be related to this issue, but it didn't help).
Found the problem.
Both the Scriptaculous Slider and Multimap were defining Array.prototype.indexOf but in different ways.
The solution (since I only wanted 1 handle on the slider) was to edit slider.js and change the calls to this.handles.indexOf.
Index: slider.js
===================================================================
--- slider.js (revision 1)
+++ slider.js (working copy)
## -219,14 +219,14 ##
this.offsetY = (pointer[1] - offsets[1]);
} else {
// find the handle (prevents issues with Safari)
- while((this.handles.indexOf(handle) == -1) && handle.parentNode)
+ while((this.handles[0] != handle) && handle.parentNode)
handle = handle.parentNode;
-
- if (this.handles.indexOf(handle)!=-1) {
+
+ if (this.handles[0] == handle) {
this.activeHandle = handle;
- this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+ this.activeHandleIdx = 0;
this.updateStyles();
-
+
var offsets = Position.cumulativeOffset(this.activeHandle);
this.offsetX = (pointer[0] - offsets[0]);
this.offsetY = (pointer[1] - offsets[1]);
Note to anyone using this fix: While this fix will make it so that the Scriptaculous Slider and Multimaps can work together on the same page, it will make it so that only 1 handle on the slider works. I have not tested what happens if you try to use this with 2 or more handles.