How to use .NET TextBoxRenderer with TextBoxState.Hot to draw a hot text box? - winforms

i am trying to use TextBoxRenderer to render a "hot" text box:
TextBoxRenderer.DrawTextBox(e.Graphics, rectangle, TextBoxState.Hot);
except that it doesn't work, it doesn't render the text box as hot.
TextBoxState.Selected doesn't render as selected
TextBoxState.Hot doesn't render as hot
How do i make TextBoxRenderer.DrawTextBox(..., Hot) render as Hot?
Related but different question:
How do i make TextBoxRenderer.DrawTextBox(..., Selected) render as Selected?

It seems that TextBoxRenderer uses EP_BACKGROUNDWITHBORDER, whereas EP_EDITBORDER_NOSCROLL is typically used by TextBox controls[1].
if (VisualStyleRenderer.IsSupported)
{
// Use the text control's focus rectangle.
// EP_EDITBORDER_NOSCROLL, EPSN_FOCUSED
VisualStyleElement element = VisualStyleElement.CreateElement("EDIT", 6, 3);
if (VisualStyleRenderer.IsElementDefined(element))
{
VisualStyleRenderer renderer = new VisualStyleRenderer(element);
renderer.DrawBackground(e.Graphics, ClientRectangle);
}
}
(It's tempting to try to get the element from VisualStyleElement but there's no nested class for EP_EDITBORDER_NOSCROLL. So numeric constants 6 and 3 it is.)

Related

Limit the number of results for autocomplete component?

I'm using React JS and I've created an autocomplete component that returns a list of results.
Here's my code for the autocomplete :
const [pokedexMatch, setPokedexMatch] = useState([]);
const searchPokedex = (text) => {
if (!text) {
setPokedexMatch([]);
} else {
let matches = pokedex.filter((pokedex) => {
const regex = new RegExp(`${text}`, "gi");
return pokedex?.name?.match(regex);
});
setPokedexMatch(matches);
}
};
Here's a working sandbox with some dummy text below. As you can see, when you type a single letter it returns a lot of results and move the text below the results.
What I'd like to do is limit the number of results to 5 and make the list of results go above the text (I guess that I should use absolute positioning but I'd like to know if there is another method without absolute positioning) ?
To limit your results to 5, use simple Javascript!
setPokedexMatch(matches.slice(0, 5));
For the positioning part of your question, you're on the right track - you can use absolute positioning of a div with a white background to make the results appear to be "above" the text.
EDIT: I've updated your sandbox here and made some very minor changes.
When you map over an array, make sure you include a key prop. Read more here.
I added the slice method to limit your results to 5
I added a simple above class to the parent <ul /> element to make the results appear "above" the text. This is just one way to accomplish this, I'll leave it to you to style it better if you'd like.

Detecting which node is selected within a slate-react text editor

I am currently working on a slate text editor where the user can add images and text. I would also like to have a hovering toolbar which serves different buttons depending on what type of element the user has selected.
For example if the user has selected an image then I would like to serve one set of buttons. If the user has selected a paragraph I would like to serve another set of buttons.
After looking through the examples found here:
https://www.slatejs.org/examples/richtext
I have pieced together a rough example of my desired text editor without the context dependant hovering toolbar buttons:
https://codesandbox.io/s/suspicious-pine-lrxgw
But I am struggling to work out how to detect what type of element is selected within the editor? I don't know if there is a way to do this using slate-react? Or even in vanilla JS?
Ideally I would also be able to get other information about the element as well. For example the images height and width as this would help with styling.
Any help appreciated
You can get the currently focused node by using the selection property from the editor and which is a Range. You then use the anchor or focus to select the currently selected children.
anchor & focus are Points which are basically an array the first item is the current block and the second item indicates the position in the block.
Point objects refer to a specific location in a text node in a Slate
document. Its path refers to the location of the node in the tree, and
its offset refers to distance into the node's string of text. Points
may only refer to Text nodes.
using the selection array we can get the current selected block like so
if (selection !== null && selection.anchor !== null) {
selected = editor.children[selection.anchor.path[0]];
} else {
selected = null;
}
Later in your render function you can have a check to render what you want.
Here, path comes from selection.anchor.path, which I noticed will walk into leaves down to a final text node (I want the cell of my table, not the text), same with paragraphs. I want the full { type: 'paragraph', children: [...text node] }, not just the text. So, I pop the end off and reduce.
const pathClone = [...path];
pathClone.pop(); // get rid of trailing text node postion in path.
const focusedNode = pathClone.reduce((node, pathPosition) => {
if (!node) return editor.children[pathPosition];
return node.children[pathPosition];
}, null);
// console.log('last node type before text node: ', focusedNode.type, focusedNode);

