mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 16:57:31 +01:00
In SelectableTableView::selectCellAtLocation, we call 'tableViewDidChangeSelection'
before scrolling. Therefore, the cell with updated with the right selected subview
is not the one drawn... To solve this issue, we keep the selectedSubview ('model')
in the HistoryController instead of in the limited-lifespan view.
167 lines
6.3 KiB
C++
167 lines
6.3 KiB
C++
#include "history_view_cell.h"
|
|
#include "app.h"
|
|
#include "../constant.h"
|
|
#include "selectable_table_view.h"
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
namespace Calculation {
|
|
|
|
/* HistoryViewCellDataSource */
|
|
|
|
HistoryViewCellDataSource::HistoryViewCellDataSource() :
|
|
m_selectedSubviewType(HistoryViewCellDataSource::SubviewType::Output) {}
|
|
|
|
void HistoryViewCellDataSource::setSelectedSubviewType(HistoryViewCellDataSource::SubviewType subviewType, HistoryViewCell * cell) {
|
|
m_selectedSubviewType = subviewType;
|
|
if (cell) {
|
|
cell->setHighlighted(cell->isHighlighted());
|
|
}
|
|
}
|
|
|
|
/* HistoryViewCell */
|
|
|
|
HistoryViewCell::HistoryViewCell(Responder * parentResponder) :
|
|
Responder(parentResponder),
|
|
m_calculation(),
|
|
m_inputLayout(),
|
|
m_leftOutputLayout(),
|
|
m_rightOutputLayout(),
|
|
m_inputView(this),
|
|
m_scrollableOutputView(this)
|
|
{
|
|
}
|
|
|
|
Shared::ScrollableExactApproximateExpressionsView * HistoryViewCell::outputView() {
|
|
return &m_scrollableOutputView;
|
|
}
|
|
|
|
void HistoryViewCell::setEven(bool even) {
|
|
EvenOddCell::setEven(even);
|
|
m_inputView.setBackgroundColor(backgroundColor());
|
|
m_scrollableOutputView.evenOddCell()->setEven(even);
|
|
}
|
|
|
|
void HistoryViewCell::setHighlighted(bool highlight) {
|
|
assert(m_dataSource);
|
|
m_highlighted = highlight;
|
|
m_inputView.setBackgroundColor(backgroundColor());
|
|
m_scrollableOutputView.evenOddCell()->setHighlighted(false);
|
|
if (isHighlighted()) {
|
|
if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) {
|
|
m_inputView.setBackgroundColor(Palette::Select);
|
|
} else {
|
|
m_scrollableOutputView.evenOddCell()->setHighlighted(true);
|
|
}
|
|
}
|
|
reloadScroll();
|
|
}
|
|
|
|
Poincare::Layout HistoryViewCell::layout() const {
|
|
assert(m_dataSource);
|
|
if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) {
|
|
return m_inputLayout;
|
|
} else {
|
|
return m_scrollableOutputView.layout();
|
|
}
|
|
}
|
|
|
|
void HistoryViewCell::reloadCell() {
|
|
m_scrollableOutputView.evenOddCell()->reloadCell();
|
|
layoutSubviews();
|
|
reloadScroll();
|
|
}
|
|
|
|
void HistoryViewCell::reloadScroll() {
|
|
m_inputView.reloadScroll();
|
|
m_scrollableOutputView.reloadScroll();
|
|
}
|
|
|
|
KDColor HistoryViewCell::backgroundColor() const {
|
|
KDColor background = m_even ? KDColorWhite : Palette::WallScreen;
|
|
return background;
|
|
}
|
|
|
|
|
|
int HistoryViewCell::numberOfSubviews() const {
|
|
return 2;
|
|
}
|
|
|
|
View * HistoryViewCell::subviewAtIndex(int index) {
|
|
View * views[2] = {&m_inputView, &m_scrollableOutputView};
|
|
return views[index];
|
|
}
|
|
|
|
void HistoryViewCell::layoutSubviews() {
|
|
KDCoordinate width = bounds().width();
|
|
KDCoordinate height = bounds().height();
|
|
KDSize inputSize = m_inputView.minimalSizeForOptimalDisplay();
|
|
if (inputSize.width() + Metric::HistoryHorizontalMargin > width) {
|
|
m_inputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, k_digitVerticalMargin, width - Metric::HistoryHorizontalMargin, inputSize.height()));
|
|
} else {
|
|
m_inputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, k_digitVerticalMargin, inputSize.width(), inputSize.height()));
|
|
}
|
|
KDSize outputSize = m_scrollableOutputView.minimalSizeForOptimalDisplay();
|
|
if (outputSize.width() + Metric::HistoryHorizontalMargin > width) {
|
|
m_scrollableOutputView.setFrame(KDRect(Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, width - Metric::HistoryHorizontalMargin, height - inputSize.height() - 3*k_digitVerticalMargin));
|
|
} else {
|
|
m_scrollableOutputView.setFrame(KDRect(width - outputSize.width() - Metric::HistoryHorizontalMargin, inputSize.height() + 2*k_digitVerticalMargin, outputSize.width(), height - inputSize.height() - 3*k_digitVerticalMargin));
|
|
}
|
|
}
|
|
|
|
void HistoryViewCell::setCalculation(Calculation * calculation) {
|
|
if (*calculation == m_calculation) {
|
|
return;
|
|
}
|
|
m_calculation = *calculation;
|
|
m_inputLayout = calculation->createInputLayout();
|
|
m_inputView.setLayout(m_inputLayout);
|
|
App * calculationApp = (App *)app();
|
|
/* Both output expressions have to be updated at the same time. Otherwise,
|
|
* when updating one layout, if the second one still points to a deleted
|
|
* layout, calling to layoutSubviews() would fail. */
|
|
if (!m_leftOutputLayout.isUninitialized()) {
|
|
m_leftOutputLayout = Poincare::Layout();
|
|
}
|
|
if (!m_rightOutputLayout.isUninitialized()) {
|
|
m_rightOutputLayout = Poincare::Layout();
|
|
}
|
|
if (calculation->shouldOnlyDisplayExactOutput()) {
|
|
m_rightOutputLayout = calculation->createExactOutputLayout();
|
|
} else {
|
|
m_rightOutputLayout = calculation->createApproximateOutputLayout(calculationApp->localContext());
|
|
if (!calculation->shouldOnlyDisplayApproximateOutput(calculationApp->localContext())) {
|
|
m_leftOutputLayout = calculation->createExactOutputLayout();
|
|
}
|
|
}
|
|
m_scrollableOutputView.setLayouts(m_rightOutputLayout, m_leftOutputLayout);
|
|
I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(calculationApp->localContext()) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual;
|
|
m_scrollableOutputView.setEqualMessage(equalMessage);
|
|
}
|
|
|
|
void HistoryViewCell::didBecomeFirstResponder() {
|
|
assert(m_dataSource);
|
|
if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) {
|
|
app()->setFirstResponder(&m_inputView);
|
|
} else {
|
|
app()->setFirstResponder(&m_scrollableOutputView);
|
|
}
|
|
}
|
|
|
|
bool HistoryViewCell::handleEvent(Ion::Events::Event event) {
|
|
assert(m_dataSource);
|
|
if ((event == Ion::Events::Down && m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) ||
|
|
(event == Ion::Events::Up && m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Output)) {
|
|
HistoryViewCellDataSource::SubviewType otherSubviewType = m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input ? HistoryViewCellDataSource::SubviewType::Output : HistoryViewCellDataSource::SubviewType::Input;
|
|
CalculationSelectableTableView * tableView = (CalculationSelectableTableView *)parentResponder();
|
|
tableView->scrollToSubviewOfTypeOfCellAtLocation(otherSubviewType, tableView->selectedColumn(), tableView->selectedRow());
|
|
HistoryViewCell * selectedCell = (HistoryViewCell *)(tableView->selectedCell());
|
|
m_dataSource->setSelectedSubviewType(otherSubviewType, selectedCell);
|
|
app()->setFirstResponder(selectedCell);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|