Custom QLineEdit, focusProxy and QDataWidgetMapper - qt5

This problem is driving me nuts so I would appreciate some assistance. Obviously done the usual googling and checking qt docs but have not found any solution.
We need to customize a standard QLineEdit. Here is a prototype:
class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
MyLineEdit(QWidget* a_parent)
{
QTextEdit* textEdit = new QTextEdit(this);
textEdit->setMinimumWidth(width() / 2);
textEdit->setMaximumWidth(width() / 2);
textEdit->setMinimumHeight(30);
textEdit->setTabChangesFocus(true);
// background color red
QPalette p = textEdit->palette();
p.setColor(QPalette::Base, QColor(244,20,20));
textEdit->setPalette(p);
textEdit->setVisible(true);
setFocusProxy(textEdit);
}
};
This shows a QLineEdit with a QTextEdit on-top of it.
Using the keyboard to change focus works as expected (the TextEdit gets the focus and not the LineEdit).
Using the mouse to change focus works as expected (selecting the LineEdit forwards the focus to the TextEdit).
The MyLineEdit and regular QLineEdit instances are added to a QDataWidgetMapper. We obviously use setModel method call on the QDataWidgetMapper instance.
In the QDialog, changing focus from a QLineEdit using keyboard or mouse triggers an invocation of our implementation of QAbstractItemModel::setData.
In the same QDialog, changing focus from a MyLineEdit using keyboard or mouse does NOT trigger an invocation of our implementation of QAbstractItemModel::setData.
This problem seems to be related to the setFocusProxy API. When removing setFocusProxy line;
changing focus from a MyLineEdit (specifically the QLineEdit) using keyboard or mouse does trigger an invocation of our implementation of QAbstractItemModel::setData.
changing focus from a MyLineEdit (specifically the QTextEdit) does NOT trigger an invocation of our implementation of QAbstractItemModel::setData.
How can I use setFocusProxy and get invocation of QAbstractItemModel::setData?
What am I doing wrong?

Related

VSCT: Place Search Textbox below the toolwindow toolbar

I have made a toolbar that has a Search Textbox, using the visual studio built in search for the toolwindowpane: https://learn.microsoft.com/pt-pt/previous-versions/visualstudio/visual-studio-2015/extensibility/adding-search-to-a-tool-window?view=vs-2015&redirectedfrom=MSDN
That is working just fine right now after overriding the methods, however i also added a toolbar to the toolwindow from the vsct file, however it is positioning the search and the toolbar in the same row:
Is there any way to position the search bar underneath the toolbar just like the solution explorer in visual studio? If not, is there a way to decrease the toolbar size so it uses the minimum space so it doesn't look weird like in the picture?
Thank you.
EDIT: Constructor of the class that inherits ToolWindowPane:
public CpcObjectsWindow() : base(null)
{
this.Caption = "CPC Objects";
// This is the user control hosted by the tool window; Note that, even if this class implements IDisposable,
// we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on
// the object returned by the Content property.
this.Content = new CpcObjectsWindowControl();
this.ToolBar = new CommandID(new Guid(CpcExtensionPackage.guidCpcExtensionPackageCmdSet), CpcExtensionPackage.cpcObjectsToolbar);
this.ToolBarLocation = (int)VSTWT_LOCATION.VSTWT_TOP;
}
I tried to add search to a tool window , a search control appears at the top of the tool window.
I tried to search form the ToolWindowPane Class but there is not any property can set the size of search bar. I think that you can submit a feature request on DC.

how to see mouseReleased() event outside canvas using processing.js