How to get know if a checkbox has been selected in a dynamic UI in codenameone

I have a container with dynamic UI components including checkboxes. How can I know the selection status of a particular component?
Using isSelected() doesn't work as it is always false because it seems to pick the last checkbox in the list which returns false since it is unselected.
bool_isMemberSelected = cb_member.isSelected(); //returns false.
I am able to get the checkbox at a particular index in the parent component but once I have it there is no isSelected option on it. So I use a dirty way by tokenizing the string representing the component to get to the selected status. There must be a better way.
System.out.println("Checkbox Data "+cnt_tablerow[Integer.parseInt(lbl_memberno.getName())].getComponentAt(0)); //Checkbox Data: CheckBox[x=0 y=0 width=63 height=152 name=524, text = , gap = 2, selected = true]
String str_chkbox = StringUtil.tokenize(StringUtil.tokenize(cnt_tablerow[Integer.parseInt(lbl_memberno.getName())].getComponentAt(0), ']').get(0), '[').get(1);
String str_status = StringUtil.tokenize(StringUtil.tokenize(str_chkbox, ',').get(3), '=').get(1).trim();
if(str_status == "true"){}
You could generate and set a name for each component when generating your dynamic UI. With a name you can use the ComponentSelector API or a simple for to get the Checkbox you want and then use the isSelected method.
If you want to keep your actual selection logic with the index, you can simply check the instance of your component and cast it to a CheckBox, that would also do the trick.

How does the MenuBar object at the bottom of Form work?

I'm struggling with the MenuBar at the bottom of a form - the one indicated by the codenameone Javadocs here:
I can't seem to find an example, but from what I can tell, something like the following should work:
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Welcome");
MenuBar menubar = hi.getMenuBar();
Command test = Command.create("TEST",null,(e)->{
Log.p("test clicked");
});
menubar.addCommand(test);
hi.show();
}
However, I don't get a MenuBar.
Obviously I'm missing something basic here - can anyone show me what I'm doing wrong?
The menu bar logic is a bit old, you don't need to define that or use it. Modern Codename One applications use the Toolbar to place elements and usually add their content to the top of the Form. I'll update the JavaDoc to reflect that.
If you are interested in having a menu at the bottom of the form just do this:
Form myForm = new Form("With Menu at Bottom", new BorderLayout());
Container content = new Container(...);
myForm.add(BorderLayout.CENTER, content);
myForm.add(BorderLayout.SOUTH,
GridLayout.encloseIn(4, menuButton1, menuButton2, menuButton3, menuButton4);
Just add your real content to content and create the buttons any way you like.
You didn't assign a MenuBar to the form yet. First, you must create one and then assign it using the function
setMenuBar(MenuBar menubar)

ExtJS: dynamically changing element styles

I'm trying to dynamically assign styles to my elements (in this case, a ExtJS displayfield).
I can't use CSS classes since I don't know what the colors will be until runtime.
I'm trying:
myDisplayField.getEl().applyStyles({ color: '#ff0000' }); //fail
myDisplayField.getEl().setStyle('color', '#ff0000'); //fail
Just to get the mechanism right, but neither seem to work.
It works using Ext.get(<div id>).setStyle(...), but that doesn't seem as clean to me. Is there a reason the former attempts don't work?
What am I missing?
Thanks.
The reason is simple: you're trying to set the styles on a wrong element. Each field, including displayfield, has quite complex table-based DOM structure that encapsulates the field label, the actual input element (or a div for display fields), and the supporting elements. field.getEl() returns the top, or main, element for a component; in this case that's the top <table> tag. What you need is the input element instead.
Now if you take a look at the DOM structure you'll notice that the <div> that you need to set styles on has an id of displayfield-123-inputEl. The -inputEl suffix is there for a reason; in most cases it indicates that the element has a Ext.dom.Element shortcut in its respective Component. For a field, that would be field.inputEl property that is available after the field has been rendered to the DOM. You can use that as well:
myDisplayField.inputEl.setStyle(...)
Or just use the convenience method available for the fields:
myDisplayField.setFieldStyle(...)
I would also suggest not hardcoding the colors but rather use CSS classes instead. In most cases there is a limited choice of colors depending on a condition, like invalid input, etc. Using CSS will require a bit more work upfront but will save you a lot of headache down the road, when someone will come up with a bright idea of changing the shade of red used for the invalid input, or somesuch.

Resources