How to extend adding functionality of two objects in Dart? - flutter

I am using as a Latex renderer in my flutter project. I want to add a latex value to an existing Catex object. I have a List of Strings which hold latex values and a listview to display them in order. I want to add a list item to the Catex every time an OnTap method is called.
so far, + operator is not supported
The operator '+' isn't defined for the type 'CaTeX'.
CaTeX catex = r'\mu =: \sqrt{x}' as CaTeX;
int value = 0;
...
List<String> get data => [
r'\mu =: \sqrt{x}',
r'\eta = 7^\frac{4}{2}',
r'\epsilon = \frac 2 {3 + 2}',
r'x_{initial} = \frac {20x} {\frac{15}{3}}',
// ignore: no_adjacent_strings_in_list
r'\colorbox{red}{bunt} \boxed{ '
r'\rm{\sf{\bf{'
r'\textcolor{red} s \textcolor{pink} i \textcolor{purple}m '
r'\textcolor{blue}p \textcolor{cyan} l \textcolor{teal} e} '
r'\textcolor{lime}c \textcolor{yellow}l \textcolor{amber} u '
r'\textcolor{orange} b}}}',
r'\TeX',
r'\LaTeX',
r'\KaTeX',
r'\CaTeX',
'x_i=a^n',
r'\hat{y} = H y',
r'12^{\frac{\frac{2}{7}}{1}}',
r'\varepsilon = \frac{\frac{2}{1}}{3}',
r'\alpha\beta\gamma\delta',
// ignore: no_adjacent_strings_in_list
r'\colorbox{black}{\textcolor{white} {black} } \colorbox{white} '
r'{\textcolor{black} {white} }',
r'\alpha\ \beta\ \ \gamma\ \ \ \delta',
r'\epsilon = \frac{2}{3 + 2}',
r'\tt {type} \textcolor{teal}{\rm{\tt {writer} }}',
'l = a * t * e * x',
r'\rm\tt{sp a c i n\ \bf\it g}',
r'5 = 1 \cdot 5',
'{2 + 3}+{3 +4 }=12',
r'\backslash \leftarrow \uparrow \rightarrow \$',
r'42\uparrow 99\Uparrow\ \ 19\downarrow 1\Downarrow',
'5x = 25',
r'10\cdot10 = 100',
'a := 96',
];
...
changeListItems(int val) {
setState(() {
this.value = val;
if (this.value != 0) {
catex += data[this.value];
}
});
}
...
body: ListView.builder(
itemCount: this.value,
itemBuilder: (context, index) {
return Column(children: [catex]);
}),
...
onTap: (int index) {
index == 0
? this.value = this.value - 1
: this.value = this.value + 1;
changeListItems(this.value);
}

You can override the + operator for the Catex class with an extension:
extension Sum on Catex{
Catex operator +(Catex other) {
return Catex(this.input + other.input);
}
}
This is not very reliable since it depends on the input property of the Catex Package. Also, you are storing a constant Widget in your class which is also not recommended.
Widgets are meant to be created during the Build process so the Flutter framework can work on it properly.
The correct way to do it would be to have in your state a String which contains the input that will be passed to the Catex:
String catexInput = r'\mu =: \sqrt{x}';
[...]
catexInput += data[this.value];
[...]
return Catex(catexInput);
Edit:
If you want to have a Column with multiple Catex Widgets, you can do the same thing except that your state will need to contain a list of Strings:
List<String> catexInputs = [r'\mu =: \sqrt{x}'];
[...]
catexInput.add(data[this.value]);
[...]
return Column(children: [for (String input in catexInput) Catex(input)]);;

Related

How to keep the current option in group button flutter

I was used group_button package from flutter to make user can select many options. After upgrading the library to version 5.0.0 or above, the selectedButtons property has been deprecated. I was save options of user by it but no I can't use it now. I was use it as:
GroupButton(
selectedButtons: setSelectedBtn(index),
isRadio: false,
spacing: 10,
onSelected: (i, isSelected) =>
onFilterSelect(index, i, isSelected),
buttons: widget.filters[index].value
.map((e) => e.value)
.toList())),
setSelectedBtn(index) {
List<int> result = [];
var valueSet = widget.filters[index].value;
bool isSelected = valueSet
.firstWhere((element) => element.isSelected,
orElse: () => CategoryFilterValues("", false))
.isSelected;
if (!isSelected) {
return result;
}
for (int index = 0; index < valueSet.length; index++) {
if (valueSet.elementAt(index).isSelected) {
result.add(index);
}
}
return result;
}
group_button
How I can save the options now in new version? Anyone can help me to do it.
thank you
Use GroupButtonController.
Controller have list of methods to interact with options.
selectIndex(int i) - Select button by index in radio type
unselectIndex(int i) - Unselect button by index in checkbox and radio type
... etc.
More docs and examples you can find here

