Numworks Epsilon  1.4.1
Graphing Calculator Operating System
banner_view.cpp
Go to the documentation of this file.
1 #include "banner_view.h"
2 #include <string.h>
3 #include <assert.h>
4 
5 namespace Shared {
6 
7 void BannerView::setLegendAtIndex(char * text, int index) {
8  /* The layout of the banner's subviews depends on their content.
9  * Indeed, we're using a "centered text" algorithm to layout the subviews.
10  * So changing a legend implies two things
11  * - First, we need to update the textView to ensure it has the new content
12  * - Second, we need to relayout *all* of our subviews. */
13  TextView * textView = textViewAtIndex(index);
14  textView->setText(text);
15  layoutSubviews();
16 }
17 
18 void BannerView::setMessageAtIndex(I18n::Message text, int index) {
19  MessageTextView * textView = messageTextViewAtIndex(index);
20  textView->setMessage(text);
21  layoutSubviews();
22 }
23 
25  return KDSize(0, KDText::charSize(KDText::FontSize::Small).height()*numberOfLines());
26 }
27 
28 int BannerView::numberOfSubviews() const {
29  return 0;
30 }
31 
32 void BannerView::layoutSubviews() {
33  /* We iterate on subviews, adding their width until we exceed the view bound.
34  * The last subview that exceeds the bound is recorded as the first subview of
35  * the next line. For the current line, we scan again the subviews and frame
36  * them by equally distributing the remaining width. We then jump to the next
37  * line and iterate the process. */
38  KDCoordinate totalWidth = bounds().width();
39  KDCoordinate lineWidth = 0;
40  TextView * textViewPreviousLine = textViewAtIndex(0);
41  int indexOfFirstViewOfCurrentLine = 0;
42  KDCoordinate y = 0;
43  /* We do a last iteration of the loop to layout the last line. */
44  for (int i = 0; i <= numberOfSubviews(); i++) {
45  TextView * textView = nullptr;
46  KDCoordinate currentViewWidth = totalWidth;
47  if (i < numberOfSubviews()) {
48  textView = textViewAtIndex(i);
49  currentViewWidth = textView->minimalSizeForOptimalDisplay().width();
50  }
51  // The subview exceed the total width
52  if (lineWidth + currentViewWidth > totalWidth) {
53  KDCoordinate x = 0;
54  int nbOfTextViewInLine = i > indexOfFirstViewOfCurrentLine ? i-indexOfFirstViewOfCurrentLine : 1;
55  KDCoordinate roundingError = totalWidth-lineWidth-nbOfTextViewInLine*(int)((totalWidth-lineWidth)/nbOfTextViewInLine);
56  for (int j = indexOfFirstViewOfCurrentLine; j < i; j++) {
57  textViewPreviousLine = textViewAtIndex(j);
58  KDCoordinate textWidth = textViewPreviousLine->minimalSizeForOptimalDisplay().width() + (totalWidth - lineWidth)/nbOfTextViewInLine;
59  // For the last text view, avoid letting a 1-pixel-wide empty vertical due to rounding error:
60  textWidth = j == i-1 ? textWidth + roundingError : textWidth;
61  KDCoordinate textHeight = textViewPreviousLine->minimalSizeForOptimalDisplay().height();
62  textViewPreviousLine->setFrame(KDRect(x, y, textWidth, textHeight));
63  x += textWidth;
64  }
65  // Next line
66  y += textViewPreviousLine->minimalSizeForOptimalDisplay().height();
67  lineWidth = 0;
68  indexOfFirstViewOfCurrentLine = i;
69  }
70  lineWidth += currentViewWidth;
71  }
72 }
73 
74 View * BannerView::subviewAtIndex(int index) {
75  assert(index >= 0 && index < numberOfSubviews());
76  return textViewAtIndex(index);
77 }
78 
79 int BannerView::numberOfLines() const {
80  KDCoordinate width = bounds().width();
81  KDCoordinate usedWidth = 0;
82  KDCoordinate lineNumber = 0;
83  for (int i = 0; i < numberOfSubviews(); i++) {
84  KDCoordinate textWidth = KDText::stringSize(textViewAtIndex(i)->text(), KDText::FontSize::Small).width();
85  if (usedWidth+textWidth > width) {
86  usedWidth = textWidth;
87  lineNumber++;
88  } else {
89  usedWidth += textWidth;
90  }
91  }
92  return lineNumber+1;
93 }
94 
95 MessageTextView * BannerView::messageTextViewAtIndex(int i) const {
96  return nullptr;
97 }
98 
99 }
void setLegendAtIndex(char *text, int index)
Definition: banner_view.cpp:7
#define assert(e)
Definition: assert.h:9
void setFrame(KDRect frame)
Definition: view.cpp:125
int16_t KDCoordinate
Definition: coordinate.h:6
constexpr KDCoordinate width() const
Definition: size.h:10
static KDSize stringSize(const char *text, FontSize size=FontSize::Large)
Definition: text.cpp:6
void setMessageAtIndex(I18n::Message text, int index)
Definition: banner_view.cpp:18
KDSize minimalSizeForOptimalDisplay() const override
Definition: banner_view.cpp:24
virtual void setText(const char *text)=0
Definition: size.h:6
void setMessage(I18n::Message message)
Definition: rect.h:26
Definition: view.h:23
KDCoordinate width() const
Definition: rect.h:39
static constexpr KDSize charSize(FontSize size=FontSize::Large)
Definition: text.h:16
KDRect bounds() const
Definition: view.cpp:157
KDSize minimalSizeForOptimalDisplay() const override
Definition: text_view.cpp:35
constexpr KDCoordinate height() const
Definition: size.h:11