Skip to content

Commit

Permalink
Changed displaying of the right part of paths #1663 (#1849)
Browse files Browse the repository at this point in the history
  • Loading branch information
oleg68 authored Mar 28, 2024
1 parent b92ab3e commit 3e33a3d
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 60 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Changed displaying of the right part of paths https://github.com/GrandOrgue/grandorgue/issues/1663
- Added automatic update checking at startup (configurable) and the ability to check for updates from Help menu
- Increased maximum value of allowed size to 32000 https://github.com/GrandOrgue/grandorgue/issues/1840
- Added capability of specifying AmplitudeLevel, Gain, PitchTuning, PitchCorrection and TrackerDelay, Percussive, HasIndependentRelease at the WindchestGroup level of ODF
Expand Down
115 changes: 78 additions & 37 deletions src/grandorgue/dialogs/GOSelectOrganDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,26 @@

#include "GOSelectOrganDialog.h"

#include <wx/listctrl.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>

#include "archive/GOArchiveFile.h"
#include "config/GOConfig.h"
#include "size/GOAdditionalSizeKeeperProxy.h"
#include "wxcontrols/GOGrid.h"

#include "GOOrgan.h"
#include "GOOrganList.h"

enum { ID_ORGANS = 200 };

BEGIN_EVENT_TABLE(GOSelectOrganDialog, GOSimpleDialog)
EVT_LIST_ITEM_ACTIVATED(ID_ORGANS, GOSelectOrganDialog::OnDoubleClick)
EVT_GRID_CMD_SELECT_CELL(ID_ORGANS, GOSelectOrganDialog::OnSelectCell)
EVT_GRID_CMD_CELL_LEFT_DCLICK(ID_ORGANS, GOSelectOrganDialog::OnDoubleClick)
END_EVENT_TABLE()

enum { GRID_COL_NAME = 0, GRID_COL_PACKAGE, GRID_COL_PATH, GRID_N_COLS };

GOSelectOrganDialog::GOSelectOrganDialog(wxWindow *parent, GOConfig &config)
: GOSimpleDialog(
nullptr,
Expand All @@ -33,61 +37,98 @@ GOSelectOrganDialog::GOSelectOrganDialog(wxWindow *parent, GOConfig &config)
wxDIALOG_NO_PARENT),
r_OrganList(config) {
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
topSizer->AddSpacer(5);

m_Organs = new wxListView(
this,
ID_ORGANS,
wxDefaultPosition,
wxDefaultSize,
wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES | wxLC_VRULES);
m_Organs->InsertColumn(0, _("Church"));
m_Organs->InsertColumn(1, _("Organ package"));
m_Organs->InsertColumn(2, _("Organ path"));
topSizer->Add(m_Organs, 1, wxEXPAND | wxALL, 5);

m_Organs->SetColumnWidth(0, 150);
m_Organs->SetColumnWidth(1, 150);
m_Organs->SetColumnWidth(2, 300);

topSizer->AddSpacer(5);

m_GridOrgans
= new GOGrid(this, ID_ORGANS, wxDefaultPosition, wxSize(100, 40));
m_GridOrgans->CreateGrid(0, 3, wxGrid::wxGridSelectRows);
m_GridOrgans->HideRowLabels();
m_GridOrgans->EnableEditing(false);
m_GridOrgans->SetColLabelValue(GRID_COL_NAME, _("Name"));
m_GridOrgans->SetColLabelValue(GRID_COL_PACKAGE, _("Organ package"));
m_GridOrgans->SetColLabelValue(GRID_COL_PATH, _("Organ path"));
m_GridOrgans->SetColSize(GRID_COL_NAME, 150);
m_GridOrgans->SetColSize(GRID_COL_PACKAGE, 150);
m_GridOrgans->SetColSize(GRID_COL_PATH, 300);
m_GridOrgans->SetColumnRightVisible(GRID_COL_PATH, true);
topSizer->Add(m_GridOrgans, 1, wxEXPAND | wxALL, 5);

LayoutWithInnerSizer(topSizer);
}

const wxString WX_GRID_ORGANS = wxT("GridOrgans");

void GOSelectOrganDialog::ApplyAdditionalSizes(
const GOAdditionalSizeKeeper &sizeKeeper) {
GOAdditionalSizeKeeperProxy proxyGridOrgans(
const_cast<GOAdditionalSizeKeeper &>(sizeKeeper), WX_GRID_ORGANS);

m_GridOrgans->ApplyColumnSizes(proxyGridOrgans);
}

void GOSelectOrganDialog::CaptureAdditionalSizes(
GOAdditionalSizeKeeper &sizeKeeper) const {
GOAdditionalSizeKeeperProxy proxyGridOrgans(sizeKeeper, WX_GRID_ORGANS);

m_GridOrgans->CaptureColumnSizes(proxyGridOrgans);
}