flutter dropdown menu string puşş and take double

i prepare a dropdown menu with 2 or more items
İ want to take the double value and use it in a calculation
My entries are Aluminium 2.75 ----Steel 7.85 etc.
I define
String density_choose = "Steel 7.25";
DropdownButton<String>(
value: density_choose,
items: density.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text("malzeme:$value"),
);
}).toList(),
icon: Icon(Icons.arrow_drop_down),
onChanged: (var secilenVeri) {
setState(() {
density_choose = secilenVeri!;
});
},
),
My calculation
double sum = int.parse(kenar.text) *
int.parse(kenar.text) *
int.parse(yukseklik.text) *
int.parse(yukseklik.text) *double.parse(density_choose.split(" ")[2])/
1000000;
output = sum.toString();
I dont have any problem in syntax but I cant take the double
I think I found the issue. It's coming from this density_choose.split(" ")[2].
You should be getting the 1 not the [2].
density_choose.split(" ")[1]
Since:
density_choose = 'Steel 7.25';
Then:
density_choose.split(" ") = ['Steel', '7.25']
density_choose.split(" ")[0] = 'Steel';
density_choose.split(" ")[1] = '7.25';

Getting undefined when selecting html element in Javascript

I have a number of tv display clones loaded onto my page. After the clone is made, it will create a new TV object at the end of the loop definition, but for some reason, when it tries to access the index based canvas element from the page, it returns undefined. I tested that when hardcoding cnvs[0] from inside the constructor, it will return the canvas element. Indexing cnvs1 will return undefined; however, I see the tv has already been cloned before this line is executed. Shouldn't there then be a second canvas element of class ".static" that can be selected? In addition to the code, I attached a screenshot of my debugger screen in Chrome to see what the scope reads following "this.cnv = cnvs1", which should dynamically be cnvs[this.index]. Thanks in advance!
const container = document.getElementsByTagName("main")[0];
const template = document.getElementsByClassName("tv-set")
const cnvs = $(".static");
/**TBD**/
class TV {
constructor (id = "tv-0", name = "Blank Slate") {
this.id = id;
this.name = name;
console.log("NEW TV CREATED: ", this);
console.log("ID: ", this.id);
this.gifArr = gifCarousel_dict[this.name];
console.log("Media selection for this tv: ", this.gifArr);
// this.cnv = $(this.id).find('.static')[0];
// this.cnv = document.querySelector("[data-name=" + CSS.escape(this.id) + "]");
this.index = getSecondPart(id);
// this.cnv = $(".static")[this.index + 1];
this.cnv = cnvs[1];
console.log(this.cnv);
this.cnv.setAttribute("c", this.cnv.getContext("2d"));
this.cnv.setAttribute("cw", this.cnv.offsetWidth);
this.cnv.setAttribute("ch", this.cnv.offsetHeight);
this.staticScrn = this.cnv.getAttribute("c").createImageData(this.cnv.setAttribute("ch"), this.cnv.setAttribute("cw"));
console.log("This canvas element: ", this.cnv);
//Static display
this.isStatic = true;
}
showStatic() {
console.log(`Printing the tv name from the prototype fxn: ${this.name}`);
// this.isStatic = true;
c.clearRect(0, 0, cw, ch);
for (var i = 0; i < staticScrn.data.length; i += 4) {
let shade = 127 + Math.round(Math.random() * 128);
staticScrn.data[0 + i] = shade;
staticScrn.data[1 + i] = shade;
staticScrn.data[2 + i] = shade;
staticScrn.data[3 + i] = 255;
}
c.putImageData(staticScrn, 0, 0);
staticTO = setTimeout(runStatic, 1e3 / staticFPS);
}
}
for (let i = 0; i < phases.length; i++) {
const clone = template[i].cloneNode(true);
clone.setAttribute("id", "tv-" + (i + 1))
console.log("clone id: ", clone.getAttribute("id"))
clone.setAttribute("data-channel", 0)
clone.setAttribute("name", phases[i])
// clone.style.backgroundColor = phases[i].channels[0]
container.appendChild(clone)
var tvName = 'tvPhase' + clone.getAttribute("name");
//Instantiate TV object
window['tvPhase' + clone.getAttribute("name")] = new TV(clone.getAttribute("id"), clone.getAttribute("name"));
console.log("New Tv Created: ", tvName)
}
As I was about to post this question, I caught my bug...but I figured perhaps someone could learn from my stupid mistake! Turns out, it was because of line const cnvs = $(".static"); Setting this constant prior to the cloning operation means it will contain only the first canvas element and cannot be changed even after clones are created since it's a constant (face palm). The solution, of course, is to just define this.cnv = $(".static")[this.index]; directly or set the global cnvs as a var/let cnvs, still wrapping my head around when to use which.

