mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 21:02:02 +08:00
Fixed issues for new ComboBoxes:
* Navigation using Up/Down Arrows. * Selection of first element which is started from input letter. * OSX specific: Revert slider step to 1. * Linux specific: Implemented possibility to use Up/Down & Left/Right arrows to navigate inside DropDown.
This commit is contained in:
parent
38b75d1ad2
commit
8bd5243b2b
@ -61,7 +61,10 @@ ComboBox::ComboBox(wxWindow * parent,
|
|||||||
for (int i = 0; i < n; ++i) Append(choices[i]);
|
for (int i = 0; i < n; ++i) Append(choices[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ComboBox::GetSelection() const { return drop.GetSelection(); }
|
int ComboBox::GetSelection() const
|
||||||
|
{
|
||||||
|
return drop.GetSelection();
|
||||||
|
}
|
||||||
|
|
||||||
void ComboBox::SetSelection(int n)
|
void ComboBox::SetSelection(int n)
|
||||||
{
|
{
|
||||||
@ -233,6 +236,11 @@ wxBitmap ComboBox::GetItemBitmap(unsigned int n)
|
|||||||
return icons[n].GetBitmapFor(m_parent);
|
return icons[n].GetBitmapFor(m_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComboBox::OnKeyDown(wxKeyEvent &event)
|
||||||
|
{
|
||||||
|
keyDown(event);
|
||||||
|
}
|
||||||
|
|
||||||
int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
|
int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
|
||||||
unsigned int pos,
|
unsigned int pos,
|
||||||
void ** clientData,
|
void ** clientData,
|
||||||
@ -290,10 +298,15 @@ void ComboBox::keyDown(wxKeyEvent& event)
|
|||||||
{
|
{
|
||||||
int key_code = event.GetKeyCode();
|
int key_code = event.GetKeyCode();
|
||||||
switch (key_code) {
|
switch (key_code) {
|
||||||
#ifndef __WXOSX__
|
|
||||||
case WXK_RETURN:
|
case WXK_RETURN:
|
||||||
if (drop_down) {
|
if (drop_down) {
|
||||||
drop.DismissAndNotify();
|
drop.DismissAndNotify();
|
||||||
|
|
||||||
|
wxCommandEvent e(wxEVT_COMBOBOX);
|
||||||
|
e.SetEventObject(this);
|
||||||
|
e.SetId(GetId());
|
||||||
|
e.SetInt(GetSelection());
|
||||||
|
GetEventHandler()->ProcessEvent(e);
|
||||||
} else if (drop.HasDismissLongTime()) {
|
} else if (drop.HasDismissLongTime()) {
|
||||||
drop.autoPosition();
|
drop.autoPosition();
|
||||||
drop_down = true;
|
drop_down = true;
|
||||||
@ -302,7 +315,6 @@ void ComboBox::keyDown(wxKeyEvent& event)
|
|||||||
GetEventHandler()->ProcessEvent(e);
|
GetEventHandler()->ProcessEvent(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case WXK_UP:
|
case WXK_UP:
|
||||||
case WXK_DOWN:
|
case WXK_DOWN:
|
||||||
case WXK_LEFT:
|
case WXK_LEFT:
|
||||||
@ -314,20 +326,22 @@ void ComboBox::keyDown(wxKeyEvent& event)
|
|||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
wxCommandEvent e(wxEVT_COMBOBOX);
|
|
||||||
e.SetEventObject(this);
|
|
||||||
e.SetId(GetId());
|
|
||||||
e.SetInt(GetSelection());
|
|
||||||
GetEventHandler()->ProcessEvent(e);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WXK_TAB:
|
case WXK_TAB:
|
||||||
HandleAsNavigationKey(event);
|
HandleAsNavigationKey(event);
|
||||||
break;
|
break;
|
||||||
default:
|
default: {
|
||||||
|
if (drop.IsShown() && HasFlag(wxCB_READONLY)) {
|
||||||
|
for (size_t n = 0; n < texts.size(); n++) {
|
||||||
|
if (texts[n].StartsWith(wxString(static_cast<char>(key_code)))) {
|
||||||
|
SetSelection(int(n));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
event.Skip();
|
event.Skip();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,8 @@ public:
|
|||||||
|
|
||||||
wxBitmap GetItemBitmap(unsigned int n);
|
wxBitmap GetItemBitmap(unsigned int n);
|
||||||
|
|
||||||
|
void OnKeyDown(wxKeyEvent& event);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int DoInsertItems(const wxArrayStringsAdapter &items,
|
virtual int DoInsertItems(const wxArrayStringsAdapter &items,
|
||||||
unsigned int pos,
|
unsigned int pos,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "DropDown.hpp"
|
#include "DropDown.hpp"
|
||||||
|
#include "ComboBox.hpp"
|
||||||
#include "../GUI_App.hpp"
|
#include "../GUI_App.hpp"
|
||||||
#include "../OptionsGroup.hpp"
|
#include "../OptionsGroup.hpp"
|
||||||
|
|
||||||
@ -60,10 +61,60 @@ DropDown::DropDown(wxWindow * parent,
|
|||||||
Create(parent, style);
|
Create(parent, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
static gint gtk_popup_key_press (GtkWidget *widget, GdkEvent *gdk_event, wxPopupWindow* win )
|
||||||
|
{
|
||||||
|
// Ignore events sent out before we connected to the signal
|
||||||
|
if (win->m_time >= ((GdkEventKey*)gdk_event)->time)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
GtkWidget *child = gtk_get_event_widget (gdk_event);
|
||||||
|
|
||||||
|
/* We don't ask for button press events on the grab widget, so
|
||||||
|
* if an event is reported directly to the grab widget, it must
|
||||||
|
* be on a window outside the application (and thus we remove
|
||||||
|
* the popup window). Otherwise, we check if the widget is a child
|
||||||
|
* of the grab widget, and only remove the popup window if it
|
||||||
|
* is not. */
|
||||||
|
if (child != widget) {
|
||||||
|
while (child) {
|
||||||
|
if (child == widget)
|
||||||
|
return FALSE;
|
||||||
|
child = gtk_widget_get_parent(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar* keyval = gdk_keyval_name(((GdkEventKey*)gdk_event)->keyval);
|
||||||
|
const long keyCode = strcmp(keyval, "Up") == 0 ? WXK_UP :
|
||||||
|
strcmp(keyval, "Down") == 0 ? WXK_DOWN :
|
||||||
|
strcmp(keyval, "Left") == 0 ? WXK_LEFT :
|
||||||
|
strcmp(keyval, "Right") == 0 ? WXK_RIGHT :
|
||||||
|
strcmp(keyval, "Return") == 0 ? WXK_RETURN : WXK_NONE;
|
||||||
|
|
||||||
|
if (keyCode != WXK_NONE) {
|
||||||
|
wxKeyEvent event( wxEVT_KEY_DOWN, win->GetId());
|
||||||
|
event.m_keyCode = keyCode;
|
||||||
|
event.SetEventObject( win );
|
||||||
|
(void)win->HandleWindowEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void DropDown::Create(wxWindow * parent,
|
void DropDown::Create(wxWindow * parent,
|
||||||
long style)
|
long style)
|
||||||
{
|
{
|
||||||
wxPopupTransientWindow::Create(parent);
|
wxPopupTransientWindow::Create(parent);
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
g_signal_connect (m_widget, "key_press_event", G_CALLBACK (gtk_popup_key_press), this);
|
||||||
|
|
||||||
|
Bind(wxEVT_KEY_DOWN, [parent](wxKeyEvent &e) {
|
||||||
|
if (ComboBox* cb = dynamic_cast<ComboBox*>(parent))
|
||||||
|
cb->OnKeyDown(e);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!wxOSX) SetBackgroundStyle(wxBG_STYLE_PAINT);
|
if (!wxOSX) SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||||
state_handler.attach({&border_color, &text_color, &selector_border_color, &selector_background_color});
|
state_handler.attach({&border_color, &text_color, &selector_border_color, &selector_background_color});
|
||||||
state_handler.update_binds();
|
state_handler.update_binds();
|
||||||
@ -95,6 +146,8 @@ void DropDown::SetSelection(int n)
|
|||||||
n = -1;
|
n = -1;
|
||||||
if (selection == n) return;
|
if (selection == n) return;
|
||||||
selection = n;
|
selection = n;
|
||||||
|
if (IsShown())
|
||||||
|
autoPosition();
|
||||||
paintNow();
|
paintNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +265,11 @@ void DropDown::SetTransparentBG(wxDC& dc, wxWindow* win)
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr int slider_width = 12;
|
constexpr int slider_width = 12;
|
||||||
|
#ifdef __WXOSX__
|
||||||
|
constexpr int slider_step = 1;
|
||||||
|
#else
|
||||||
constexpr int slider_step = 5;
|
constexpr int slider_step = 5;
|
||||||
|
#endif
|
||||||
constexpr int items_padding = 2;
|
constexpr int items_padding = 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -423,14 +480,14 @@ void DropDown::autoPosition()
|
|||||||
if (use_content_width && texts.size() <= 15) size.x += 6;
|
if (use_content_width && texts.size() <= 15) size.x += 6;
|
||||||
size.y = drect.GetBottom() - GetPosition().y - 10;
|
size.y = drect.GetBottom() - GetPosition().y - 10;
|
||||||
wxWindow::SetSize(size);
|
wxWindow::SetSize(size);
|
||||||
if (selection >= 0) {
|
|
||||||
if (offset.y + rowSize.y * (selection + 1) > size.y)
|
|
||||||
offset.y = size.y - rowSize.y * (selection + 1);
|
|
||||||
else if (offset.y + rowSize.y * selection < 0)
|
|
||||||
offset.y = -rowSize.y * selection;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (selection >= 0) {
|
||||||
|
if (offset.y + rowSize.y * (selection + 1) > size.y)
|
||||||
|
offset.y = size.y - rowSize.y * (selection + 3);
|
||||||
|
else if (offset.y + rowSize.y * selection < 0)
|
||||||
|
offset.y = -rowSize.y * selection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDown::mouseDown(wxMouseEvent& event)
|
void DropDown::mouseDown(wxMouseEvent& event)
|
||||||
@ -461,6 +518,10 @@ void DropDown::mouseReleased(wxMouseEvent& event)
|
|||||||
if (HasCapture())
|
if (HasCapture())
|
||||||
ReleaseMouse();
|
ReleaseMouse();
|
||||||
if (hover_item >= 0) { // not moved
|
if (hover_item >= 0) { // not moved
|
||||||
|
#ifdef __WXOSX__
|
||||||
|
// To avoid cases, when some dialog appears after item selection, but DropDown is still shown
|
||||||
|
Hide();
|
||||||
|
#endif
|
||||||
sendDropDownEvent();
|
sendDropDownEvent();
|
||||||
DismissAndNotify();
|
DismissAndNotify();
|
||||||
}
|
}
|
||||||
@ -507,6 +568,8 @@ void DropDown::mouseMove(wxMouseEvent &event)
|
|||||||
|
|
||||||
void DropDown::mouseWheelMoved(wxMouseEvent &event)
|
void DropDown::mouseWheelMoved(wxMouseEvent &event)
|
||||||
{
|
{
|
||||||
|
if (event.GetWheelRotation() == 0)
|
||||||
|
return;
|
||||||
auto delta = event.GetWheelRotation() > 0 ? rowSize.y : -rowSize.y;
|
auto delta = event.GetWheelRotation() > 0 ? rowSize.y : -rowSize.y;
|
||||||
wxPoint pt2 = offset + wxPoint{0, slider_step * delta};
|
wxPoint pt2 = offset + wxPoint{0, slider_step * delta};
|
||||||
int text_size = int(texts.size());
|
int text_size = int(texts.size());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user