bool GOSelectOrganDialog::TransferDataToWindow() {
for (unsigned i = 0, j = 0; j < r_OrganList.GetOrganList().size(); j++) {
const GOOrgan *o = r_OrganList.GetOrganList()[j];
int nRowsOld = m_GridOrgans->GetNumberRows();
unsigned rowN = 0;

if (nRowsOld > 0)
m_GridOrgans->DeleteRows(0, nRowsOld);
m_OrganPtrs.clear();
for (const auto o : r_OrganList.GetOrganList())
if (o->IsUsable(r_OrganList)) {
const bool isArchive = o->GetArchiveID() != wxEmptyString;
const wxString &archiveId = o->GetArchiveID();
const bool isArchive = !archiveId.IsEmpty();
wxString packageName;

m_Organs->InsertItem(i, o->GetChurchName());
m_Organs->SetItemPtrData(i, (wxUIntPtr)o);
if (isArchive) {
const GOArchiveFile *a = r_OrganList.GetArchiveByID(o->GetArchiveID());
const GOArchiveFile *a
= r_OrganList.GetArchiveByPath(o->GetArchivePath());

m_Organs->SetItem(i, 1, a ? a->GetName() : o->GetArchiveID());
packageName = a ? a->GetName() : archiveId;
}
m_Organs->SetItem(
i, 2, isArchive ? o->GetArchivePath() : o->GetODFPath());
i++;
m_OrganPtrs.push_back(o);
m_GridOrgans->AppendRows(1);
m_GridOrgans->SetCellValue(rowN, GRID_COL_NAME, o->GetChurchName());
m_GridOrgans->SetCellValue(rowN, GRID_COL_PACKAGE, packageName);
m_GridOrgans->SetCellValue(
rowN, GRID_COL_PATH, isArchive ? o->GetArchivePath() : o->GetODFPath());
rowN++;
}
}
return true;
}

void GOSelectOrganDialog::OnSelectCell(wxGridEvent &event) {
const int index = event.GetRow();
const wxArrayInt selectedRows = m_GridOrgans->GetSelectedRows();
bool isAlreadySelected = false;

for (auto rowN : selectedRows)
if (rowN == index)
isAlreadySelected = true;
else
m_GridOrgans->DeselectRow(rowN);
if (index >= 0 && !isAlreadySelected)
m_GridOrgans->SelectRow(index);
}

const GOOrgan *GOSelectOrganDialog::GetSelection() {
int index = m_GridOrgans->GetGridCursorRow();

return index >= 0 ? m_OrganPtrs[index] : nullptr;
}