I have an object I want to drag around the screen with the mouse in Processing. I set acquired to true on mouse down over the object, and to false on mouse up, thus:
void mousePressed() {
if (overThing()) {
acquired = true;
}
}
void mouseReleased() {
acquired = false;
}
I then query acquired in my update(), and drag the object if it is true.
void update() {
\\ other stuff...
if (acquired) {
\\ drag thing code ...
}
}
This all works fine in Processing. mouseReleased() gets called whether I release the mouse inside or outside the active window.
However, when I move the code to Chrome, using processing.js (v1.4.8), mouseReleased() is not called if I release the mouse outside the canvas (whether the mouse is still over the web page, or outside the browser window). So when I return the (now unclicked) mouse to the canvas, the object is still getting dragged around.
I tried including a test of mousePressed in update(), but that also returns true in these circumstances.
Any help on what I need to do to make mouse state changes outside the canvas visible with processing.js?
I don't know about Processing specifically, but releasing mouse buttons outside a widget is a common issue in GUI development.
I suspect that you have no way of knowing the precise time when the mouse is released outside the widget, but you do have two options:
Set acquired = false in mouseOut(), as #Kevin suggests.
I assume there is some type of mouseEntered() method in Processing, and also some way of knowing if the mouse button is currently pressed (either a global variable, or an event object passed to mouseEntered()). You can catch the mouse entered event, check if the mouse has been released, and set acquired = false then.
Like so:
void mouseEntered() {
if (mouse button is pressed) {
acquired = false;
}
}
Edit: From your comments, #Susan, it seems like there is a bug in processing.js, where mousePressed is not set to false if the mouse button is released outside the canvas. One thing pointing to this being a bug is that the mouse movement example on the processing website also shows this behaviour.
Depending upon how much control you have over the website this is going on, and how much effort you want to go to, you could fix the bug yourself by writing some javascript (separate from your processing code):
Define a mouseUp() event on the page <body>, to catch all mouse release events on the page.
In the mouseUp() event, check if the event comes from your Processing control. (There is probably an event object passed to the mouseUp() function, and you might have to give your Processing control an ID to identify it)
If the event doesn't come from your Processing control, then fire a mouseUp event yourself, on the Processing control. This should (hopefully!) trigger a mouse event inside your Processing code.
I'm not sure what Processing will make of the mouse (x,y) position being outside its control when it handles the event you send it. You might want to set a flag on the event object (assuming you can add extra data to the event object) to say "don't use the (x,y) position of this event - it's outside the control".
Edit2: It was easier than I thought! Here is the JavaScript code to detect the mouse being released outside of the Processing canvas and send the mouseReleased event to the canvas. I've tested it on the mouse movement example from the Processing website, and it fixes the bug.
It uses jQuery (although it could be re-written to not use jQuery), and it assumes your Processing canvas has the ID "processingCanvas":
$(':not(processingCanvas)').mouseup(function(){
Processing.getInstanceById('processingCanvas').mouseReleased();
});
To use this code, include it anywhere in your page (in a JavaScript file or in <script> tags) and make sure you have the jQuery library included before this code.
The Processing object allows JavaScript to call any functions defined in your Processing code. Here I've used it to call Processing's built in mouseReleased() function, but if you wanted to call a custom function to handle the mouse-released-outside state differently, then you could.
You should use the mouseOut() function to detect when the mouse leaves the sketch:
void mouseOut() {
acquired = false;
}
More info in the reference here.

Frame without borders and default controls. Sizers doesn't work