taking items from map in flutter

I am tring to use a map to get words from a string and map them to a widget.
I have tried this but my problem is the key for the words doe and sister get the same keys so i end up getting only one of them
String theText = "my name is doe from http.doe.com, my sister is selly. doe and saqil are not sister friends of koiter.";
wordsMap = Map.fromIterable(text.split(' '),
key: (v) => v,
value: (v) => TextSpan(text: v));
so I tried the code below
Map mapMyWord = {};
// var wordsMap;
var splitForSize = text.split(' ').toList();
for(var t = 0;t<= splitForSize.length-1;t++){
mapMyWord[t] = {'$t':TextSpan(text: splitForSize[t])};
}
but In the second code when I tried to access mapMyWord.values.toList() it returns a list of map data again
[{0: TextSpan("my")}, {1: TextSpan("name")}, {2: TextSpan("is")}, {3: TextSpan("doe")}, {4: TextSpan("````http.codeish.com````,")}, ... ,{19: TextSpan("koiter")}]
so my main problem is how to get the values from here.
It returns maps because you're assigning maps with this line :
mapMyWord[t] = {'$t':TextSpan(text: splitForSize[t])};
So in the end you have a Map<Int, Map<String, TextSpan>>.
If you meant to turn the words of that sentence into a list of TextSpan, this would be the way :
var textSpanList = text.split(" ").map((word) => TextSpan(text: word)).toList();
If you want to do it directly in the widget tree, this would do it :
children: <Widget>[
for(var word in text.split(" "))
Text(word),
]
N.B: This last snippet requires a minimum SDK of 2.2.2 in the pubspec.yaml
In your second code, change the assignment part:
Map mapMyWord = {};
// var wordsMap;
var splitForSize = text.split(' ').toList();
for(var t = 0;t<= splitForSize.length-1;t++){
mapMyWord[t] = TextSpan(text: splitForSize[t]);
}
Then, mapMyWord.values.toList() will only return a list of TextSpan's. And if you want to get some specific value from the map:
int index = 1; //some number
print(mapMyWord[index]); //this will return one TextSpan

Draft.js insert image at dropped position

I'm trying to drop image from outside of draft-js editor but it's always inserted at last position of the cursor/selection in editor (or at end if cursor/selection not set).
This is my wrap around draft-js-drag-n-drop-plugin
const droppableBlockDndPlugin = {
...blockDndPlugin,
handleDrop: (
selection,
dataTransfer,
isInternal,
{getEditorState, setEditorState}
) => {
const editorState = getEditorState();
const raw = dataTransfer.data.getData('text');
const data = raw ? raw.split(IMAGE_BLOCK_TYPE_SEPARATOR) : [];
if (data.length > 1 && data[0] === IMAGE_BLOCK_TYPE_PURE) {
const url = data[1];
if (url) {
const newState = imagePlugin.addImage(editorState, url);
setEditorState(newState);
}
}
return blockDndPlugin.handleDrop(selection, dataTransfer, isInternal, {
getEditorState,
setEditorState
});
}
};
Basically I'm just doing extra logic before base handleDrop occurs where I insert image using imagePlugin.addImage. Is there way to drop image to dragged position?
Actually it was quite obvious solution - you should just use passed selection and create new state with it and then add image to that new state:
const newState = imagePlugin.addImage(EditorState.forceSelection(editorState, selection), url);
setEditorState(newState);