bool GOSelectOrganDialog::Validate() {
bool isValid = true;
long index = m_Organs->GetFirstSelected();

if (index < 0 || !m_Organs->GetItemData(index)) {
if (!GetSelection()) {
wxMessageBox(
_("Please select an organ"), _("Error"), wxOK | wxICON_ERROR, this);
isValid = false;
}
return isValid;
}

const GOOrgan *GOSelectOrganDialog::GetSelection() {
return (const GOOrgan *)m_Organs->GetItemData(m_Organs->GetFirstSelected());
}
17 changes: 13 additions & 4 deletions src/grandorgue/dialogs/GOSelectOrganDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,34 @@
#ifndef GOSELECTORGANDIALOG_H_
#define GOSELECTORGANDIALOG_H_

#include <vector>

#include <wx/event.h>

#include "common/GOSimpleDialog.h"

class wxListEvent;
class wxListView;
class wxGridEvent;

class GOConfig;
class GOGrid;
class GOOrgan;
class GOOrganList;

class GOSelectOrganDialog : public GOSimpleDialog {
private:
const GOOrganList &r_OrganList;
wxListView *m_Organs;

GOGrid *m_GridOrgans;
std::vector<GOOrgan *> m_OrganPtrs;

void ApplyAdditionalSizes(const GOAdditionalSizeKeeper &sizeKeeper) override;
void CaptureAdditionalSizes(
GOAdditionalSizeKeeper &sizeKeeper) const override;

bool Validate() override;

void OnDoubleClick(wxListEvent &event) { CloseAdvanced(wxID_OK); }
void OnSelectCell(wxGridEvent &event);
void OnDoubleClick(wxGridEvent &event) { CloseAdvanced(wxID_OK); }

public:
GOSelectOrganDialog(wxWindow *parent, GOConfig &config);
Expand Down
44 changes: 25 additions & 19 deletions src/grandorgue/wxcontrols/GOGrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@

#include "GOGrid.h"

#include <algorithm>

#include <wx/dc.h>

#include "size/GOAdditionalSizeKeeper.h"

class RightVisibleCellRenderer : public wxGridCellStringRenderer {
class GOCellRenderer : public wxGridCellStringRenderer {
private:
bool m_IsRightVisible;

virtual void Draw(
wxGrid &grid,
wxGridCellAttr &attr,
Expand All @@ -20,12 +25,10 @@ class RightVisibleCellRenderer : public wxGridCellStringRenderer {
int row,
int col,
bool isSelected) override;
};

static size_t clamp(size_t v, size_t l, size_t u) {
// std::clamp in C++17
return v < l ? l : v > u ? u : v;
}
public:
GOCellRenderer(bool isRightVisible) : m_IsRightVisible(isRightVisible) {}
};

static wxString truncate_line_left(
wxDC &dc, const wxString &line, wxCoord targetWidth) {
Expand Down Expand Up @@ -54,7 +57,7 @@ static wxString truncate_line_left(
// Heuristic: consider average character width
wxCoord avgCharW = (lW - uW) / (u - l);
size_t mid = avgCharW != 0
? clamp(l + (lW - targetWidth) / avgCharW, l + 1, u - 1)
? std::clamp(l + (lW - targetWidth) / avgCharW, l + 1, u - 1)
: (l + u) / 2;
wxCoord midW, midH;
wxString midLine = ellipsis + line.Mid(mid);
Expand All @@ -76,7 +79,8 @@ static void draw_text_rectangle(
const wxArrayString &lines,
const wxRect &rect,
int horizAlign,
int vertAlign) {
int vertAlign,
bool isRightVisible) {
// Based on wxGrid::DrawTextRectangle(wxDC, wxArrayString, ...).
// Simplified for HORIZONTAL text orientation
if (lines.empty()) {
Expand Down Expand Up @@ -128,14 +132,15 @@ static void draw_text_rectangle(
case wxALIGN_LEFT:
default:
x = rect.x + GRID_TEXT_MARGIN;
if (textWidth > rect.width) {

if (textWidth > rect.width && isRightVisible) {
// if text box is too wide, prefer showing its right part
x -= textWidth - rect.width;
}
break;
}

if (x >= rect.x) {
if (x >= rect.x || !isRightVisible) {
// Text fits
dc.DrawText(line, x, y);
} else {
Expand All @@ -150,7 +155,7 @@ static void draw_text_rectangle(
}
}

void RightVisibleCellRenderer::Draw(
void GOCellRenderer::Draw(
wxGrid &grid,
wxGridCellAttr &attr,
wxDC &dc,
Expand All @@ -173,7 +178,8 @@ void RightVisibleCellRenderer::Draw(
// Render text
wxRect rect = rectCell;
rect.Inflate(-1);
draw_text_rectangle(grid, dc, lines, rect, horizAlign, vertAlign);
draw_text_rectangle(
grid, dc, lines, rect, horizAlign, vertAlign, m_IsRightVisible);
}

GOGrid::GOGrid(
Expand All @@ -184,11 +190,13 @@ GOGrid::GOGrid(
long style,
const wxString &name)
: wxGrid(parent, id, pos, size, style, name),
p_RightVisibleRenderer(new RightVisibleCellRenderer()) {}
p_NormalVisibleRenderer(new GOCellRenderer(false)),
p_RightVisibleRenderer(new GOCellRenderer(true)) {}

GOGrid::~GOGrid() {
// force deleting p_RightVisibleRenderer after deletion of all columns
p_RightVisibleRenderer->DecRef();
p_NormalVisibleRenderer->DecRef();
}

bool GOGrid::IsColumnRightVisible(unsigned colN) const {
Expand Down Expand Up @@ -222,12 +230,10 @@ void GOGrid::CaptureColumnSizes(GOAdditionalSizeKeeper &sizeKeeper) const {
}

wxGridCellRenderer *GOGrid::GetDefaultRendererForCell(int row, int col) const {
wxGridCellRenderer *pRenderer;
wxGridCellRenderer *pRenderer = IsColumnRightVisible(col)
? p_RightVisibleRenderer
: p_NormalVisibleRenderer;

if (IsColumnRightVisible(col)) {
p_RightVisibleRenderer->IncRef();
pRenderer = p_RightVisibleRenderer;
} else
pRenderer = wxGrid::GetDefaultRendererForCell(row, col);
pRenderer->IncRef();
return pRenderer;
}
1 change: 1 addition & 0 deletions src/grandorgue/wxcontrols/GOGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class GOAdditionalSizeKeeper;

class GOGrid : public wxGrid {
private:
wxGridCellStringRenderer *p_NormalVisibleRenderer;
wxGridCellStringRenderer *p_RightVisibleRenderer;
std::vector<bool> m_AreColumnsRightVisible;

Expand Down

0 comments on commit 3e33a3d

Please sign in to comment.