4#include "Stroika/Frameworks/StroikaPreComp.h"
13#include "StandardStyledTextImager.h"
15#include "HiddenText.h"
20using namespace Stroika::Frameworks;
21using namespace Stroika::Frameworks::Led;
28HidableTextMarkerOwner::HidableTextMarkerOwner (TextStore& textStore)
29 : fTextStore{textStore}
31 SetInternalizer (
nullptr);
32 SetExternalizer (
nullptr);
33 fTextStore.AddMarkerOwner (
this);
36HidableTextMarkerOwner::~HidableTextMarkerOwner ()
38 Require (fMarkersToBeDeleted.IsEmpty ());
40 MarkerList markers = CollectAllInRange (0, fTextStore.GetLength () + 1);
41 if (not markers.empty ()) {
44 copy (markers.begin (), markers.end (), inserter (tmp, tmp.begin ()));
45 GetTextStore ().RemoveMarkers (Traversal::Iterator2Pointer (tmp.begin ()), tmp.size ());
47 for (
auto i = markers.begin (); i != markers.end (); ++i) {
51 fTextStore.RemoveMarkerOwner (
this);
66void HidableTextMarkerOwner::HideAll ()
68 HideAll (0, fTextStore.GetEnd () + 1);
71void HidableTextMarkerOwner::HideAll (
size_t from,
size_t to)
74 MarkerList markers = CollectAllInRange (from, to);
75 sort (markers.begin (), markers.end (), LessThan<HidableTextMarker> ());
77 for (
auto i = markers.rbegin (); i != markers.rend (); ++i) {
78 if (TextStore::Overlap (**i, from, to)) {
92void HidableTextMarkerOwner::ShowAll ()
94 ShowAll (0, fTextStore.GetEnd () + 1);
97void HidableTextMarkerOwner::ShowAll (
size_t from,
size_t to)
100 MarkerList markers = CollectAllInRange (from, to);
101 sort (markers.begin (), markers.end (), LessThan<HidableTextMarker> ());
103 for (
auto i = markers.rbegin (); i != markers.rend (); ++i) {
104 if (TextStore::Overlap (**i, from, to)) {
105#if qStroika_Foundation_Debug_AssertionsChecked
106 HidableTextMarkerOwner::Invariant_ ();
109#if qStroika_Foundation_Debug_AssertionsChecked
110 HidableTextMarkerOwner::Invariant_ ();
128void HidableTextMarkerOwner::MakeRegionHidable (
size_t from,
size_t to)
130 Require (from <= to);
137 MarkerList hidableTextMarkersInRange = CollectAllInRange (from, to);
140 if (hidableTextMarkersInRange.size () == 1 and hidableTextMarkersInRange[0]->GetStart () <= from and hidableTextMarkersInRange[0]->GetEnd () >= to) {
144 sort (hidableTextMarkersInRange.begin (), hidableTextMarkersInRange.end (), LessThan<HidableTextMarker> ());
146 HidableTextMarker* prevNonEmptyMarker =
nullptr;
149 MarkerList tmp = CollectAllInRange (from - 1, from);
151 for (
auto i = tmp.begin (); i != tmp.end (); ++i) {
152 if ((*i)->IsShown () and (*i)->GetEnd () == from) {
153 prevNonEmptyMarker = *i;
161 TextStore::SimpleUpdater updater{fTextStore, from, to};
164 for (
auto i = hidableTextMarkersInRange.begin (); i != hidableTextMarkersInRange.end (); ++i) {
166 if (prevNonEmptyMarker ==
nullptr) {
167 Assert (i == hidableTextMarkersInRange.begin ());
168 prevNonEmptyMarker = *i;
170 DISABLE_COMPILER_MSC_WARNING_START (6011)
171 if (from < prevNonEmptyMarker->GetStart ()) {
172 if (prevNonEmptyMarker->IsShown ()) {
173 fTextStore.SetMarkerStart (prevNonEmptyMarker, from);
177 Assert (prevNonEmptyMarker->GetStart () > from);
178 GetTextStore ().AddMarker (MakeHidableTextMarker (), from, prevNonEmptyMarker->GetStart () - from,
this);
181 DISABLE_COMPILER_MSC_WARNING_END (6011)
183 else if (prevNonEmptyMarker->IsShown ()) {
185 fMarkersToBeDeleted.AccumulateMarkerForDeletion (*i);
188 if (prevNonEmptyMarker ==
nullptr) {
189 GetTextStore ().AddMarker (MakeHidableTextMarker (), from, to - from,
this);
192 if (prevNonEmptyMarker->GetEnd () < to) {
193 if (prevNonEmptyMarker->IsShown ()) {
194 fTextStore.SetMarkerEnd (prevNonEmptyMarker, to);
198 Assert (to > prevNonEmptyMarker->GetEnd ());
199 GetTextStore ().AddMarker (MakeHidableTextMarker (), prevNonEmptyMarker->GetEnd (), to - prevNonEmptyMarker->GetEnd (),
this);
214void HidableTextMarkerOwner::MakeRegionUnHidable (
size_t from,
size_t to)
216 Require (from <= to);
223 MarkerList hidableTextMarkersInRange = CollectAllInRange (from, to);
225 if (hidableTextMarkersInRange.empty ()) {
229 TempMarker pastSelMarker (GetTextStore (), to + 1, to + 1);
233 TextStore::SimpleUpdater updater{fTextStore, from, to};
235 sort (hidableTextMarkersInRange.begin (), hidableTextMarkersInRange.end (), LessThan<HidableTextMarker>{});
239 for (
auto i = hidableTextMarkersInRange.begin (); i != hidableTextMarkersInRange.end (); ++i) {
240 if (i == hidableTextMarkersInRange.begin () and (*i)->GetStart () < from) {
243 size_t oldEnd = (*i)->GetEnd ();
244 fTextStore.SetMarkerEnd (*i, from);
246 fTextStore.AddMarker (MakeHidableTextMarker (), to, oldEnd - to,
this);
249 else if (i + 1 == hidableTextMarkersInRange.end () and (*i)->GetEnd () > to) {
251 fTextStore.SetMarkerStart (*i, to);
254 fMarkersToBeDeleted.AccumulateMarkerForDeletion (*i);
267 TextStore::SimpleUpdater updater{fTextStore, to, pastSelMarker.GetEnd ()};
283DiscontiguousRun<bool> HidableTextMarkerOwner::GetHidableRegions (
size_t from,
size_t to)
const
286 DiscontiguousRun<bool> result;
287 MarkerList markers = CollectAllInRange (from, to);
288 sort (markers.begin (), markers.end (), LessThan<HidableTextMarker> ());
289 size_t relStartFrom = from;
290 for (
auto i = markers.begin (); i != markers.end (); ++i) {
293 (*i)->GetRange (&mStart, &mEnd);
295 mStart = max (mStart, relStartFrom);
296 mEnd = min (mEnd, to);
297 Assert (mStart < mEnd);
298 result.push_back (DiscontiguousRunElement<bool> (mStart - relStartFrom, mEnd - mStart, (*i)->IsShown ()));
305DiscontiguousRun<bool> HidableTextMarkerOwner::GetHidableRegions ()
const
307 return GetHidableRegions (0, fTextStore.GetEnd () + 1);
315bool HidableTextMarkerOwner::GetHidableRegionsContiguous (
size_t from,
size_t to,
bool hidden)
const
319 DiscontiguousRun<bool> tmpHack = GetHidableRegions (from, to);
320 if (tmpHack.size () == 1) {
321 return tmpHack[0].fData == hidden and tmpHack[0].fOffsetFromPrev == 0 and tmpHack[0].fElementLength >= to - from;
328 return tmpHack.size () == 0;
338void HidableTextMarkerOwner::SetInternalizer (
const shared_ptr<FlavorPackageInternalizer>& i)
341 if (fInternalizer ==
nullptr) {
342 fInternalizer = make_shared<FlavorPackageInternalizer> (GetTextStore ());
351void HidableTextMarkerOwner::SetExternalizer (
const shared_ptr<FlavorPackageExternalizer>& e)
354 if (fExternalizer ==
nullptr) {
355 fExternalizer = make_shared<FlavorPackageExternalizer> (GetTextStore ());
363void HidableTextMarkerOwner::CollapseMarker (HidableTextMarker* m)
369 m->GetRange (&start, &end);
370 TextStore::SimpleUpdater updater{fTextStore, start, end,
false};
378void HidableTextMarkerOwner::ReifyMarker (HidableTextMarker* m)
381 Require (not m->fShown);
385 m->GetRange (&start, &end);
387 TextStore::SimpleUpdater updater (fTextStore, start, end,
false);
399HidableTextMarkerOwner::HidableTextMarker* HidableTextMarkerOwner::MakeHidableTextMarker ()
418 return new LightUnderlineHidableTextMarker{};
421TextStore* HidableTextMarkerOwner::PeekAtTextStore ()
const
426void HidableTextMarkerOwner::AboutToUpdateText (
const UpdateInfo& updateInfo)
429 Assert (fMarkersToBeDeleted.IsEmpty ());
430 inherited::AboutToUpdateText (updateInfo);
433void HidableTextMarkerOwner::DidUpdateText (
const UpdateInfo& updateInfo)
noexcept
435 inherited::DidUpdateText (updateInfo);
436 if (updateInfo.fTextModified) {
438 MarkerList markers = CollectAllInRange_OrSurroundings (updateInfo.fReplaceFrom, updateInfo.GetResultingRHS ());
439 for (
auto i = markers.begin (); i != markers.end (); ++i) {
440 HidableTextMarker* m = *i;
441 if (m->GetLength () == 0) {
442 fMarkersToBeDeleted.AccumulateMarkerForDeletion (m);
446 fMarkersToBeDeleted.FinalizeMarkerDeletions ();
450HidableTextMarkerOwner::MarkerList HidableTextMarkerOwner::CollectAllInRange (
size_t from,
size_t to)
const
452 MarkersOfATypeMarkerSink2Vector<HidableTextMarker> result;
453 fTextStore.CollectAllMarkersInRangeInto (from, to,
this, result);
454 return result.fResult;
457HidableTextMarkerOwner::MarkerList HidableTextMarkerOwner::CollectAllInRange_OrSurroundings (
size_t from,
size_t to)
const
459 MarkersOfATypeMarkerSink2Vector<HidableTextMarker> result;
460 fTextStore.CollectAllMarkersInRangeInto_OrSurroundings (from, to,
this, result);
461 return result.fResult;
464#if qStroika_Foundation_Debug_AssertionsChecked
465void HidableTextMarkerOwner::Invariant_ ()
const
467 MarkerList markers = CollectAllInRange (0, fTextStore.GetEnd () + 1);
469 sort (markers.begin (), markers.end (), LessThan<HidableTextMarker> ());
476 for (
size_t i = 0; i < markers.size (); i++) {
477 HidableTextMarker* m = markers[i];
478 Assert (m->GetLength () > 0);
479 Assert (m->GetStart () >= lastEnd);
480 lastEnd = m->GetEnd ();
482 Assert (lastEnd <= fTextStore.GetLength () + 1);
491HidableTextMarkerOwner::LightUnderlineHidableTextMarker::LightUnderlineHidableTextMarker (
const IncrementalFontSpecification& fsp)
493 fFontSpecification = fsp;
496Color HidableTextMarkerOwner::LightUnderlineHidableTextMarker::GetUnderlineBaseColor ()
const
498 if (fFontSpecification.GetTextColor_Valid ()) {
499 return fFontSpecification.GetTextColor ();
502 return inherited::GetUnderlineBaseColor ();
511UniformHidableTextMarkerOwner::UniformHidableTextMarkerOwner (TextStore& textStore)
512 : inherited{textStore}
516void UniformHidableTextMarkerOwner::HideAll ()
519 inherited::HideAll ();
524void UniformHidableTextMarkerOwner::ShowAll ()
527 inherited::ShowAll ();
532void UniformHidableTextMarkerOwner::MakeRegionHidable (
size_t from,
size_t to)
534 Require (from <= to);
537 inherited::MakeRegionHidable (from, to);
539 inherited::HideAll ();
542 inherited::ShowAll ();
546#if qStroika_Frameworks_Led_SupportGDI
552FontSpecification HidableTextMarkerOwner::FontSpecHidableTextMarker::MakeFontSpec (
const StyledTextImager* ,
const StyleRunElement& runElement)
const
555 for (
auto i = runElement.fSupercededMarkers.begin (); i != runElement.fSupercededMarkers.end (); ++i) {
556 if (StandardStyleMarker* m =
dynamic_cast<StandardStyleMarker*
> (*i)) {
557 fsp.MergeIn (m->fFontSpecification);
560 fsp.MergeIn (fFontSpecification);
570void ColoredUniformHidableTextMarkerOwner::FixupSubMarkers ()
573 MarkerList markers = CollectAllInRange_OrSurroundings (0, GetTextStore ().GetEnd () + 1);
574 for (
auto i = markers.begin (); i != markers.end (); ++i) {
575 LightUnderlineHidableTextMarker* m =
dynamic_cast<LightUnderlineHidableTextMarker*
> (*i);
578 m->fFontSpecification.SetTextColor (fColor);
581 m->fFontSpecification.InvalidateTextColor ();
586ColoredUniformHidableTextMarkerOwner::HidableTextMarker* ColoredUniformHidableTextMarkerOwner::MakeHidableTextMarker ()
588 IncrementalFontSpecification fontSpec;
590 fontSpec.SetTextColor (fColor);
592 return new LightUnderlineHidableTextMarker (fontSpec);
#define RequireNotNull(p)