mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[Update] Epsilon 14
This commit is contained in:
@@ -66,6 +66,7 @@ escher_src += $(addprefix escher/src/,\
|
||||
message_text_view.cpp \
|
||||
metric.cpp \
|
||||
modal_view_controller.cpp \
|
||||
modal_view_empty_controller.cpp \
|
||||
nested_menu_controller.cpp \
|
||||
palette.cpp \
|
||||
pointer_text_view.cpp \
|
||||
|
||||
@@ -87,11 +87,7 @@ private:
|
||||
bool selectionIsEmpty() const;
|
||||
void deleteSelection();
|
||||
void invalidateInsertionCursor() { m_insertionCursor = Poincare::LayoutCursor(); }
|
||||
void updateInsertionCursor() {
|
||||
if (!m_insertionCursor.isDefined()) {
|
||||
m_insertionCursor = m_cursor;
|
||||
}
|
||||
}
|
||||
void updateInsertionCursor();
|
||||
|
||||
private:
|
||||
int numberOfSubviews() const override { return 2; }
|
||||
|
||||
@@ -13,8 +13,12 @@ public:
|
||||
void setMessage(I18n::Message message);
|
||||
virtual void setTextColor(KDColor color);
|
||||
void setMessageFont(const KDFont * font);
|
||||
void setBackgroundColor(KDColor color);
|
||||
protected:
|
||||
KDColor backgroundColor() const override { return m_backgroundColor; }
|
||||
private:
|
||||
MessageTextView m_messageTextView;
|
||||
KDColor m_backgroundColor;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
m_numberOfChildren(numberOfChildren)
|
||||
{
|
||||
};
|
||||
virtual const MessageTree * children(int index) const = 0;
|
||||
virtual const MessageTree * childAtIndex(int index) const = 0;
|
||||
I18n::Message label() const { return m_label; }
|
||||
int numberOfChildren() const { return m_numberOfChildren; }
|
||||
bool isNull() const { return (m_label == (I18n::Message)0); }
|
||||
|
||||
37
escher/include/escher/modal_view_empty_controller.h
Normal file
37
escher/include/escher/modal_view_empty_controller.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef ESCHER_EMPTY_MODAL_VIEW_EMPTY_CONTROLLER_H
|
||||
#define ESCHER_EMPTY_MODAL_VIEW_EMPTY_CONTROLLER_H
|
||||
|
||||
#include <escher/bordered.h>
|
||||
#include <escher/expression_view.h>
|
||||
#include <escher/message_text_view.h>
|
||||
#include <escher/view_controller.h>
|
||||
|
||||
class ModalViewEmptyController : public ViewController {
|
||||
public:
|
||||
ModalViewEmptyController() : ViewController(nullptr) {}
|
||||
void setMessages(I18n::Message * messages);
|
||||
// View Controller
|
||||
DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
|
||||
protected:
|
||||
class ModalViewEmptyView : public View, public Bordered {
|
||||
public:
|
||||
constexpr static const KDFont * k_font = KDFont::SmallFont;
|
||||
void initMessageViews();
|
||||
void setMessages(I18n::Message * message);
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
private:
|
||||
constexpr static int k_expressionViewRowIndex = 2;
|
||||
constexpr static KDColor k_backgroundColor = Palette::WallScreen;
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews(bool force = false) override;
|
||||
virtual int numberOfMessageTextViews() const = 0;
|
||||
virtual MessageTextView * messageTextViewAtIndex(int index) = 0;
|
||||
bool hasExpressionView() const {
|
||||
return const_cast<ModalViewEmptyView *>(this)->expressionView() != nullptr;
|
||||
}
|
||||
virtual ExpressionView * expressionView() { return nullptr; }
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -7,10 +7,11 @@
|
||||
#include <escher/selectable_table_view.h>
|
||||
#include <escher/stack_view_controller.h>
|
||||
|
||||
class NestedMenuController : public StackViewController, public ListViewDataSource, public SelectableTableViewDataSource {
|
||||
class NestedMenuController : public StackViewController, public ListViewDataSource, public SelectableTableViewDataSource, public SelectableTableViewDelegate {
|
||||
public:
|
||||
NestedMenuController(Responder * parentResponder, I18n::Message title = (I18n::Message)0);
|
||||
void setSender(InputEventHandler * sender) { m_sender = sender; }
|
||||
void setTitle(I18n::Message title);
|
||||
|
||||
// StackViewController
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
@@ -48,6 +49,7 @@ protected:
|
||||
public:
|
||||
ListController(Responder * parentResponder, SelectableTableView * tableView, I18n::Message title);
|
||||
const char * title() override;
|
||||
void setTitle(I18n::Message title) { m_title = title; }
|
||||
View * view() override;
|
||||
void didBecomeFirstResponder() override;
|
||||
void setFirstSelectedRow(int firstSelectedRow);
|
||||
|
||||
150
escher/include/escher/palette.h
Normal file
150
escher/include/escher/palette.h
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifndef ESCHER_PALETTE_H
|
||||
#define ESCHER_PALETTE_H
|
||||
|
||||
#include <kandinsky/color.h>
|
||||
#include <stddef.h>
|
||||
|
||||
class Palette {
|
||||
public:
|
||||
constexpr static KDColor PrimaryText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor SecondaryText = KDColor::RGB24(0x6e6e6e);
|
||||
constexpr static KDColor AccentText = KDColor::RGB24(0x00857f);
|
||||
constexpr static KDColor ApproximateSignText = KDColor::RGB24(0x595959);
|
||||
constexpr static KDColor ApproximateExpressionText = KDColor::RGB24(0x595959);
|
||||
constexpr static KDColor BackgroundHard = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor BackgroundApps = KDColor::RGB24(0xfafafa);
|
||||
constexpr static KDColor BackgroundAppsSecondary = KDColor::RGB24(0xf0f0f0);
|
||||
constexpr static KDColor Toolbar = KDColor::RGB24(0xc03535);
|
||||
constexpr static KDColor ToolbarText = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor ExpressionInputBackground = KDColor::RGB24(0xe0e0e0);
|
||||
constexpr static KDColor ExpressionInputBorder = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor GridPrimaryLine = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor GridSecondaryLine = KDColor::RGB24(0xf5f5f5);
|
||||
constexpr static KDColor Battery = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor BatteryInCharge = KDColor::RGB24(0x179e1f);
|
||||
constexpr static KDColor BatteryLow = KDColor::RGB24(0x992321);
|
||||
constexpr static KDColor ScrollBarForeground = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor ScrollBarBackground = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor Control = KDColor::RGB24(0x00857f);
|
||||
constexpr static KDColor ControlEnabled = KDColor::RGB24(0x00b2b0);
|
||||
constexpr static KDColor ControlDisabled = KDColor::RGB24(0x9e9e9e);
|
||||
constexpr static KDColor CalculationBackgroundOdd = KDColor::RGB24(0xfafafa);
|
||||
constexpr static KDColor CalculationBackgroundEven = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor CalculationEmptyBox = KDColor::RGB24(0xc4c4c4);
|
||||
constexpr static KDColor CalculationEmptyBoxNeeded = KDColor::RGB24(0x00857f);
|
||||
constexpr static KDColor CalculationTrigoAndComplexForeground = KDColor::RGB24(0xff000c);
|
||||
constexpr static KDColor CodeBackground = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor CodeBackgroundSelected = KDColor::RGB24(0xe0e0e0);
|
||||
constexpr static KDColor CodeText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor CodeComment = KDColor::RGB24(0x999988);
|
||||
constexpr static KDColor CodeNumber = KDColor::RGB24(0x009999);
|
||||
constexpr static KDColor CodeKeyword = KDColor::RGB24(0xff000c);
|
||||
constexpr static KDColor CodeOperator = KDColor::RGB24(0xd73a49);
|
||||
constexpr static KDColor CodeString = KDColor::RGB24(0x032f62);
|
||||
constexpr static KDColor CodeGutterViewBackground = KDColor::RGB24(0xE4E6E7);
|
||||
constexpr static KDColor ProbabilityCurve = KDColor::RGB24(0x00857f);
|
||||
constexpr static KDColor ProbabilityCellBorder = KDColor::RGB24(0xececec);
|
||||
constexpr static KDColor ProbabilityHistogramBar = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor StatisticsBox = KDColor::RGB24(0x00857f);
|
||||
constexpr static KDColor StatisticsBoxVerticalLine = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor StatisticsSelected = KDColor::RGB24(0x00857f);
|
||||
constexpr static KDColor StatisticsNotSelected = KDColor::RGB24(0xf5f5f5);
|
||||
constexpr static KDColor GraphTangent = KDColor::RGB24(0x595959);
|
||||
constexpr static KDColor SubMenuBackground = KDColor::RGB24(0xe0e0e0);
|
||||
constexpr static KDColor SubMenuBorder = KDColor::RGB24(0xfafafa);
|
||||
constexpr static KDColor SubMenuText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor ToolboxHeaderBackground = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor ToolboxHeaderText = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor ToolboxHeaderBorder = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor ToolboxBackground = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor ListCellBackground = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor ListCellBackgroundSelected = KDColor::RGB24(0xe0e0e0);
|
||||
constexpr static KDColor ListCellBorder = KDColor::RGB24(0xededef);
|
||||
constexpr static KDColor ButtonBackground = KDColor::RGB24(0xe6e6e6);
|
||||
constexpr static KDColor ButtonBackgroundSelected = KDColor::RGB24(0xc9c9c9);
|
||||
constexpr static KDColor ButtonBackgroundSelectedHighContrast = KDColor::RGB24(0x00b2b0);
|
||||
constexpr static KDColor ButtonBorder = KDColor::RGB24(0xadadad);
|
||||
constexpr static KDColor ButtonRowBorder = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor ButtonBorderOut = KDColor::RGB24(0xf5f5f5);
|
||||
constexpr static KDColor ButtonShadow = KDColor::RGB24(0x003833);
|
||||
constexpr static KDColor ButtonText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor TabBackground = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor TabBackgroundSelected = KDColor::RGB24(0x757575);
|
||||
constexpr static KDColor TabBackgroundActive = KDColor::RGB24(0xfafafa);
|
||||
constexpr static KDColor TabBackgroundSelectedAndActive = KDColor::RGB24(0xe3e3e3);
|
||||
constexpr static KDColor TabText = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor TabTextActive = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor SubTabBackground = KDColor::RGB24(0xe0e0e0);
|
||||
constexpr static KDColor SubTabBackgroundSelected = KDColor::RGB24(0xd1d1d1);
|
||||
constexpr static KDColor SubTabText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor BannerFirstBackground = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor BannerFirstBorder = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor BannerFirstText = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor BannerFirstVariantBackground = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor BannerFirstVariantBorder = KDColor::RGB24(0xfafafa);
|
||||
constexpr static KDColor BannerFirstVariantText = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor BannerSecondBackground = KDColor::RGB24(0xe0e0e0);
|
||||
constexpr static KDColor BannerSecondBorder = KDColor::RGB24(0xfafafa);
|
||||
constexpr static KDColor BannerSecondText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor HomeBackground = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor HomeCellBackground = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor HomeCellBackgroundActive = KDColor::RGB24(0x4a4a4a);
|
||||
constexpr static KDColor HomeCellText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor HomeCellTextActive = KDColor::RGB24(0xffffff);
|
||||
constexpr static KDColor HomeCellTextExternal = KDColor::RGB24(0x008f87);
|
||||
constexpr static KDColor HomeCellTextExternalActive = KDColor::RGB24(0x6fe6df);
|
||||
constexpr static KDColor AtomUnknown = KDColor::RGB24(0xeeeeee);
|
||||
constexpr static KDColor AtomText = KDColor::RGB24(0x000000);
|
||||
constexpr static KDColor AtomAlkaliMetal = KDColor::RGB24(0xffaa00);
|
||||
constexpr static KDColor AtomAlkaliEarthMetal = KDColor::RGB24(0xf6f200);
|
||||
constexpr static KDColor AtomLanthanide = KDColor::RGB24(0xffaa8b);
|
||||
constexpr static KDColor AtomActinide = KDColor::RGB24(0xdeaacd);
|
||||
constexpr static KDColor AtomTransitionMetal = KDColor::RGB24(0xde999c);
|
||||
constexpr static KDColor AtomPostTransitionMetal = KDColor::RGB24(0x9cbaac);
|
||||
constexpr static KDColor AtomMetalloid = KDColor::RGB24(0x52ce8b);
|
||||
constexpr static KDColor AtomHalogen = KDColor::RGB24(0x00debd);
|
||||
constexpr static KDColor AtomReactiveNonmetal = KDColor::RGB24(0x00ee00);
|
||||
constexpr static KDColor AtomNobleGas = KDColor::RGB24(0x8baaff);
|
||||
constexpr static KDColor AtomTableLines = KDColor::RGB24(0x323532);
|
||||
constexpr static KDColor YellowDark = KDColor::RGB24(0xffb734);
|
||||
constexpr static KDColor YellowLight = KDColor::RGB24(0xffcc7b);
|
||||
constexpr static KDColor PurpleBright = KDColor::RGB24(0x656975);
|
||||
constexpr static KDColor PurpleDark = KDColor::RGB24(0x414147);
|
||||
constexpr static KDColor GreyWhite = KDColor::RGB24(0xf5f5f5);
|
||||
constexpr static KDColor GreyBright = KDColor::RGB24(0xececec);
|
||||
constexpr static KDColor GreyMiddle = KDColor::RGB24(0xd9d9d9);
|
||||
constexpr static KDColor GreyDark = KDColor::RGB24(0xa7a7a7);
|
||||
constexpr static KDColor GreyVeryDark = KDColor::RGB24(0x8c8c8c);
|
||||
constexpr static KDColor Select = KDColor::RGB24(0xd4d7e0);
|
||||
constexpr static KDColor SelectDark = KDColor::RGB24(0xb0b8d8);
|
||||
constexpr static KDColor WallScreen = KDColor::RGB24(0xf7f9fa);
|
||||
constexpr static KDColor WallScreenDark = KDColor::RGB24(0xe0e6ed);
|
||||
constexpr static KDColor SubTab = KDColor::RGB24(0xb8bbc5);
|
||||
constexpr static KDColor LowBattery = KDColor::RGB24(0xf30211);
|
||||
constexpr static KDColor Red = KDColor::RGB24(0xff000c);
|
||||
constexpr static KDColor RedLight = KDColor::RGB24(0xfe6363);
|
||||
constexpr static KDColor Magenta = KDColor::RGB24(0xff0588);
|
||||
constexpr static KDColor Turquoise = KDColor::RGB24(0x60c1ec);
|
||||
constexpr static KDColor Pink = KDColor::RGB24(0xffabb6);
|
||||
constexpr static KDColor Blue = KDColor::RGB24(0x5075f2);
|
||||
constexpr static KDColor BlueLight = KDColor::RGB24(0x718fee);
|
||||
constexpr static KDColor Orange = KDColor::RGB24(0xfe871f);
|
||||
constexpr static KDColor Green = KDColor::RGB24(0x50c102);
|
||||
constexpr static KDColor GreenLight = KDColor::RGB24(0x52db8f);
|
||||
constexpr static KDColor Brown = KDColor::RGB24(0x8d7350);
|
||||
constexpr static KDColor Purple = KDColor::RGB24(0x6e2d79);
|
||||
constexpr static KDColor BlueishGrey = KDColor::RGB24(0x919ea4);
|
||||
constexpr static KDColor Cyan = KDColorBlue;
|
||||
constexpr static KDColor DataColor[] = {Red, Blue, Green, YellowDark, Magenta, Turquoise, Pink, Orange};
|
||||
constexpr static KDColor DataColorLight[] = {RedLight, BlueLight, GreenLight, YellowLight};
|
||||
constexpr static KDColor AtomColor[] = {
|
||||
AtomUnknown, AtomAlkaliMetal, AtomAlkaliEarthMetal, AtomLanthanide, AtomActinide, AtomTransitionMetal,
|
||||
AtomPostTransitionMetal, AtomMetalloid, AtomHalogen, AtomReactiveNonmetal, AtomNobleGas
|
||||
};
|
||||
|
||||
constexpr static size_t numberOfDataColors() { return sizeof(DataColor)/sizeof(KDColor); }
|
||||
constexpr static size_t numberOfLightDataColors() { return sizeof(DataColorLight)/sizeof(KDColor); }
|
||||
static KDColor nextDataColor(int * colorIndex);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
* the previous selected cell. We might implement different course of action
|
||||
* when the selection change is 'real' or within temporary selection. */
|
||||
virtual void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection = false) {}
|
||||
virtual void tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection = false) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,8 @@ public:
|
||||
void push(ViewController * vc, KDColor textColor = Palette::SubMenuText, KDColor backgroundColor = Palette::SubMenuBackground, KDColor separatorColor = Palette::SubMenuBorder);
|
||||
void pop();
|
||||
|
||||
int depth();
|
||||
View * view() override;
|
||||
int depth() const { return m_numberOfChildren; }
|
||||
View * view() override { return &m_view; }
|
||||
ViewController * topViewController();
|
||||
const char * title() override;
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
|
||||
@@ -23,8 +23,9 @@ public:
|
||||
virtual View * subAccessoryView() const;
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
protected:
|
||||
virtual KDCoordinate labelMargin() const { return Metric::TableCellHorizontalMargin; }
|
||||
virtual KDCoordinate accessoryMargin() const { return Metric::TableCellHorizontalMargin; }
|
||||
virtual KDColor backgroundColor() const { return KDColorWhite; }
|
||||
virtual KDCoordinate labelMargin() const { return k_horizontalMargin; }
|
||||
virtual KDCoordinate accessoryMargin() const { return k_horizontalMargin; }
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews(bool force = false) override;
|
||||
|
||||
@@ -58,8 +58,6 @@ protected:
|
||||
* coordinates that refer to the data source entire table */
|
||||
int absoluteColumnNumberFromSubviewIndex(int index) const;
|
||||
int absoluteRowNumberFromSubviewIndex(int index) const;
|
||||
int numberOfFullyDisplayableRows() const;
|
||||
int numberOfFullyDisplayableColumns() const;
|
||||
int typeOfSubviewAtIndex(int index) const;
|
||||
/* This method transform a index (of subview for instance) into an index
|
||||
* refering to the set of cells of type "type". */
|
||||
|
||||
@@ -117,11 +117,12 @@ protected:
|
||||
const char * editedText() const override { return m_text.text(); }
|
||||
size_t editedTextLength() const override { return m_text.textLength(); }
|
||||
const Text * getText() const { return &m_text; }
|
||||
bool insertTextAtLocation(const char * text, char * location) override;
|
||||
bool insertTextAtLocation(const char * text, char * location, int textLength = -1) override;
|
||||
void moveCursorGeo(int deltaX, int deltaY);
|
||||
bool removePreviousGlyph() override;
|
||||
bool removeEndOfLine() override;
|
||||
bool removeStartOfLine();
|
||||
size_t removeText(const char * start, const char * end);
|
||||
size_t deleteSelection() override;
|
||||
protected:
|
||||
KDRect glyphFrameAtPosition(const char * text, const char * position) const override;
|
||||
|
||||
@@ -74,7 +74,7 @@ protected:
|
||||
/* If the text to be appended is too long to be added without overflowing the
|
||||
* buffer, nothing is done (not even adding few letters from the text to reach
|
||||
* the maximum buffer capacity) and false is returned. */
|
||||
bool insertTextAtLocation(const char * text, char * location) override;
|
||||
bool insertTextAtLocation(const char * text, char * location, int textLength = -1) override;
|
||||
KDSize minimalSizeForOptimalDisplay() const override;
|
||||
bool removePreviousGlyph() override;
|
||||
bool removeEndOfLine() override;
|
||||
|
||||
@@ -49,7 +49,7 @@ protected:
|
||||
|
||||
// Virtual text get/add/remove
|
||||
virtual const char * text() const = 0;
|
||||
virtual bool insertTextAtLocation(const char * text, char * location) = 0;
|
||||
virtual bool insertTextAtLocation(const char * text, char * location, int textLength = -1) = 0;
|
||||
virtual bool removePreviousGlyph() = 0;
|
||||
virtual bool removeEndOfLine() = 0;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
N,
|
||||
true);
|
||||
}
|
||||
const MessageTree * children(int index) const override { return &m_children[index]; }
|
||||
const MessageTree * childAtIndex(int index) const override { return &m_children[index]; }
|
||||
I18n::Message text() const { return m_text; }
|
||||
I18n::Message insertedText() const { return m_insertedText; }
|
||||
bool stripInsertedText() const { return m_stripInsertedText; }
|
||||
|
||||
@@ -18,13 +18,11 @@ ExpressionView::ExpressionView(float horizontalAlignment, float verticalAlignmen
|
||||
}
|
||||
|
||||
bool ExpressionView::setLayout(Layout layoutR) {
|
||||
/* TODO: this would avoid some useless redrawing. However, when we call
|
||||
* setLayout after raising an Exception that led to erase all
|
||||
* Poincare::TreePool, accessing m_layout will result in an ACCESS ERROR.
|
||||
* How do we avoid that? */
|
||||
/*if (m_layout.isIdenticalTo(layoutR)) {
|
||||
if (!m_layout.wasErasedByException() && m_layout.isIdenticalTo(layoutR)) {
|
||||
/* Check m_layout.wasErasedByException(), otherwise accessing m_layout would
|
||||
* result in an ACCESS ERROR. */
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
m_layout = layoutR;
|
||||
markRectAsDirty(bounds());
|
||||
return true;
|
||||
|
||||
@@ -5,10 +5,14 @@
|
||||
#include <escher/metric.h>
|
||||
|
||||
bool InputEventHandler::handleBoxEvent(Ion::Events::Event event) {
|
||||
if (m_inputEventHandlerDelegate == nullptr) {
|
||||
return false;
|
||||
}
|
||||
NestedMenuController * box = nullptr;
|
||||
if (m_inputEventHandlerDelegate) {
|
||||
box = event == Ion::Events::Toolbox ? m_inputEventHandlerDelegate->toolboxForInputEventHandler(this) : box;
|
||||
box = event == Ion::Events::Var ? m_inputEventHandlerDelegate->variableBoxForInputEventHandler(this) : box;
|
||||
if (event == Ion::Events::Toolbox) {
|
||||
box = m_inputEventHandlerDelegate->toolboxForInputEventHandler(this);
|
||||
} else if (event == Ion::Events::Var) {
|
||||
box = m_inputEventHandlerDelegate->variableBoxForInputEventHandler(this);
|
||||
}
|
||||
if (box) {
|
||||
box->setSender(this);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <escher/clipboard.h>
|
||||
#include <escher/text_field.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/empty_layout.h>
|
||||
#include <poincare/horizontal_layout.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
@@ -42,13 +43,16 @@ bool LayoutField::ContentView::setEditing(bool isEditing) {
|
||||
|
||||
void LayoutField::ContentView::useInsertionCursor() {
|
||||
if (m_insertionCursor.isDefined()) {
|
||||
m_cursor.layout().removeGreySquaresFromAllMatrixAncestors();
|
||||
m_cursor = m_insertionCursor;
|
||||
m_cursor.layout().addGreySquaresToAllMatrixAncestors();
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutField::ContentView::clearLayout() {
|
||||
HorizontalLayout h = HorizontalLayout::Builder();
|
||||
if (m_expressionView.setLayout(h)) {
|
||||
resetSelection();
|
||||
m_cursor.setLayout(h);
|
||||
}
|
||||
}
|
||||
@@ -234,6 +238,17 @@ void LayoutField::ContentView::deleteSelection() {
|
||||
resetSelection();
|
||||
}
|
||||
|
||||
void LayoutField::ContentView::updateInsertionCursor() {
|
||||
if (!m_insertionCursor.isDefined()) {
|
||||
Layout l = m_cursor.layout();
|
||||
if (l.type() == LayoutNode::Type::EmptyLayout && static_cast<EmptyLayout &>(l).color() == EmptyLayoutNode::Color::Grey) {
|
||||
// Don't set m_insertionCursor pointing to a layout which might disappear
|
||||
return;
|
||||
}
|
||||
m_insertionCursor = m_cursor;
|
||||
}
|
||||
}
|
||||
|
||||
View * LayoutField::ContentView::subviewAtIndex(int index) {
|
||||
assert(0 <= index && index < numberOfSubviews());
|
||||
View * m_views[] = {&m_expressionView, &m_cursorView};
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
MessageTableCell::MessageTableCell(I18n::Message label, const KDFont * font, Layout layout) :
|
||||
TableCell(layout),
|
||||
m_messageTextView(font, label, 0, 0.5, Palette::PrimaryText, Palette::ListCellBackground)
|
||||
m_messageTextView(font, label, 0, 0.5, Palette::PrimaryText, Palette::ListCellBackground),
|
||||
m_backgroundColor(KDColorWhite)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,3 +32,8 @@ void MessageTableCell::setMessageFont(const KDFont * font) {
|
||||
m_messageTextView.setFont(font);
|
||||
layoutSubviews();
|
||||
}
|
||||
|
||||
void MessageTableCell::setBackgroundColor(KDColor color) {
|
||||
m_backgroundColor = color;
|
||||
m_messageTextView.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
81
escher/src/modal_view_empty_controller.cpp
Normal file
81
escher/src/modal_view_empty_controller.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include <escher/modal_view_empty_controller.h>
|
||||
#include <apps/i18n.h>
|
||||
#include <assert.h>
|
||||
|
||||
constexpr KDColor ModalViewEmptyController::ModalViewEmptyView::k_backgroundColor;
|
||||
|
||||
// ModalViewEmptyController::ModalViewEmptyView
|
||||
void ModalViewEmptyController::ModalViewEmptyView::initMessageViews() {
|
||||
const int numberOfMessageViews = numberOfMessageTextViews();
|
||||
for (int i = 0; i < numberOfMessageViews; i++) {
|
||||
MessageTextView * message = messageTextViewAtIndex(i);
|
||||
message->setFont(k_font);
|
||||
message->setBackgroundColor(k_backgroundColor);
|
||||
float verticalAlignment = 0.5f;
|
||||
if (i == 0) {
|
||||
verticalAlignment = 1.0f;
|
||||
} else if (i == numberOfMessageViews - 1) {
|
||||
verticalAlignment = 0.0f;
|
||||
}
|
||||
message->setAlignment(0.5f, verticalAlignment);
|
||||
}
|
||||
}
|
||||
|
||||
void ModalViewEmptyController::ModalViewEmptyView::setMessages(I18n::Message * message) {
|
||||
const int numberOfMessageViews = numberOfMessageTextViews();
|
||||
for (int i = 0; i < numberOfMessageViews; i++) {
|
||||
messageTextViewAtIndex(i)->setMessage(message[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ModalViewEmptyController::ModalViewEmptyView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(bounds(), k_backgroundColor);
|
||||
drawBorderOfRect(ctx, bounds(), Palette::GreyBright);
|
||||
}
|
||||
|
||||
int ModalViewEmptyController::ModalViewEmptyView::numberOfSubviews() const {
|
||||
return numberOfMessageTextViews() + hasExpressionView();
|
||||
}
|
||||
|
||||
View * ModalViewEmptyController::ModalViewEmptyView::subviewAtIndex(int index) {
|
||||
if (hasExpressionView()) {
|
||||
if (index == k_expressionViewRowIndex) {
|
||||
return expressionView();
|
||||
}
|
||||
return messageTextViewAtIndex(index + (index < k_expressionViewRowIndex ? 0 : -1));
|
||||
}
|
||||
return messageTextViewAtIndex(index);
|
||||
}
|
||||
|
||||
void ModalViewEmptyController::ModalViewEmptyView::layoutSubviews(bool force) {
|
||||
const int numberOfMessageViews = numberOfMessageTextViews();
|
||||
const bool hasExpression = hasExpressionView();
|
||||
KDCoordinate width = bounds().width() - 2 * k_separatorThickness;
|
||||
KDCoordinate height = bounds().height() - 2 * k_separatorThickness;
|
||||
KDCoordinate textHeight = k_font->glyphSize().height();
|
||||
KDCoordinate layoutHeight = hasExpression ? expressionView()->minimalSizeForOptimalDisplay().height() : 0;
|
||||
KDCoordinate margin = (height - numberOfMessageViews * textHeight - layoutHeight) / 2;
|
||||
if (hasExpression) {
|
||||
expressionView()->setFrame(KDRect(
|
||||
k_separatorThickness,
|
||||
k_separatorThickness + margin + k_expressionViewRowIndex * textHeight,
|
||||
width,
|
||||
layoutHeight),
|
||||
force);
|
||||
}
|
||||
KDCoordinate currentHeight = k_separatorThickness;
|
||||
for (uint8_t i = 0; i < numberOfMessageViews; i++) {
|
||||
if (hasExpression && i == k_expressionViewRowIndex) {
|
||||
currentHeight += layoutHeight;
|
||||
}
|
||||
KDCoordinate h = (i == 0 || i == numberOfMessageViews - 1) ? textHeight + margin : textHeight;
|
||||
messageTextViewAtIndex(i)->setFrame(KDRect(k_separatorThickness, currentHeight, width, h), force);
|
||||
currentHeight += h;
|
||||
}
|
||||
}
|
||||
|
||||
// ModalViewEmptyController
|
||||
|
||||
void ModalViewEmptyController::setMessages(I18n::Message * messages) {
|
||||
static_cast<ModalViewEmptyView *>(view())->setMessages(messages);
|
||||
}
|
||||
@@ -90,7 +90,7 @@ void NestedMenuController::ListController::setFirstSelectedRow(int firstSelected
|
||||
|
||||
NestedMenuController::NestedMenuController(Responder * parentResponder, I18n::Message title) :
|
||||
StackViewController(parentResponder, &m_listController, Palette::ToolboxHeaderText, Palette::ToolboxHeaderBackground, Palette::ToolboxHeaderBorder),
|
||||
m_selectableTableView(&m_listController, this, this),
|
||||
m_selectableTableView(&m_listController, this, this, this),
|
||||
m_listController(this, &m_selectableTableView, title),
|
||||
m_sender(nullptr)
|
||||
{
|
||||
@@ -98,6 +98,10 @@ NestedMenuController::NestedMenuController(Responder * parentResponder, I18n::Me
|
||||
m_selectableTableView.setDecoratorType(ScrollView::Decorator::Type::None);
|
||||
}
|
||||
|
||||
void NestedMenuController::setTitle(I18n::Message title) {
|
||||
m_listController.setTitle(title);
|
||||
}
|
||||
|
||||
bool NestedMenuController::handleEvent(Ion::Events::Event event) {
|
||||
return handleEventForRow(event, selectedRow());
|
||||
}
|
||||
|
||||
@@ -130,6 +130,8 @@ constexpr KDColor Palette::Green;
|
||||
constexpr KDColor Palette::GreenLight;
|
||||
constexpr KDColor Palette::Brown;
|
||||
constexpr KDColor Palette::Purple;
|
||||
constexpr KDColor Palette::Cyan; // TODO Palette change
|
||||
constexpr KDColor Palette::BlueishGrey; // TODO Palette change
|
||||
constexpr KDColor Palette::DataColor[];
|
||||
constexpr KDColor Palette::DataColorLight[];
|
||||
|
||||
|
||||
@@ -53,9 +53,16 @@ void ScrollView::scrollToContentPoint(KDPoint p, bool allowOverscroll) {
|
||||
if (!allowOverscroll && !m_contentView->bounds().contains(p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
KDRect visibleRect = visibleContentRect();
|
||||
|
||||
if (visibleRect.width() < 0 || visibleRect.height() < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
KDCoordinate offsetX = 0;
|
||||
KDCoordinate offsetY = 0;
|
||||
KDRect visibleRect = visibleContentRect();
|
||||
|
||||
if (visibleRect.left() > p.x()) {
|
||||
offsetX = p.x() - visibleRect.left();
|
||||
}
|
||||
@@ -74,8 +81,16 @@ void ScrollView::scrollToContentPoint(KDPoint p, bool allowOverscroll) {
|
||||
|
||||
// Handle cases when the size of the view has decreased.
|
||||
setContentOffset(KDPoint(
|
||||
std::min(contentOffset().x(), std::max<KDCoordinate>(minimalSizeForOptimalDisplay().width() - bounds().width(), KDCoordinate{0})),
|
||||
std::min(contentOffset().y(), std::max<KDCoordinate>(minimalSizeForOptimalDisplay().height() - bounds().height(), 0))));
|
||||
std::min(
|
||||
contentOffset().x(),
|
||||
std::max<KDCoordinate>(
|
||||
minimalSizeForOptimalDisplay().width() - bounds().width(),
|
||||
KDCoordinate(0))),
|
||||
std::min(
|
||||
contentOffset().y(),
|
||||
std::max<KDCoordinate>(
|
||||
minimalSizeForOptimalDisplay().height() - bounds().height(),
|
||||
KDCoordinate(0)))));
|
||||
}
|
||||
|
||||
void ScrollView::scrollToContentRect(KDRect rect, bool allowOverscroll) {
|
||||
@@ -83,7 +98,7 @@ void ScrollView::scrollToContentRect(KDRect rect, bool allowOverscroll) {
|
||||
KDPoint br = rect.bottomRight();
|
||||
KDRect visibleRect = visibleContentRect();
|
||||
/* We first check that we can display the whole rect. If we can't, we focus
|
||||
* the croll to the closest part of the rect. */
|
||||
* the scroll to the closest part of the rect. */
|
||||
if (visibleRect.height() < rect.height()) {
|
||||
// The visible rect is too small to display 'rect'
|
||||
if (rect.top() >= visibleRect.top()) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <escher/scroll_view_indicator.h>
|
||||
#include <escher/metric.h>
|
||||
#include <escher/palette.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
@@ -8,7 +9,7 @@ extern "C" {
|
||||
ScrollViewIndicator::ScrollViewIndicator() :
|
||||
View(),
|
||||
m_color(Palette::ScrollBarForeground),
|
||||
m_margin(14)
|
||||
m_margin(Metric::CommonTopMargin)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ void SelectableTableView::deselectTable(bool withinTemporarySelection) {
|
||||
selectRow(-1);
|
||||
if (m_delegate) {
|
||||
m_delegate->tableViewDidChangeSelection(this, previousSelectedCellX, previousSelectedCellY, withinTemporarySelection);
|
||||
m_delegate->tableViewDidChangeSelectionAndDidScroll(this, previousSelectedCellX, previousSelectedCellY, withinTemporarySelection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,21 +88,28 @@ bool SelectableTableView::selectCellAtLocation(int i, int j, bool setFirstRespon
|
||||
selectColumn(i);
|
||||
selectRow(j);
|
||||
|
||||
/* The delegate is notified:
|
||||
* - after changing the selected cell but before scrolling: for instance,
|
||||
* ExpressionModelListController needs to update its memoized cell before
|
||||
* being able to scroll;
|
||||
* - after scrolling: for instance, the calculation history table might
|
||||
* change its cell content when selected (outup toggling, ellipsis toggling)
|
||||
* and thus need to access the right used cell - which is defined only
|
||||
* after scrolling.
|
||||
*/
|
||||
|
||||
if (m_delegate) {
|
||||
m_delegate->tableViewDidChangeSelection(this, previousX, previousY, withinTemporarySelection);
|
||||
}
|
||||
|
||||
/* We need to scroll:
|
||||
* - After notifying the delegate. For instance,
|
||||
* ExpressionModelListController needs to update its memoized cell
|
||||
* height values before any scroll.
|
||||
* - Before setting the first responder. If the first responder is a view, it
|
||||
* might change during the scroll. */
|
||||
|
||||
if (selectedRow() >= 0) {
|
||||
scrollToCell(selectedColumn(), selectedRow());
|
||||
}
|
||||
|
||||
if (m_delegate) {
|
||||
m_delegate->tableViewDidChangeSelectionAndDidScroll(this, previousX, previousY, withinTemporarySelection);
|
||||
}
|
||||
|
||||
HighlightCell * cell = selectedCell();
|
||||
if (cell) {
|
||||
// Update first responder
|
||||
|
||||
@@ -129,10 +129,6 @@ void StackViewController::pop() {
|
||||
vc->viewDidDisappear();
|
||||
}
|
||||
|
||||
int StackViewController::depth() {
|
||||
return m_numberOfChildren;
|
||||
}
|
||||
|
||||
void StackViewController::pushModel(Frame frame) {
|
||||
m_childrenFrame[m_numberOfChildren++] = frame;
|
||||
}
|
||||
@@ -160,10 +156,6 @@ bool StackViewController::handleEvent(Ion::Events::Event event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
View * StackViewController::view() {
|
||||
return &m_view;
|
||||
}
|
||||
|
||||
void StackViewController::initView() {
|
||||
m_childrenFrame[0].viewController()->initView();
|
||||
}
|
||||
|
||||
@@ -98,16 +98,16 @@ void TableCell::layoutSubviews(bool force) {
|
||||
y += labelHeight + k_verticalMargin;
|
||||
}
|
||||
horizontalMargin = k_separatorThickness + k_horizontalMargin;
|
||||
y = std::max<KDCoordinate>(y, height - k_separatorThickness - withMargin(accessorySize.height(), Metric::TableCellVerticalMargin) - withMargin(subAccessorySize.height(), 0));
|
||||
y = std::max<KDCoordinate>(y, height - k_separatorThickness - withMargin(accessorySize.height(), k_verticalMargin) - withMargin(subAccessorySize.height(), 0));
|
||||
if (subAccessory) {
|
||||
KDCoordinate subAccessoryHeight = std::min<KDCoordinate>(subAccessorySize.height(), height - y - k_separatorThickness - Metric::TableCellVerticalMargin);
|
||||
KDCoordinate subAccessoryHeight = std::min<KDCoordinate>(subAccessorySize.height(), height - y - k_separatorThickness - k_verticalMargin);
|
||||
accessory->setFrame(KDRect(horizontalMargin, y, width - 2*horizontalMargin, subAccessoryHeight), force);
|
||||
y += subAccessoryHeight;
|
||||
}
|
||||
horizontalMargin = k_separatorThickness + accessoryMargin();
|
||||
y = std::max<KDCoordinate>(y, height - k_separatorThickness - withMargin(accessorySize.height(), Metric::TableCellVerticalMargin));
|
||||
y = std::max<KDCoordinate>(y, height - k_separatorThickness - withMargin(accessorySize.height(), k_verticalMargin));
|
||||
if (accessory) {
|
||||
KDCoordinate accessoryHeight = std::min<KDCoordinate>(accessorySize.height(), height - y - k_separatorThickness - Metric::TableCellVerticalMargin);
|
||||
KDCoordinate accessoryHeight = std::min<KDCoordinate>(accessorySize.height(), height - y - k_separatorThickness - k_verticalMargin);
|
||||
accessory->setFrame(KDRect(horizontalMargin, y, width - 2*horizontalMargin, accessoryHeight), force);
|
||||
}
|
||||
} else {
|
||||
@@ -164,7 +164,7 @@ void TableCell::layoutSubviews(bool force) {
|
||||
}
|
||||
|
||||
void TableCell::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
KDColor backgroundColor = isHighlighted() ? Palette::ListCellBackgroundSelected : Palette::ListCellBackground;
|
||||
drawInnerRect(ctx, bounds(), backgroundColor);
|
||||
KDColor backColor = isHighlighted() ? Palette::ListCellBackgroundSelected : Palette::ListCellBackground;
|
||||
drawInnerRect(ctx, bounds(), backColor);
|
||||
drawBorderOfRect(ctx, bounds(), Palette::ListCellBorder);
|
||||
}
|
||||
|
||||
@@ -177,55 +177,28 @@ void TableView::ContentView::layoutSubviews(bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int TableView::ContentView::numberOfFullyDisplayableRows() const {
|
||||
// The number of displayable rows taking into accounts margins
|
||||
int rowOffsetWithMargin = m_dataSource->indexFromCumulatedHeight(m_tableView->contentOffset().y() +
|
||||
m_tableView->topMargin());
|
||||
int displayedHeightWithOffsetAndMargin = m_dataSource->indexFromCumulatedHeight(m_tableView->maxContentHeightDisplayableWithoutScrolling() +
|
||||
m_tableView->contentOffset().y() + m_tableView->topMargin());
|
||||
return displayedHeightWithOffsetAndMargin - rowOffsetWithMargin;
|
||||
}
|
||||
|
||||
int TableView::ContentView::numberOfFullyDisplayableColumns() const {
|
||||
// The number of displayable rows taking into accounts margins
|
||||
int columnOffsetWithMargin = m_dataSource->indexFromCumulatedWidth(m_tableView->contentOffset().x() +
|
||||
m_tableView->leftMargin());
|
||||
int displayedWidthWithOffsetAndMargin = m_dataSource->indexFromCumulatedWidth(m_tableView->maxContentWidthDisplayableWithoutScrolling() +
|
||||
m_tableView->contentOffset().x() + m_tableView->leftMargin());
|
||||
return displayedWidthWithOffsetAndMargin - columnOffsetWithMargin;
|
||||
}
|
||||
|
||||
int TableView::ContentView::numberOfDisplayableRows() const {
|
||||
int rowOffset = rowsScrollingOffset();
|
||||
int displayedHeightWithOffset = m_dataSource->indexFromCumulatedHeight(m_tableView->bounds().height() + m_tableView->contentOffset().y());
|
||||
return std::min(
|
||||
m_dataSource->numberOfRows(),
|
||||
displayedHeightWithOffset + 1
|
||||
) - rowOffset;
|
||||
int displayedHeightWithOffset = m_dataSource->indexFromCumulatedHeight(m_tableView->bounds().height() + (m_tableView->contentOffset().y() - m_tableView->topMargin()));
|
||||
return std::min(m_dataSource->numberOfRows(), displayedHeightWithOffset + 1) - rowOffset;
|
||||
}
|
||||
|
||||
int TableView::ContentView::numberOfDisplayableColumns() const {
|
||||
int columnOffset = columnsScrollingOffset();
|
||||
int displayedWidthWithOffset = m_dataSource->indexFromCumulatedWidth(m_tableView->bounds().width() + m_tableView->contentOffset().x());
|
||||
return std::min(
|
||||
m_dataSource->numberOfColumns(),
|
||||
displayedWidthWithOffset + 1
|
||||
) - columnOffset;
|
||||
int displayedWidthWithOffset = m_dataSource->indexFromCumulatedWidth(m_tableView->bounds().width() + m_tableView->contentOffset().x() - m_tableView->leftMargin());
|
||||
return std::min(m_dataSource->numberOfColumns(), displayedWidthWithOffset + 1) - columnOffset;
|
||||
}
|
||||
|
||||
int TableView::ContentView::rowsScrollingOffset() const {
|
||||
/* Here, we want to translate the offset at which our tableView is displaying
|
||||
* us into an integer offset we can use to ask cells to our data source. */
|
||||
KDCoordinate invisibleHeight = m_tableView->contentOffset().y()-m_tableView->topMargin();
|
||||
invisibleHeight = invisibleHeight < 0 ? 0 : invisibleHeight;
|
||||
KDCoordinate invisibleHeight = std::max(m_tableView->contentOffset().y() - m_tableView->topMargin(), 0);
|
||||
return m_dataSource->indexFromCumulatedHeight(invisibleHeight);
|
||||
}
|
||||
|
||||
int TableView::ContentView::columnsScrollingOffset() const {
|
||||
/* Here, we want to translate the offset at which our tableView is displaying
|
||||
* us into an integer offset we can use to ask cells to our data source. */
|
||||
KDCoordinate invisibleWidth = m_tableView->contentOffset().x()-m_tableView->leftMargin();
|
||||
invisibleWidth = invisibleWidth < 0 ? 0 : invisibleWidth;
|
||||
KDCoordinate invisibleWidth = std::max(m_tableView->contentOffset().x() - m_tableView->leftMargin(), 0);
|
||||
return m_dataSource->indexFromCumulatedWidth(invisibleWidth);
|
||||
}
|
||||
|
||||
@@ -258,11 +258,16 @@ void TextArea::Text::insertText(const char * s, int textLength, char * location)
|
||||
assert(m_buffer != nullptr);
|
||||
assert(location >= m_buffer && location < m_buffer + m_bufferSize - 1);
|
||||
assert(strlen(m_buffer) + textLength < m_bufferSize);
|
||||
// assert the text to insert does not overlap the location where to insert
|
||||
assert(s >= location || s + textLength < location);
|
||||
|
||||
/* The text to insert might be located after the insertion location, in which
|
||||
* case we cannot simply do a memmove, as s will be shifted by the copy. */
|
||||
bool noShift = (s + textLength < location) || (s > m_buffer + m_bufferSize);
|
||||
size_t sizeToMove = strlen(location) + 1;
|
||||
assert(location + textLength + sizeToMove <= m_buffer + m_bufferSize);
|
||||
memmove(location + textLength, location, sizeToMove);
|
||||
memmove(location, s, textLength);
|
||||
memmove(location, s + (noShift ? 0 : textLength), textLength);
|
||||
}
|
||||
|
||||
void TextArea::Text::insertSpacesAtLocation(int numberOfSpaces, char * location) {
|
||||
@@ -479,26 +484,19 @@ void TextArea::ContentView::setText(char * textBuffer, size_t textBufferSize) {
|
||||
m_cursorLocation = text();
|
||||
}
|
||||
|
||||
bool TextArea::ContentView::insertTextAtLocation(const char * text, char * location) {
|
||||
int textSize = strlen(text);
|
||||
if (m_text.textLength() + textSize >= m_text.bufferSize() || textSize == 0) {
|
||||
bool TextArea::ContentView::insertTextAtLocation(const char * text, char * location, int textLength) {
|
||||
int textLen = textLength < 0 ? strlen(text) : textLength;
|
||||
assert(textLen < 0 || textLen <= strlen(text));
|
||||
if (m_text.textLength() + textLen >= m_text.bufferSize() || textLen == 0) {
|
||||
return false;
|
||||
}
|
||||
bool lineBreak = false;
|
||||
|
||||
// Scan for \n and 0
|
||||
const char * nullLocation = UTF8Helper::PerformAtCodePoints(
|
||||
text, '\n',
|
||||
[](int codePointOffset, void * lineBreak, int context1, int context2) {
|
||||
*((bool *)lineBreak) = true;
|
||||
},
|
||||
[](int c1, void * c2, int c3, int c4) { },
|
||||
&lineBreak, 0);
|
||||
// Scan for \n
|
||||
bool lineBreak = UTF8Helper::HasCodePoint(text, '\n', text + textLen);
|
||||
|
||||
assert(UTF8Helper::CodePointIs(nullLocation, 0));
|
||||
m_text.insertText(text, nullLocation - text, location);
|
||||
m_text.insertText(text, textLen, location);
|
||||
// Replace System parentheses (used to keep layout tree structure) by normal parentheses
|
||||
Poincare::SerializationHelper::ReplaceSystemParenthesesByUserParentheses(location, nullLocation - text);
|
||||
Poincare::SerializationHelper::ReplaceSystemParenthesesByUserParentheses(location, textLen);
|
||||
reloadRectFromPosition(location, lineBreak);
|
||||
return true;
|
||||
}
|
||||
@@ -542,9 +540,13 @@ bool TextArea::ContentView::removeStartOfLine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t TextArea::ContentView::removeText(const char * start, const char * end) {
|
||||
return m_text.removeText(start, end);
|
||||
}
|
||||
|
||||
size_t TextArea::ContentView::deleteSelection() {
|
||||
assert(!selectionIsEmpty());
|
||||
size_t removedLength = m_text.removeText(m_selectionStart, m_selectionEnd);
|
||||
size_t removedLength = removeText(m_selectionStart, m_selectionEnd);
|
||||
/* We cannot call resetSelection() because m_selectionStart and m_selectionEnd
|
||||
* are invalid */
|
||||
m_selectionStart = nullptr;
|
||||
|
||||
@@ -119,10 +119,10 @@ void TextField::ContentView::reinitDraftTextBuffer() {
|
||||
setCursorLocation(s_draftTextBuffer);
|
||||
}
|
||||
|
||||
bool TextField::ContentView::insertTextAtLocation(const char * text, char * location) {
|
||||
bool TextField::ContentView::insertTextAtLocation(const char * text, char * location, int textLen) {
|
||||
assert(m_isEditing);
|
||||
|
||||
int textLength = strlen(text);
|
||||
size_t textLength = textLen < 0 ? strlen(text) : (size_t)textLen;
|
||||
if (m_currentDraftTextLength + textLength >= m_draftTextBufferSize || textLength == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -130,12 +130,12 @@ bool TextField::ContentView::insertTextAtLocation(const char * text, char * loca
|
||||
memmove(location + textLength, location, (s_draftTextBuffer + m_currentDraftTextLength + 1) - location);
|
||||
|
||||
// Caution! One byte will be overridden by the null-terminating char of strlcpy
|
||||
char * overridenByteLocation = location + textLength;
|
||||
size_t copySize = std::min(textLength + 1, static_cast<size_t>((s_draftTextBuffer + m_draftTextBufferSize) - location));
|
||||
char * overridenByteLocation = location + copySize - 1;
|
||||
char overridenByte = *overridenByteLocation;
|
||||
strlcpy(location, text, (s_draftTextBuffer + m_draftTextBufferSize) - location);
|
||||
assert(overridenByteLocation < s_draftTextBuffer + m_draftTextBufferSize);
|
||||
strlcpy(location, text, copySize);
|
||||
*overridenByteLocation = overridenByte;
|
||||
m_currentDraftTextLength += textLength;
|
||||
m_currentDraftTextLength += copySize-1; // Do no count the null-termination
|
||||
|
||||
reloadRectFromPosition(m_horizontalAlignment == 0.0f ? location : s_draftTextBuffer);
|
||||
return true;
|
||||
|
||||
@@ -25,7 +25,7 @@ int Toolbox::reusableCellCount(int type) {
|
||||
}
|
||||
|
||||
void Toolbox::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
ToolboxMessageTree * messageTree = (ToolboxMessageTree *)m_messageTreeModel->children(index);
|
||||
ToolboxMessageTree * messageTree = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(index);
|
||||
if (messageTree->numberOfChildren() == 0) {
|
||||
MessageTableCellWithMessage * myCell = (MessageTableCellWithMessage *)cell;
|
||||
myCell->setMessage(messageTree->label());
|
||||
@@ -39,7 +39,7 @@ void Toolbox::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
}
|
||||
|
||||
int Toolbox::typeAtLocation(int i, int j) {
|
||||
MessageTree * messageTree = (MessageTree *)m_messageTreeModel->children(j);
|
||||
MessageTree * messageTree = (MessageTree *)m_messageTreeModel->childAtIndex(j);
|
||||
if (messageTree->numberOfChildren() == 0) {
|
||||
return LeafCellType;
|
||||
}
|
||||
@@ -48,7 +48,7 @@ int Toolbox::typeAtLocation(int i, int j) {
|
||||
|
||||
bool Toolbox::selectSubMenu(int selectedRow) {
|
||||
m_selectableTableView.deselectTable();
|
||||
m_messageTreeModel = (ToolboxMessageTree *)m_messageTreeModel->children(selectedRow);
|
||||
m_messageTreeModel = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow);
|
||||
return NestedMenuController::selectSubMenu(selectedRow);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ bool Toolbox::returnToPreviousMenu() {
|
||||
ToolboxMessageTree * parentMessageTree = (ToolboxMessageTree *)rootModel();
|
||||
Stack::State * previousState = m_stack.stateAtIndex(index++);
|
||||
while (currentDepth-- > 1) {
|
||||
parentMessageTree = (ToolboxMessageTree *)parentMessageTree->children(previousState->selectedRow());
|
||||
parentMessageTree = (ToolboxMessageTree *)parentMessageTree->childAtIndex(previousState->selectedRow());
|
||||
previousState = m_stack.stateAtIndex(index++);
|
||||
}
|
||||
m_messageTreeModel = parentMessageTree;
|
||||
|
||||
Reference in New Issue
Block a user