123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 |
- #include "pch.h"
- //////////////////////////////////////////////////////////////////////////////
- //
- // Link Pane
- //
- //////////////////////////////////////////////////////////////////////////////
- class TabWordPane : public Pane {
- private:
- public:
- TabWordPane(int x) :
- Pane(NULL, WinPoint(0, 0))
- {
- }
- int GetAlignedXSize(int xPos)
- {
- int tabs = (xPos / 16) + 1;
- int size = tabs * 16 - xPos;
- return size;
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Link Pane
- //
- //////////////////////////////////////////////////////////////////////////////
- class LinkPane : public StringPane {
- private:
- TRef<StringEventSourceImpl> m_peventSource;
- ZString m_strTopic;
- Color m_color;
- Color m_colorSelected;
- bool m_bInside;
- public:
- LinkPane(
- StringEventSourceImpl* peventSource,
- const ZString& str,
- const ZString& strTopic,
- IEngineFont* pfont,
- const Color& color,
- const Color& colorSelected
- ) :
- StringPane(str, pfont),
- m_peventSource(peventSource),
- m_strTopic(strTopic),
- m_color(color),
- m_colorSelected(colorSelected),
- m_bInside(false)
- {
- SetTextColor(m_color);
- }
- void MouseEnter(IInputProvider* pprovider, const Point& point)
- {
- m_bInside = true;
- SetTextColor(m_colorSelected);
- }
- void MouseLeave(IInputProvider* pprovider)
- {
- m_bInside = false;
- SetTextColor(m_color);
- }
- MouseResult Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown)
- {
- if (button == 0 && bDown) {
- m_peventSource->Trigger(m_strTopic);
- }
- return MouseResult();
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Page Pane
- //
- //////////////////////////////////////////////////////////////////////////////
- class PagePaneImpl : public PagePane {
- private:
- TRef<Modeler> m_pmodeler;
- TRef<PagePaneIncluder> m_ppagePaneIncluder;
- TRef<IEngineFont> m_pfontDefault;
- Color m_colorDefault;
- TRef<IEngineFont> m_pfont;
- Color m_color;
- Color m_colorMain;
- Color m_colorSecondary;
- Color m_colorHighlight;
- int m_width;
- TRef<StringEventSourceImpl> m_peventSourceMain;
- TRef<StringEventSourceImpl> m_peventSourceSecondary;
- public:
- PagePaneImpl(
- Modeler* pmodeler,
- int width,
- StringEventSourceImpl* peventSourceMain,
- StringEventSourceImpl* peventSourceSecondary
- ) :
- m_pmodeler(pmodeler),
- m_width(width)
- {
- if (peventSourceMain) {
- m_peventSourceMain = peventSourceMain;
- } else {
- m_peventSourceMain = new StringEventSourceImpl();
- }
- if (peventSourceSecondary) {
- m_peventSourceSecondary = peventSourceSecondary;
- } else {
- m_peventSourceSecondary = new StringEventSourceImpl();
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Implementation
- //
- //////////////////////////////////////////////////////////////////////////////
- void InsertWord(PCC pcc, PCC pccEnd)
- {
- TRef<StringPane> pstringPane =
- new StringPane(
- ZString(pcc, pccEnd - pcc) + " ",
- m_pfont
- );
- pstringPane->SetTextColor(m_color);
- InsertAtBottom(pstringPane);
- }
- void InsertString(const ZString& str)
- {
- TRef<StringPane> pstringPane =
- new StringPane(
- str + " ",
- m_pfont
- );
- pstringPane->SetTextColor(m_color);
- InsertAtBottom(pstringPane);
- }
- void InsertTab()
- {
- InsertAtBottom(new TabWordPane(1));
- }
- bool InsertLink(PCC& pcc, PCC pccEnd, const Color& color, StringEventSourceImpl* peventSource)
- {
- //
- // topic|text>
- //
- //
- // topic
- //
- ZString strTopic;
- if (!ParseSymbol(pcc, pccEnd, '|', strTopic)) {
- return false;
- }
- //
- // text
- //
- ZString strText;
- if (!ParseSymbol(pcc, pccEnd, '>', strText)) {
- return false;
- }
- //
- // The LinkPane
- //
-
- TRef<LinkPane> plinkPane =
- new LinkPane(
- peventSource,
- strText + " ",
- strTopic,
- m_pfont,
- color,
- m_colorHighlight
- );
- InsertAtBottom(plinkPane);
- return true;
- }
- bool Error(const ZString& str)
- {
- m_color = Color::Red();
- Parse(NULL, "Error: " + str);
- return false;
- }
- bool MatchBrace(PCC& pcc, PCC pccEnd)
- {
- int depth = 1;
- while (pcc < pccEnd && depth != 0) {
- if (*pcc == '<') {
- depth++;
- } else if (*pcc == '>') {
- depth--;
- }
- pcc++;
- }
- if (depth != 0) {
- return Error("Expected '>'");
- }
- return true;
- }
- bool ParseComment(PCC& pcc, PCC pccEnd)
- {
- return MatchBrace(pcc, pccEnd);
- }
- bool ParseBullet(INameSpace* pns, PCC& pcc, PCC pccEnd)
- {
- ZString strImage;
- if (!ParseSymbol(pcc, pccEnd, '|', strImage)) {
- return false;
- }
- TRef<Image> pimage = m_pmodeler->LoadImage(strImage + "bmp", true, false);
- if (pimage == NULL) {
- return Error("Invalid image");
- }
- PCC pccStart = pcc;
- if (!MatchBrace(pcc, pccEnd)) {
- return false;
- }
- TRef<PagePaneImpl> ppagePane =
- new PagePaneImpl(
- m_pmodeler,
- m_width - int(pimage->GetBounds().GetRect().XSize()),
- m_peventSourceMain,
- m_peventSourceSecondary
- );
- ppagePane->SetAttributes(
- m_pfontDefault,
- m_colorDefault,
- m_colorMain,
- m_colorSecondary,
- m_colorHighlight
- );
- ppagePane->m_pfont = m_pfontDefault;
- ppagePane->m_color = m_colorDefault;
- ppagePane->RemoveAllChildren();
- ppagePane->Parse(pns, pccStart, pcc - 1);
- InsertAtBottom(
- new JustifyPane(
- JustifyPane::Left | JustifyPane::Top,
- WinPoint(m_width, 0),
- new RowPane(
- new ImagePane(pimage),
- ppagePane
- )
- )
- );
- return true;
- }
- bool ParseSymbol(PCC& pcc, PCC pccEnd, char chEnd, ZString& str)
- {
- PCC pccSymbol = pcc;
- while (
- pcc < pccEnd
- && *pcc != chEnd
- ) {
- pcc++;
- }
- if (pcc == pccEnd || *pcc != chEnd) {
- return Error("Expected '>'");
- }
- str = ZString(pccSymbol, pcc - pccSymbol);
- pcc++;
- return true;
- }
- bool Include(INameSpace* pns, const ZString& str, const ZString& strFile)
- {
- if (m_ppagePaneIncluder) {
- TRef<ZFile> pfile = m_ppagePaneIncluder->Include(str);
- if (pfile == NULL) {
- pfile = m_pmodeler->LoadFile(strFile, "mml", false);
- }
- if (pfile) {
- if (pfile->GetLength() > 0) {
- PCC pcc = (PCC)(pfile->GetPointer());
- Parse(pns, pcc, pcc + pfile->GetLength());
- }
- }
- }
- return true;
- }
- bool ParseTag(INameSpace* pns, PCC& pcc, PCC pccEnd)
- {
- pcc++;
- if (pcc == pccEnd) {
- return Error("End of string");
- }
- //
- // << or <>
- //
- if (*pcc == '<' || *pcc == '>') {
- InsertWord(pcc, pcc+1);
- pcc++;
- return true;
- }
- //
- // <xff>
- //
- if (*pcc == 'x') {
- pcc++;
- char ch = ReadHexNumber(pcc, 2);
- InsertWord(&ch, (&ch) + 1);
- if (pcc == pccEnd || pcc[0] != '>') {
- return Error("Expected '>'");
- }
-
- pcc++;
- return true;
- }
- //
- // <!comment>
- //
- if (*pcc == '!') {
- return ParseComment(pcc, pccEnd);
- }
- //
- // <p>
- //
- if (*pcc == 'p') {
- if (pcc == pccEnd || pcc[1] != '>') {
- return Error("Expected '>'");
- }
- InsertAtBottom(new Pane(NULL, WinPoint(0, m_pfontDefault->GetHeight())));
- pcc += 2;
- return true;
- }
- //
- // Get the tag
- //
- ZString strTag;
- if (!ParseSymbol(pcc, pccEnd, '|', strTag)) {
- return false;
- }
- //
- // <Color|color>
- // <Font|smallFont>
- // <Image|image>
- // <Main|topic|text>
- // <Secondary|topic|text>
- // <Bullet|image|text>
- // <String|identifier>
- //
- ZString str;
- if (strTag == "Color") {
- if (!ParseSymbol(pcc, pccEnd, '>', str)) {
- return false;
- }
- TRef<ColorValue> pcolor; CastTo(pcolor, pns->FindMember(str));
- if (pcolor) {
- m_color = pcolor->GetValue();
- return true;
- } else {
- return Error("Invalid color");
- }
- } else if (strTag == "String") {
- if (!ParseSymbol(pcc, pccEnd, '>', str)) {
- return false;
- }
- TRef<StringValue> pstring; CastTo(pstring, pns->FindMember(str));
- if (pstring) {
- InsertString(pstring->GetValue());
- return true;
- } else {
- return Error("undefined identifier '" + str + "'");
- }
- } else if (strTag == "Include") {
- if (!ParseSymbol(pcc, pccEnd, '|', str)) {
- return false;
- }
- ZString strFile;
- if (!ParseSymbol(pcc, pccEnd, '>', strFile)) {
- return false;
- }
- return Include(pns, str, strFile);
- } else if (strTag == "Font") {
- if (!ParseSymbol(pcc, pccEnd, '>', str)) {
- return false;
- }
- TRef<FontValue> pfont; CastTo(pfont, pns->FindMember(str));
- if (pfont) {
- m_pfont = pfont->GetValue();
- return true;
- } else {
- return Error("Invalid font");
- }
- } else if (strTag == "Image") {
- if (!ParseSymbol(pcc, pccEnd, '>', str)) {
- return false;
- }
- TRef<Image> pimage = m_pmodeler->LoadImage(str + "bmp", true, false);
- if (pimage) {
- InsertAtBottom(new ImagePane(pimage));
- return true;
- } else {
- return Error("Invalid image");
- }
- } else if (strTag == "Main") {
- return InsertLink(pcc, pccEnd, m_colorMain, m_peventSourceMain);
- } else if (strTag == "Secondary") {
- return InsertLink(pcc, pccEnd, m_colorSecondary, m_peventSourceSecondary);
- } else if (strTag == "Bullet") {
- return ParseBullet(pns, pcc, pccEnd);
- }
- return Error("Unknown tag: " + strTag);
- }
- void ParseWord(PCC& pcc, PCC pccEnd)
- {
- PCC pccStart = pcc;
- while (
- pcc < pccEnd
- && *pcc != ' '
- && *pcc != '\t'
- && *pcc != '<'
- && *pcc != 10
- && *pcc != 13
- ) {
- pcc++;
- }
- InsertWord(pccStart, pcc);
- }
- void SkipWhite(PCC& pcc, PCC pccEnd)
- {
- while (
- pcc < pccEnd
- && (
- *pcc == ' '
- || *pcc == 10
- || *pcc == 13
- )
- ) {
- pcc++;
- }
- }
- void Parse(INameSpace* pns, PCC pccStart, PCC pccEnd)
- {
- PCC pcc = pccStart;
- //
- // Find all the words
- //
- SkipWhite(pcc, pccEnd);
- while (pcc < pccEnd) {
- if (*pcc == '<') {
- //
- // It's a tag
- //
- if (!ParseTag(pns, pcc, pccEnd)) {
- return;
- }
- } else if (*pcc == '\t') {
- //
- // It's a tab
- //
-
- pcc++;
- InsertTab();
- } else {
- //
- // It's a word
- //
-
- ParseWord(pcc, pccEnd);
- }
- SkipWhite(pcc, pccEnd);
- }
- }
- void Parse(INameSpace* pns, const ZString& str)
- {
- Parse(pns, &str[0], (&str[0]) + str.GetLength());
- }
- void FixupLineY(Pane* ppaneFirst, Pane* ppaneLast, int ysize)
- {
- for (Pane* ppane = ppaneFirst; ppane != ppaneLast; ppane = ppane->Next()) {
- InternalSetOffset(
- ppane,
- WinPoint(
- ppane->XOffset(),
- ppane->YOffset() + (ysize - ppane->YSize())
- )
- );
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // PagePane methods
- //
- //////////////////////////////////////////////////////////////////////////////
- void SetAttributes(
- IEngineFont* pfont,
- const Color& color,
- const Color& colorMain,
- const Color& colorSecondary,
- const Color& colorHighlight
- ) {
- m_pfontDefault = pfont;
- m_colorDefault = color;
- m_colorMain = colorMain;
- m_colorSecondary = colorSecondary;
- m_colorHighlight = colorHighlight;
- }
- TRef<IStringEventSource> GetMainLinkEventSource()
- {
- return m_peventSourceMain;
- }
- TRef<IStringEventSource> GetSecondaryLinkEventSource()
- {
- return m_peventSourceSecondary;
- }
- void SetTopic(INameSpace* pns, const ZString& str)
- {
- RemoveAllChildren();
- m_color = m_colorDefault;
- m_pfont = m_pfontDefault;
- TRef<ZFile> pfile = m_pmodeler->LoadFile(str, "mml", false);
- if (pfile) {
- if (pfile->GetLength() > 0) {
- PCC pcc = (PCC)(pfile->GetPointer());
- Parse(pns, pcc, pcc + pfile->GetLength());
- }
- } else {
- ZString str("<Color|red>Error: Can't open file '" + str + "'");
- Parse(pns, PCC(str), PCC(str) + str.GetLength());
- }
- }
- void SetTopicText(INameSpace* pns, const ZString& str)
- {
- RemoveAllChildren();
- m_color = m_colorDefault;
- m_pfont = m_pfontDefault;
- PCC pcc = str;
- Parse(pns, pcc, pcc + str.GetLength());
- }
- void SetPagePaneIncluder(PagePaneIncluder* ppagePaneIncluder)
- {
- m_ppagePaneIncluder = ppagePaneIncluder;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Pane methods
- //
- //////////////////////////////////////////////////////////////////////////////
- void UpdateLayout()
- {
- //
- // Update the size of all the children
- //
- Pane* ppane;
- for(ppane = Child(); ppane != NULL; ppane = ppane->Next()) {
- InternalSetExpand(ppane, WinPoint(0, 0));
- ppane->UpdateLayout();
- }
- //
- // Flow the words
- //
- int xsize = XExpand();
- int ysizeLine = 0;
- int x = 0;
- int y = 0;
- Pane* ppaneLine = Child();
- for(ppane = Child(); ppane != NULL; ppane = ppane->Next()) {
- //
- // Go to the next line?
- //
- int xsizePane = ppane->GetAlignedXSize(x);
- if (
- xsizePane == 0
- || (
- x + xsizePane > xsize
- && x != 0
- )
- ) {
- //
- // Doesn't fit on this line.
- //
- FixupLineY(ppaneLine, ppane, ysizeLine);
- y += ysizeLine;
- x = 0;
- ysizeLine = 0;
- ppaneLine = ppane;
- }
- //
- // Place the word
- //
- InternalSetOffset(ppane, WinPoint(x, y));
- x += xsizePane;
- ysizeLine = max(ysizeLine, ppane->YSize());
- }
- //
- // fixup the last line
- //
- FixupLineY(ppaneLine, NULL, ysizeLine);
- //
- // This panes's size
- //
- InternalSetSize(WinPoint(xsize, y + ysizeLine));
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- //
- //
- //////////////////////////////////////////////////////////////////////////////
- class ScrollingPanePane :
- public Pane,
- public IIntegerEventSink
- {
- private:
- TRef<ScrollPane> m_pscroll;
- TRef<Pane> m_ppane;
- TRef<IIntegerEventSink> m_pintegerEventSink;
- //TRef<ModifiablePointValue> m_ppoint;
- public:
- ScrollingPanePane(Pane* ppane, const WinPoint& size, ScrollPane* pscroll) :
- m_ppane(ppane),
- m_pscroll(pscroll)
- {
- InternalSetSize(size);
- InsertAtBottom(ppane);
- /*
- m_ppoint = new ModiablePointValue(Point(0, 0));
- InsertAtBotttom(
- new AnimatedImagePane(
- new PaneImage(
- new AnimatedImagePaneRect(
- new TranslateImage(
- pimage,
- m_ppoint
- ),
- rect
- ),
- false,
- true
- )
- )
- );
- */
- if (m_pscroll) {
- m_pscroll->GetEventSource()->AddSink(
- m_pintegerEventSink = IIntegerEventSink::CreateDelegate(this)
- );
- }
- }
- ~ScrollingPanePane()
- {
- if (m_pscroll) {
- m_pscroll->GetEventSource()->RemoveSink(m_pintegerEventSink);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Implementation methods
- //
- //////////////////////////////////////////////////////////////////////////////
- bool OnEvent(IIntegerEventSource* pevent, int value)
- {
- NeedPaint();
- NeedLayout();
- return true;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Pane methods
- //
- //////////////////////////////////////////////////////////////////////////////
- void UpdateLayout()
- {
- InternalSetOffset(m_ppane, WinPoint(0, -m_pscroll->GetPos()));
- m_ppane->UpdateLayout();
- m_pscroll->SetLineSize(8);
- m_pscroll->SetSizes(
- m_ppane->YSize(),
- YSize()
- );
- }
- void Paint(Surface* psurface)
- {
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // PagePane Wrapper
- //
- //////////////////////////////////////////////////////////////////////////////
- class PagePaneWrapper : public PagePane {
- private:
- TRef<PagePane> m_ppagePane;
- public:
- PagePaneWrapper(Modeler* pmodeler, const WinPoint& size, ScrollPane* pscrollPane)
- {
- m_ppagePane = new PagePaneImpl(pmodeler, size.X(), NULL, NULL);
- TRef<Pane> ppane =
- new JustifyPane(
- JustifyPane::Left | JustifyPane::Top,
- size,
- m_ppagePane
- );
- if (pscrollPane) {
- InsertAtBottom(
- new ScrollingPanePane(
- ppane,
- size,
- pscrollPane
- )
- );
- } else {
- InsertAtBottom(ppane);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // PagePane methods
- //
- //////////////////////////////////////////////////////////////////////////////
- void SetAttributes(
- IEngineFont* pfont,
- const Color& color,
- const Color& colorMain,
- const Color& colorSecondary,
- const Color& colorHighlight
- ) {
- m_ppagePane->SetAttributes(
- pfont,
- color,
- colorMain,
- colorSecondary,
- colorHighlight
- );
- }
- TRef<IStringEventSource> GetMainLinkEventSource()
- {
- return m_ppagePane->GetMainLinkEventSource();
- }
- TRef<IStringEventSource> GetSecondaryLinkEventSource()
- {
- return m_ppagePane->GetSecondaryLinkEventSource();
- }
- void SetTopic(INameSpace* pns, const ZString& str)
- {
- m_ppagePane->SetTopic(pns, str);
- }
- void SetTopicText(INameSpace* pns, const ZString& str)
- {
- m_ppagePane->SetTopicText(pns, str);
- }
- void SetPagePaneIncluder(PagePaneIncluder* ppagePaneIncluder)
- {
- m_ppagePane->SetPagePaneIncluder(ppagePaneIncluder);
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Pane methods
- //
- //////////////////////////////////////////////////////////////////////////////
- void UpdateLayout()
- {
- DefaultUpdateLayout();
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Factories
- //
- //////////////////////////////////////////////////////////////////////////////
- class PagePaneFactory : public IFunction {
- private:
- TRef<Modeler> m_pmodeler;
- public:
- PagePaneFactory(Modeler* pmodeler) :
- m_pmodeler(pmodeler)
- {
- }
- TRef<IObject> Apply(ObjectStack& stack)
- {
- TRef<PointValue> psize; CastTo(psize, (IObject*)stack.Pop());
- TRef<ScrollPane> pscrollPane; CastTo(pscrollPane, (Pane*)(IObject*)stack.Pop());
- return new PagePaneWrapper(m_pmodeler, WinPoint::Cast(psize->GetValue()), pscrollPane);
- }
- };
- void AddPagePaneFactory(
- INameSpace* pns,
- Modeler* pmodeler
- ) {
- pns->AddMember("PagePane", new PagePaneFactory(pmodeler));
- }
|