Create slider field type

This commit is contained in:
GenevensiS
2025-05-22 12:52:26 +02:00
committed by GitHub
parent 38624d4784
commit 616ea3f725
12 changed files with 274 additions and 33 deletions
+84 -30
View File
@@ -15,6 +15,12 @@
#include <util/rotation.hpp>
#include <gfx/gfx.hpp>
#include <wx/dcbuffer.h>
bool DropDownList::slider_loaded;
wxBitmap DropDownList::slider_left;
wxBitmap DropDownList::slider_right;
wxBitmap DropDownList::slider_center;
wxBitmap DropDownList::slider_tick;
// ----------------------------------------------------------------------------- : DropDownHider
@@ -91,7 +97,7 @@ void DropDownList::show(bool in_place, wxPoint pos, RealRect* rect) {
onShow();
// find selection
selected_item = selection();
// width
// determine item width
size_t count = itemCount();
if (item_size.width == 100) { // not initialized
wxClientDC dc(this);
@@ -102,16 +108,19 @@ void DropDownList::show(bool in_place, wxPoint pos, RealRect* rect) {
item_size.width = max(item_size.width, text_width + icon_size.width + 14); // 14 = room for popup arrow + padding
}
}
// height
int line_count = 0;
for (size_t i = 0 ; i < count ; ++i) if (lineBelow(i)) line_count += 1;
// size
// determine dropdown size
RealSize border_size(2,2); // GetClientSize() - GetSize(), assume 1px borders
RealSize size(
item_size.width + marginW * 2,
item_size.height * count + marginH * 2 + line_count
);
// placement
RealSize size;
if (is_slider) {
size.height = 70 + marginH * 2;
size.width = min(1000.0, max(150.0, max(100.0 + count, item_size.width + marginW * 2)));
} else {
int line_count = 0;
for (size_t i = 0; i < count; ++i) if (lineBelow(i)) line_count += 1;
size.height = item_size.height * count + marginH * 2 + line_count;
size.width = item_size.width + marginW * 2;
}
// determine placement
int parent_height = 0;
if (!in_place && viewer) {
// Position the drop down list below the editor control (based on the style)
@@ -302,17 +311,48 @@ void DropDownList::onPaint(wxPaintEvent&) {
void DropDownList::draw(DC& dc) {
// Size
wxSize cs = dc.GetSize();
size_t count = itemCount();
// Draw background & frame
dc.SetPen (*wxTRANSPARENT_PEN);
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.DrawRectangle(0, 0, cs.x, cs.y);
dc.SetFont(*wxNORMAL_FONT);
// Draw items
int y = marginH - visible_start;
size_t count = itemCount();
for (size_t i = 0 ; i < count ; ++i) {
drawItem(dc, y, i);
y += (int)item_size.height + lineBelow(i);
dc.SetFont(*wxNORMAL_FONT);
if (is_slider) {
// If it's a slider, draw the slider
cs = GetClientSize();
dc.SetPen(*wxBLACK_PEN);
dc.SetFont(wxFont(12, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, _("Arial")));
int first_text_width;
dc.GetTextExtent(capitalize(itemText(0)), &first_text_width, nullptr);
int last_text_width;
dc.GetTextExtent(capitalize(itemText(count-1)), &last_text_width, nullptr);
dc.DrawText(capitalize(itemText(0)), marginW + 4, 14);
dc.DrawText(capitalize(itemText(count-1)), cs.x - marginW - 4 - last_text_width, 14);
int slider_start = first_text_width + marginW + 16;
int slider_end = cs.x - (last_text_width + marginW + 16);
dc.DrawBitmap(slider_left, slider_start, 14);
for (size_t i = slider_start + 19; i < slider_end - 19; i+=19) {
dc.DrawBitmap(slider_center, i, 14);
}
dc.DrawBitmap(slider_right, slider_end - 19, 14);
int selected_index = selected_item < 0 ? 0 : selected_item;
int slider_pos = round((double)selected_index/(count - 1) * (slider_end - slider_start)) + slider_start;
dc.DrawBitmap(slider_tick, slider_pos - 7, 9); // -7 cause the bitmap is 15 pixels wide
int selected_text_width;
dc.GetTextExtent(capitalize(itemText(selected_index)), &selected_text_width, nullptr);
dc.DrawText(capitalize(itemText(selected_index)), slider_pos - selected_text_width/2, 44);
dc.SetFont(*wxNORMAL_FONT);
} else {
// If it's not a slider, draw the list of items
int y = marginH - visible_start;
for (size_t i = 0; i < count; ++i) {
drawItem(dc, y, i);
y += (int)item_size.height + lineBelow(i);
}
}
}
@@ -384,21 +424,35 @@ void DropDownList::onMotion(wxMouseEvent& ev) {
ev.Skip();
return;
}
// find selected item
int startY = marginH - visible_start;
// find selected item
size_t count = itemCount();
for (size_t i = 0 ; i < count ; ++i) {
int endY = startY + (int)item_size.height;
if (ev.GetY() >= startY && ev.GetY() < endY) {
if (itemEnabled(i)) {
showSubMenu(i, startY);
if (is_slider) {
int first_text_width;
GetTextExtent(capitalize(itemText(0)), &first_text_width, nullptr);
int last_text_width;
GetTextExtent(capitalize(itemText(count - 1)), &last_text_width, nullptr);
int slider_start = first_text_width + marginW + 16;
int slider_end = cs.x - (last_text_width + marginW + 16);
int slider_pos = ev.GetX();
if (slider_pos < slider_start) slider_pos = slider_start;
if (slider_pos > slider_end) slider_pos = slider_end;
int selected_item = round(((double)(slider_pos - slider_start)) / (slider_end - slider_start) * (count - 1));
selectItem(selected_item);
} else {
int startY = marginH - visible_start;
for (size_t i = 0; i < count; ++i) {
int endY = startY + (int)item_size.height;
if (ev.GetY() >= startY && ev.GetY() < endY) {
if (itemEnabled(i)) {
showSubMenu(i, startY);
}
selectItem(i);
return;
}
selectItem(i);
return;
startY = endY + lineBelow(i);
}
startY = endY + lineBelow(i);
hideSubMenu();
}
hideSubMenu();
}
void DropDownList::onMouseLeave(wxMouseEvent& ev) {
@@ -516,4 +570,4 @@ BEGIN_EVENT_TABLE(DropDownList,wxPopupWindow)
EVT_LEAVE_WINDOW (DropDownList::onMouseLeave)
EVT_MOUSEWHEEL (DropDownList::onMouseWheel)
EVT_SCROLLWIN (DropDownList::onScroll)
END_EVENT_TABLE ()
END_EVENT_TABLE ()