I am working on the Keil uv4 IDE with an ARM Cortex-M3 in a bare metal C application. I have a GUI that I created that is currently in English, but I would like to give the user the ability to go between other languages like you can on a cell phone.
I have created a structure with all the words that are used called string_table_t.
struct string_table_t
{
char *word1;
char *word2;
char *word3;
};
My thought process was to have plain text files for the different languages and the list of words used contained in each one. Then I would do a load function that would link the pointers of the string table with the actual word.
Now, my initial menu is created statically by defining it like so. It is based off of Altium software platform.
// Test structure
struct string_table_t string_table = {"Main Menu","test1","test2"};
form_t mainmenu_form =
{
.obj.x = 0,
.obj.y = 0,
.obj.width = 240,
.obj.height = 320,
.obj.draw = form_draw,
.obj.handler = mainmenu_form_handler,
.obj.parent = NULL,
.obj.agui_index = 0,
.obj.visible = __TRUE,
.obj.enabled = __TRUE,
.caption.x = 0,
.caption.y = 0,
.caption.text = "Main Menu",
.caption.font = &helveticaneueltstdltext18_2BPP,
.caption.color = RGB(230,230,230),
.caption_line_color = RGB(241,101,33),
.caption.fontstyle = FS_NONE,
.caption.align = ALIGN_CENTRE,
.captionbarcolor = RGB(88,89,91),
.children = mainmenu_children,
.n_children = 4,
.relief = RELIEF_NONE,
.color = RGB(65,64,66),
};
What I want to do is replace the "Main Menu" of the caption.text with string_table.word1. Therefore, if I load a different language set, the menu will automatically be pointing to the correct char array. Doing this currently results in a error expression must have a constant value.
Now, I can get this to work by leaving the text null in the menu component and adding:
Link_pointer_to_menu() {
mainmenu_form.caption.text = string_table.Main_menu_text;
}
This will compile and work, but I would rather not have to have 100 or so of these statements. Is there a more optimal way of doing this?
I would recommend something like that:
enum MyWords
{
msgHello,
msgOpen,
msgClose,
msgMainMenu,
num_Messages,
};
char *string_table_t[num_Messages];
You should write code that loads your language file and assigns pointers in this array. After that in your code:
.caption.text = string_table_t[msgMainMenu];
The idea is that you give each string a symbolic name that is an offset in the table of strings. After that you use this offset as an index into the table.
Related
I am trying to create a moodle-STACK question with an interactive element via jsxgraph.
Within the [[jsxgraph]] ... [[/jsxgraph]] tags, I am plotting a curve with two databases, each with 6 elements.
Since I would like students to add error bars for both scales, I added a loop within the jsxgraph-element:
var plot = function() {
var j, xr0, yr0, xr1, yr1, xr2, yr2, err1, err2;
board.suspendUpdate();
for (j=0; j<6;j++) {
const v1 = Number(input1.Value());
const v2 = Number(input2.Value());
xr1 = dataX[j]-v1;
yr1 = dataY[j]+v2;
xr2 = dataX[j]+v1;
yr2 = dataY[j]-v2;
xr0 = dataX[j];
yr0 = dataY[j];
err1 = board.create('line',[[xr1,yr0],[xr2,yr0]],{straightFirst:false,straightLast:false, fixed:true});
err2 = board.create('line', [[xr0,yr1],[xr0,yr2]],{straightFirst:false,straightLast:false, fixed:true});
}
};
Since the jsxgraph code is within the HTML-text field of the STACK-question in moodle, the < sign is converted to < and now the loop cant be executed.
Is there a way to use a < sign within the HTML-field of moodle? If not, how can I get past this problem?
I already wrote a running Javascript-Code that shows what I want to create within moodle:
https://jsfiddle.net/Furfinator/3q8yk7hp/15/
I use AppDesigner inMATLAB to show photos with changed RGB. But there is the problem with character of the photo.
When I switch on my own fuction "changeRGB", finally "choosenImage" has 20bytes, class "char" and size(1x10). OK!
There is no problem in using the "function OpenButtonValueChanged". OK!
There is the problem with "function UploadButtonPushed". OK!
ABOUT THE PROBLEM:
When I click button which callback is "function UploadButtonPushed" I get the error:
"Error using imread>parse_inputs (line 502)
The file name or URL argument must be a character
vector or string scalar."
"Error in imread (line 342)
[source, fmt_s, extraArgs, was_cached_fmt_used] =
parse_inputs(cached_fmt, varargin{:});"
WHY?
Because in the "function UploadButtonPushed" my choosenImage has 1977624bytes, class "uint8" and size(681x968x3). So it's too bug for "imread".
WHAT I TRIED:
When in "function OpenButtonValueChanged" I convert a photo, adding "char": (myimage = char(app.clickedImage)); the class of the photo is changing from uint8 to char but the size.
When I use "num2cell", the claas of the photo is changing on "cell" but size and number of bytes are the same- so big. And I get the Error: "Error using imread>parse_inputs (line 502) The file name or URL argument must be a character vector or string scalar."
In my own function "changeRGB" I used "imread(image)" and here is the problem with the size of the photo. Do you know how to get the correct one?
%my own properties in AppDesigner- to use them in different functions
properties (Access = public)
clickedImage;
addR = 1;
addG = 1;
addB = 1;
end
%first function in AppDeesigner
function OpenButtonValueChanged(app, event)
value = app.OpenButton.Value;
[file, howManyFiles] = chooseImagesFromComputer; %myown function
%I load 3 images which are showed as miniatures
myFile1 = imread(file{1});
imshow(myFile1, 'Parent', app.UIAxes1_1);
myFile2 = imread(file{2});
imshow(myFile2, 'Parent', app.UIAxes1_2);
myFile3 = imread(file{3});
imshow(myFile3, 'Parent', app.UIAxes1_3);
%take values of changed RGB from the slider
app.addR = app.SliderR.Value
app.addG = app.SliderG.Value
app.addB = app.SliderB.Value
%work only on one image to change its colors. app.clickedImage, app.addR, app.addG, app.addB are properties at the beginning of the code
app.clickedImage = file{1};
app.clickedImage = changeRGB(app.clickedImage,app.addR,app.addG,app.addB); %changeRGB- my own function- here is the problem. I add it bottom
imshow(app.clickedImage,'Parent',app.UIAxesMain);
end
%second function in AppDesigner
%here is the button to upload color of the photo
function UploadButtonPushed(app, event)
myimage = app.clickedImage;
myimage = changeRGB(myimage,app.addR,app.addG,app.addB);
imshow(myimage);
end
%here is my own function in matlab, not in AppDesigner, which makes problem:
function [changedImage] = changeRGB(choosenImage, addR, addG, addB)
whos
loadedImage = imread(choosenImage);
R = loadedImage(:,:,1); %extract one of the color channels
G = loadedImage(:,:,2);
B = loadedImage(:,:,3);
RBG = cat(3,R,G,B);
R_adj2 = R + addR;
G_adj2 = G + addG;
B_adj2 = B + addB;
changedImage = cat(3,R_adj2,G_adj2,B_adj2);
end
First, you make unnecessary operations in changeRGB
function [changedImage] = changeRGB(choosenImage, addR, addG, addB)
loadedImage = imread(choosenImage);
loadedImage = bsxfun(#sum, loadedImage, reshape([addR, addG, addB], [1 1 3]);
end
Then this function return an array (the modified image) so in UploadButtonPushed(app, event) when you run myimage = app.clickedImage;, you are passing the modified array instead of the image path, that you set here app.clickedImage = changeRGB(app.clickedImage,app.addR,app.addG,app.addB);
So you have to change the design of your variables, because app.clickedImage is saving either the image path, or the image itself. Consider having 2 different variables.
A good advice also is to use matlab debugger which is really good help to find the source of this kind of problems.
I am trying to create an array of structures in Simulink and got some problems with it.
first of all i tried to create it directly in Simulink using this:
function a = fcn(Dibhole, t , x, const)
%#codegen
%Output = zeros(10,10);
f1 = 'number';
f2 = 'move';
cube = struct(f1, 0, f2, 0);
a = repmat(cube, 20, 10);
for i = 1:20
for j = 1:10
a(i,j).number = 0;
a(i,j).move = 0;
end
end
and i got this error:
Derived output was of type struct. 'Inherited type' is unsupported for this
type and a defined bus object must be used instead. Click on 'a' and
set data type for 'a' to be 'Bus: ', where '' is
the name of a bus object from the MATLAB workspace.
So i found some example how to create struct in Matlab and receive this to Simulink: http://blogs.mathworks.com/seth/2011/12/05/initializing-buses-using-a-matlab-structure/
That works perfectly but i still can't repeat this with array:
f1 = 'number';
f2 = 'move';
cube = struct(f1, 0, f2, 0);
myStruct2 = repmat(cube, 20, 10);
for i = 1:20
for j = 1:10
myStruct2(i,j).number = 1;
myStruct2(i,j).move = 1;
end
end
busInfo = Simulink.Bus.createObject(myStruct2);
Can anyone clarify to me what's the problem? Or maybe there is different way to create array of struct in Simulink?
Mihail
Simulink wants you to define the output of the function to be a bus.
As 'Bus: My_test_bus', for example.
Take a look at the Simulink Bus Editor. You can find it in any model under the menu, Edit->Bus Editor.
This would be a good start.
Rick, i think you are right!
i have tried this problem for a long time, and have got this results:
the irony is that I was never able to create array of structures BUT i did this with structure of arrays! :D
I made this steps for it:
to use structure of arrays we need to define and initialize it in some MATLAB function. Like this:
number = zeros(10,1);
move = zeros(10,1);
for i = 1:10
number(i,1) = i+1;
move(i,1) = i+2;
end
a = struct('numbers',number,'movement', move);
To work this data we must use Bus Selector.
So we have array in "numbers" and "movement".
BUT! Here we go, Rick: we must define type of output of MATLAB function like Bus! How to do this in simulink? i found this way:
in model properties in simulink Callbacks/PreLoadFcn define some function and in same folder as project create .m file named like this just defined function.
In this file create structure of array and define Bus type for it:
number = zeros(10,1);
move = zeros(10,1);
a = struct('numbers',number,'movement', move);
busInfo = Simulink.Bus.createObject(a);
Now we have Bus type for our structure at first loading of simulink model.
Last step: define MATLAB function output type directly.
in Model Explorer choose your MATLAB function. choose output variable. Set DataType for it: Bus:slBus1 (the name of this Bus type you can see in wokspace of matlab, because its a global variable).
That's all! now it works!
(tried to add pictures, but i have no enough reputation :( )
Now my program works in this way, but i also tried to create array of structures and still have the problems. i tried to create Bus for it, but can't transmit it to Bus Selector - it doesn't know what to do with structures... i also tried to add one more MATLAB function to create some data from structures and then display it, but it doesn't works too(
I am new to Visual Basic and have a homework assignment as follows:
"You are to create an array of 10 elements, String type, and load 10 unique values into the array, one value per element. Your program must then output those values into a Listbox control.
Note: Your program MUST use a loop to load the data into the array(Hint: use InputBox function), and another loop to output it to the Listbox control. How your program acquires the information is up to you, but processing must be done using loops."
I am confused about how to enter the data that I want (arrayvalue(0) - arrayvalue(9)) via loop to a listbox.
I started with:
Dim n as integer = 10
Dim fruitarray(n) as string
Do Until fruitarray(n)=10
fruitarray(0) = "watermelon"
fruitarray(1) = "apple"
fruitarray(2) = "pear"
fruitarray(3) = "plum"
fruitarray(4) = "pineapple"
fruitarray(5) = "grapes"
fruitarray(6) = "strawberry"
fruitarray(7) = "raspberry"
fruitarray(8) = "banana"
fruitarray(9) = "blackberry"
ListBox1.Items.Add(CStr(n))
Loop
Thanks in advance!
You are doing all the things in one loop and without using InputBox as per requirement.
so here is your solution.
int n = 10;
string[] fruitarray = new string[n]
Dim message, title As String
message = "Enter your value"
title = "InputBox Demo"
for(int i=0;i<10;i++)
{
fruitarray[i]=InputBox(message, title, defaultValue)
}
for(int i=0;i<10;i++)
{
ListBox1.Items.Add(fruitarray[i]);
}
How would I save a picture within any file (and not overwrite the existing data in it) and then be able to access it later? (for example, if it was the picture at the index of 0, you would access it by specifying 0 later, or hopefully something like that)
Use method:
bool QPixmap::save ( "fileName", const char * format = 0, int quality = -1 ) const