I try to write small GUI programm for windows using wx and wxFrame. I have this code in ctor:
MainFrame::MainFrame(wxPoint pos)
: wxFrame(NULL, wxID_ANY, wxT("Sample text"), pos,
wxDefaultSize, wxBORDER_NONE | wxFRAME_NOTASKBAR)
{
SetSize(wxSize(250, 100));
CreateLayout();
}
And CreateLayout function:
void MainFrame::CreateLayout()
{
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(new wxStaticText(this, -1, "1000.56"), 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
SetSizer(sizer);
}
As you can see, I want to align text to vertical center of the frame. But with this set of frame style flags sizers doesn't work! They work only if i set wxDEFAULT_FRAME_STYLE! But i need to have frame without borders and capture and close|minimize|maximize buttons, how can I get this work?
In the MainFrame constructor, move the call to SetSize() after the call to CreateLayout(). That's it.
Normally, the call to Show() after creating the frame should make the above unnecessary, but it looks like in this case it doesn't (see the details below). Anyway, I think it makes sense to first set up all the sizers and controls inside the window, and then change the size to trigger a Layout(), just to be on the safe side.
This also means an alternative solution is to leave the call to SetSize() where it is, and force a layout by adding a call to Layout() at the very end of your CreateLayout(). But... I like being efficient (read: lazy); I'd go with the first solution.
EDIT: I've found some information regarding why this happens.
For a wxFrame created with wxDEFAULT_FRAME_STYLE, the call to Show() ends up calling ::ShowWindow(), which triggers a WM_SIZE, which eventually triggers a Layout().
For a wxFrame created with wxBORDER_NONE, ::ShowWindow() doesn't seem to trigger a WM_SIZE, which is why the solutions above for forcing the call to Layout() are necessary.

Durandal 2.0 Dialog Repositioning

At the bottom of the durandal docs for dialogs / modals (http://durandaljs.com/documentation/Showing-Message-Boxes-And-Modals.html) there's some syntax for repositioning a dialog. The dialog I have gets gradually bigger as the user selects stuff, so every time a selection is made, I'd like to call reposition(). I tried following along with this:
vm.compositionComplete = function (child, parent, context) {
var addEditDialog = dialog.getDialog(context.model); // resolves
// whenever something is selected:
addEditDialog.context.reposition(vm); // no method 'reposition'
}
But I get an error - there is no function reposition. What am I doing wrong?
You can set up a custom dialog context that responds to a reposition message (using Durandal's app.trigger()). You would trigger the message upon some event in your dialog (such as, as you say, the user's selecting stuff).
Also in that custom dialog context, create a method call reposition. In the activate or attached handler of that custom dialog context, subscribe to the message you use to trigger a reposition.
I'm advocating a messaging approach because you may wish to isolate your "selection viewModel" in its own viewModel, and then compose it into your custom dialog context. With this approach, your selection viewModel and your custom dialog context would be loosely bound. That way, you could use your selection viewModel elsewhere in your code (and even have some other viewModel, instead of the custom dialog context, respond to the reposition message).

Custom context menu XAML for WP8

I try to implement a custom ContextMenu in a LongListSelector.
I'm not using the ContextMenu from Microsoft.Phone.Controls.Toolkit, it's basically the same as in the Rowi App:
(source: hiddenpineapple.com)
Approach 1
My list item toggles a VisualState on hold and an overlay is shown with controls in it.
The problem
I can't find a way to go back to the default state when the user clicks outside of the list item (as in the default ContextMenu).
Approach 2
I've implemented a custom template for the toolkit ContextMenu which looks exactly the same. I had to move its margin top to -itemHeight, as by default it is below the item.
The problem
The problem with this solution is, that it automatically closes itself when opening and I couldn't figure out how to avoid this.
Another problem was that it didn't work well with TiltEffect.IsTiltEnabled from the Toolkit (visual problems).
I need your help
Any suggestions on how to get this working?
Answer
Thanks to Cheese, now I know how to properly close the menu when the user clicks outside.
His suggestion was to get the coordinates of a Tap event on the current page, and check if it's inside the menu. When not, close the menu.
So I added a Tap listener to the page when the menu opens, and removed it when the menu closes. From the page listener I got the event coordinates and could check if it's inside the control which holds the menu (same size and position). I received the position of the control with Point leftUpperPoint = control.TransformToVisual(page).Transform(new Point(0, 0)) and the rightLowerPoint by adding the ActualWidth and ActualHeight.
But then I realized:
Why should I even calculate if the tap is inside the menu? I always want to close the menu when the user taps anywhere on the screen. If it's outside, yes. If it's on a menu button, yes.
Another modification I made was to listen for MouseLeftButtonDown instead of Tap as it also triggers when the user swipes.
So I removed this code and came up with the following:
private void ToggleMenu(object sender, System.Windows.Input.GestureEventArgs e)
{
PhoneApplicationFrame frame = ((PhoneApplicationFrame)Application.Current.RootVisual);
VisualState state = this.States.CurrentState;
if (state == null || state.Name == "DefaultState")
{
frame.MouseLeftButtonDown += MouseDownDelegate;
this.State = "MenuState";
}
else
{
frame.MouseLeftButtonDown -= MouseDownDelegate;
this.State = "DefaultState";
}
}
private void MouseDownDelegate(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
ToggleMenu(sender, null);
}
This works perfectly!
Thanks to Cheese for the hint.
Something like this by #denniscode http://dotnet.dzone.com/articles/rowi-show-tap-menu
Approach 1 problem
The best solution would be:
Get the menus coordinates, when user makes a tap - you check are tap coordinates on menu or not, if not - dissmiss - simple.
Approach 2 problem
I guess you had some button in a corner and when you tapped on it - nothing happened? And when you dissmissed the Tilt all worked. It seems that tilt works faster than a click, so, tilt changes the button coordinates, and device thiks you have missed/or dragged off
You can use what #ScottIsAFool suggested and maybe create another Dependency Property on your TapMenu control of type UIElement named CloseWhenTappedElement and automatically listen for Tap events inside your control once set. For example
<Grid x:Name="TapArea"/>
<TapMenu CloseWhenTappedElement="{Binding ElementName=TapArea"}/>