wxMaxima
Loading...
Searching...
No Matches
MatrCell.h
1// -*- mode: c++; c-file-style: "linux"; c-basic-offset: 2; indent-tabs-mode: nil -*-
2//
3// Copyright (C) 2004-2015 Andrej Vodopivec <andrej.vodopivec@gmail.com>
4// (C) 2014-2016 Gunter Königsmann <wxMaxima@physikbuch.de>
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20//
21// SPDX-License-Identifier: GPL-2.0+
22
23#ifndef MATRCELL_H
24#define MATRCELL_H
25
26#include "Cell.h"
27#include "MatrixBlock.h"
28#include <optional>
29
30#include <vector>
31
94class MatrCell final : public Cell
95{
96public:
98 MatrCell(GroupCell *group, const MatrCell &cell);
99 std::unique_ptr<Cell> Copy(GroupCell *group) const override;
100 const CellTypeInfo &GetInfo() override;
101
102 size_t GetInnerCellCount() const override { return m_cells.size(); }
103 Cell *GetInnerCell(size_t index) const override { return m_cells.at(index).get(); }
104 Cell *GetInnerCell(int x, int y) const {
105 return m_cells.at(static_cast<size_t>(x) * m_matWidth + y).get(); }
106
107 void Recalculate(const AFontSize fontsize) const override;
108
110 void SetCurrentPoint(wxPoint point) const override;
111 void Draw(wxDC *dc, wxDC *antialiassingDC) override;
112
113 const wxString GetToolTip(wxPoint point) const override;
114 Range GetInnerCellsInRect(const wxRect &rect) const override;
115
130 std::optional<MatrixBlock> BlockInRect(const wxRect &rect) const;
132 bool IsWholeMatrix(const MatrixBlock &block) const;
138 wxRect BlockRect(const MatrixBlock &block) const;
148 MatrixEntry StepEntry(const MatrixEntry &entry, int rowStep,
149 int colStep) const;
157 std::unique_ptr<MatrCell> CopyBlock(const MatrixBlock &block,
158 GroupCell *group) const;
160
162 size_t GetMatrixRows() const { return m_matHeight; }
164 size_t GetMatrixColumns() const { return m_matWidth; }
165
167 bool IsElided(size_t row, size_t col) const
168 { return m_rowElision.Hides(row) || m_colElision.Hides(col); }
178 bool EntryAt(wxPoint point, size_t &row, size_t &col) const;
180 size_t ElidedColumns() const { return m_colElision.count; }
182 size_t ElidedRows() const { return m_rowElision.count; }
183
193 bool HasHorizontalScrollbar() const { return m_hasHorizontalScrollbar; }
195 bool HasVerticalScrollbar() const { return m_hasVerticalScrollbar; }
197 wxRect HorizontalScrollbarRect() const;
199 wxRect VerticalScrollbarRect() const;
201 wxRect ViewportRect() const;
203 wxSize ScrollableSize() const { return m_scrollableSize; }
205 wxSize ViewportSize() const { return m_contentSize; }
207 wxPoint ScrollPosition() const { return m_scroll; }
213 bool ScrollTo(wxPoint position);
221 bool ScrollEntryIntoView(size_t row, size_t col);
223 bool IsNestedInMatrix() const { return m_nestedInMatrix; }
226 void AddNewCell(std::unique_ptr<Cell> &&cell);
227
228 void NewRow() { m_matHeight++; m_dropCenters.emplace_back(-1, -1);}
229 void NewColumn() { m_matWidth++; m_widths.emplace_back(-1);}
230
231 void SetDimension();
232
233 wxString ToMathML() const override;
234 wxString ToMatlab() const override;
243 wxString ToCSV(const wxString &delimiter) const;
244 wxString ToOMML() const override;
245 wxString ToString() const override;
246 wxString ToTeX() const override;
247 wxString ToXML() const override;
248
249 void SetSpecialFlag(bool special) { m_specialMatrix = special; }
250
251 void SetInferenceFlag(bool inference) { m_inferenceMatrix = inference; }
252
253 void RowNames(bool rn) { m_rowNames = rn; }
254
255 void ColNames(bool cn) { m_colNames = cn; }
256
257 void RoundedParens() { m_parenType = paren_rounded;}
258 void BracketParens() { m_parenType = paren_brackets;}
259 void StraightParens() { m_parenType = paren_straight;}
260 void AngledParens() { m_parenType = paren_angled;}
261 void NoParens() { m_parenType = paren_none;}
262
271 void SetOversizedMode(std::optional<Configuration::OversizedMatrices> mode) {
272 m_oversizedMode = mode ? static_cast<uint8_t>(*mode) : oversizedFollowConfig;
273 }
275 std::optional<Configuration::OversizedMatrices> GetOversizedMode() const {
276 if (m_oversizedMode == oversizedFollowConfig)
277 return std::nullopt;
278 return static_cast<Configuration::OversizedMatrices>(m_oversizedMode);
279 }
283 static std::optional<Configuration::OversizedMatrices>
284 OversizedModeFromName(const wxString &name);
285
286private:
287 struct DropCenter
288 {
289 int drop = {}, center = {};
290 constexpr int Sum() const { return drop + center; }
291 constexpr DropCenter() = default;
292 constexpr DropCenter(int drop, int center) : drop(drop), center(center) {}
293 };
294
296 struct Elision
297 {
299 size_t first = 0;
301 size_t count = 0;
302 constexpr bool Active() const { return count > 0; }
303 constexpr bool Hides(size_t index) const
304 { return (index >= first) && (index < first + count); }
305 };
306
318 static Elision ChooseElision(const std::vector<wxCoord> &sizes,
319 wxCoord gapSize, wxCoord budget);
320
322 wxCoord ElementSkip() const {return Scale_Px(5);}
324 wxCoord DotsSkip() const {return Scale_Px(20);}
326 wxCoord DotPitch() const;
328 wxCoord DotRadius() const;
330 wxCoord DotsExtent() const { return 2 * DotPitch() + 2 * DotRadius(); }
332 wxCoord DotsGap() const {return DotsExtent() + DotsSkip() * 2;}
334 void DrawDots(wxDC *dc, wxPoint start, wxPoint step) const;
336 void DrawElisionMarks(wxDC *dc) const;
351 void DrawBands(wxDC *dc) const;
352public:
358 bool IsShownPartially() const
359 { return m_colElision.Active() || m_rowElision.Active() || IsScrolling(); }
365 bool IsBanded() const {
366 if (const auto banding = GetBanding())
367 return *banding;
368 return m_alwaysBanded || IsShownPartially();
369 }
376 void SetBanding(std::optional<bool> banding) {
377 m_banding = !banding ? bandingAuto : (*banding ? bandingOn : bandingOff);
378 }
380 std::optional<bool> GetBanding() const {
381 if (m_banding == bandingAuto)
382 return std::nullopt;
383 return m_banding == bandingOn;
384 }
390 void AlwaysBanded(bool banded) { m_alwaysBanded = banded; }
391private:
393 bool IsScrolling() const
394 { return m_hasHorizontalScrollbar || m_hasVerticalScrollbar; }
396 bool IsEntryShown(size_t row, size_t col) const;
398 wxRect EntrySlotRect(size_t row, size_t col) const;
400 void ClampScrollPosition() const;
402 static void MarkNestedMatrices(Cell *list);
403
405 std::vector<std::unique_ptr<Cell>> m_cells;
406
407 mutable std::vector<wxCoord> m_widths;
408 mutable std::vector<DropCenter> m_dropCenters;
409
416 mutable wxSize m_contentSize;
418 mutable wxSize m_scrollableSize;
420 mutable wxPoint m_scroll;
422 mutable wxCoord m_scrollbarThickness = 0;
423
425 mutable Elision m_colElision;
427 mutable Elision m_rowElision;
428
429 size_t m_matWidth = 0;
430 size_t m_matHeight = 0;
431
432 enum parenType : int8_t
433 {
434 paren_rounded = 0,
435 paren_brackets = 1,
436 paren_angled = 2,
437 paren_straight = 3,
438 paren_none = 4
439 };
440//** Bitfield objects (1 bytes)
441//**
442 uint8_t m_parenType : 3 = paren_rounded;
444 static constexpr uint8_t oversizedFollowConfig = 3;
445 static_assert(static_cast<uint8_t>(Configuration::OversizedMatrices::scroll) <
446 oversizedFollowConfig,
447 "m_oversizedMode is too narrow for OversizedMatrices");
449 uint8_t m_oversizedMode : 2 = oversizedFollowConfig;
450 bool m_specialMatrix : 1 = false;
451 bool m_inferenceMatrix : 1 = false;
452 bool m_rowNames : 1 = false;
453 bool m_colNames : 1 = false;
455 bool m_nestedInMatrix : 1 = false;
457 bool m_alwaysBanded : 1 = false;
459 static constexpr uint8_t bandingAuto = 0, bandingOn = 1, bandingOff = 2;
461 uint8_t m_banding : 2 = bandingAuto;
462 mutable bool m_hasHorizontalScrollbar : 1 = false;
463 mutable bool m_hasVerticalScrollbar : 1 = false;
464};
465
466#endif // MATRCELL_H
The definition of the base class of all cells the worksheet consists of.
int group
Neighbouring sections of the same group aren't separated.
Definition: ToolBarSections.cpp:45
A Type-Safe Fixed-Point Font Size.
Definition: FontAttribs.h:99
A class that carries information about the type of a cell.
Definition: Cell.h:93
The base class all cell types the worksheet can consist of are derived from.
Definition: Cell.h:148
wxCoord Scale_Px(double px) const
Scale font sizes and line widths according to the zoom factor.
Definition: Cell.h:182
virtual void SetCurrentPoint(wxPoint point) const
Pass 2: Arrangement.
Definition: Cell.cpp:526
The configuration storage for the current worksheet.
Definition: Configuration.h:101
OversizedMatrices
How to show a matrix too large for the window.
Definition: Configuration.h:517
@ scroll
Show a window-sized part of it, with native scrollbars.
A cell grouping input (and, if there is one, also the output) cell to a foldable item.
Definition: GroupCell.h:88
A Cell that displays a matrix.
Definition: MatrCell.h:95
size_t ElidedColumns() const
How many columns are left out of the display (0 = none)
Definition: MatrCell.h:180
std::optional< Configuration::OversizedMatrices > GetOversizedMode() const
The mode SetOversizedMode() asked for, if any.
Definition: MatrCell.h:275
wxString ToString() const override
Returns the cell's representation as a string.
Definition: MatrCell.cpp:955
const CellTypeInfo & GetInfo() override
Returns the information about this cell's type.
size_t GetMatrixRows() const
How many rows the matrix has.
Definition: MatrCell.h:162
wxRect BlockRect(const MatrixBlock &block) const
Where the shown part of a block is drawn, e.g.
Definition: MatrCell.cpp:688
size_t GetInnerCellCount() const override
The number of inner cells - for use by the iterators.
Definition: MatrCell.h:102
static wxString OversizedModeName(Configuration::OversizedMatrices mode)
The name wx_matrix() and the XML use for an oversized-matrix mode.
Definition: MatrCell.cpp:912
wxPoint ScrollPosition() const
How far the matrix is scrolled.
Definition: MatrCell.h:207
wxString ToXML() const override
Convert this cell to a representation fit for saving in a .wxmx file.
Definition: MatrCell.cpp:1166
wxString ToOMML() const override
Returns the cell's representation as OMML.
Definition: MatrCell.cpp:1118
bool IsWholeMatrix(const MatrixBlock &block) const
Is this block every entry of the matrix?
Definition: MatrCell.cpp:683
bool IsBanded() const
Does this matrix get alternating row/column bands? See DrawBands().
Definition: MatrCell.h:365
wxSize ScrollableSize() const
The size of the whole matrix, as it would be drawn without scrolling.
Definition: MatrCell.h:203
wxString ToCSV(const wxString &delimiter) const
The matrix as comma- (or tab-, ...) separated values (GH #2364)
Definition: MatrCell.cpp:993
wxString ToMathML() const override
Convert this cell to a representation fit for saving in a .wxmx file.
Definition: MatrCell.cpp:1063
Cell * GetInnerCell(size_t index) const override
Retrieve an inner cell with given index which must be less than GetInnerCellCount.
Definition: MatrCell.h:103
void SetCurrentPoint(wxPoint point) const override
Pass 2: Arrangement.
Definition: MatrCell.cpp:491
void Recalculate(const AFontSize fontsize) const override
Recalculate the size of the cell and the difference between top and center.
Definition: MatrCell.cpp:69
wxString ToTeX() const override
Convert this cell to its LaTeX representation.
Definition: MatrCell.cpp:1015
bool ScrollEntryIntoView(size_t row, size_t col)
Scrolls just far enough that an entry is inside the viewport (GH #2380)
Definition: MatrCell.cpp:281
size_t ElidedRows() const
How many rows are left out of the display (0 = none)
Definition: MatrCell.h:182
bool IsShownPartially() const
Does the worksheet show only part of this matrix right now?
Definition: MatrCell.h:358
bool EntryAt(wxPoint point, size_t &row, size_t &col) const
Which entry's slot is at this point?
Definition: MatrCell.cpp:524
static std::optional< Configuration::OversizedMatrices > OversizedModeFromName(const wxString &name)
Parses OversizedModeName()'s output; std::nullopt if it isn't one.
Definition: MatrCell.cpp:927
Range GetInnerCellsInRect(const wxRect &rect) const override
Select the cells inside this cell described by the rectangle rect.
Definition: MatrCell.cpp:635
std::unique_ptr< MatrCell > CopyBlock(const MatrixBlock &block, GroupCell *group) const
A new matrix holding only this block of entries.
Definition: MatrCell.cpp:720
size_t GetMatrixColumns() const
How many columns the matrix has.
Definition: MatrCell.h:164
bool IsNestedInMatrix() const
Does this matrix sit inside another matrix? Only the outermost one scrolls.
Definition: MatrCell.h:223
bool IsElided(size_t row, size_t col) const
Is the entry in this row and column left out of the display?
Definition: MatrCell.h:167
std::unique_ptr< Cell > Copy(GroupCell *group) const override
Create a copy of this cell.
void AlwaysBanded(bool banded)
Band this matrix even if it is shown in full.
Definition: MatrCell.h:390
const wxString GetToolTip(wxPoint point) const override
Returns the ToolTip this cell provides at a given point.
Definition: MatrCell.cpp:568
bool HasHorizontalScrollbar() const
Does this matrix show a horizontal scrollbar?
Definition: MatrCell.h:193
wxRect ViewportRect() const
The part of the worksheet the matrix's entries are shown in.
Definition: MatrCell.cpp:299
bool ScrollTo(wxPoint position)
Scrolls the matrix, clamped to its scrollable range.
Definition: MatrCell.cpp:257
void Draw(wxDC *dc, wxDC *antialiassingDC) override
Pass 3 (Paint): Renders the cell using pre-calculated coordinates.
Definition: MatrCell.cpp:749
wxSize ViewportSize() const
The size of the viewport onto it, brackets' margins included.
Definition: MatrCell.h:205
MatrixEntry StepEntry(const MatrixEntry &entry, int rowStep, int colStep) const
The entry one step away from this one, for Shift+arrow keys (GH #2370)
Definition: MatrCell.cpp:700
std::optional< bool > GetBanding() const
What SetBanding() asked for, if anything.
Definition: MatrCell.h:380
wxString ToMatlab() const override
Convert this cell to its Matlab representation.
Definition: MatrCell.cpp:973
wxRect VerticalScrollbarRect() const
Where the vertical scrollbar belongs; empty if there is none.
Definition: MatrCell.cpp:315
wxRect HorizontalScrollbarRect() const
Where the horizontal scrollbar belongs; empty if there is none.
Definition: MatrCell.cpp:308
std::optional< MatrixBlock > BlockInRect(const wxRect &rect) const
The block of shown entries a rectangle touches.
Definition: MatrCell.cpp:665
bool HasVerticalScrollbar() const
Does this matrix show a vertical scrollbar?
Definition: MatrCell.h:195
void SetBanding(std::optional< bool > banding)
Force alternating bands on (true) or off (false), or std::nullopt to decide by size.
Definition: MatrCell.h:376
void SetOversizedMode(std::optional< Configuration::OversizedMatrices > mode)
How this matrix wants to be shown if it is too large for the window.
Definition: MatrCell.h:271
A rectangular block of a matrix's entries: a sub-matrix (GH #2345)
Definition: MatrixBlock.h:47
One entry of a matrix, by its zero-based row and column.
Definition: MatrixBlock.h:30