public override void RemoveFromView(object obj) { BorderView.RemoveAsSubview(obj); QuoteLabel.RemoveAsSubview(obj); Citation.RemoveAsSubview(obj); UrlGlyph.RemoveAsSubview(obj); TryRemoveDebugLayer(obj); }
public override void AddToView(object obj) { BorderView.AddAsSubview(obj); QuoteLabel.AddAsSubview(obj); Citation.AddAsSubview(obj); UrlGlyph.AddAsSubview(obj); TryAddDebugLayer(obj); }
public void SetPosition(float xPos, float yPos) { // we're not moving if we're in edit mode if (EditMode_Enabled == false) { // first, let the Citation + Glyph define the minimum width this control can be Citation.Frame = new RectangleF( ); Citation.SizeToFit( ); if (string.IsNullOrEmpty(ActiveUrl) == false) { UrlGlyph.Text = PrivateNoteConfig.CitationUrl_Icon; } else { UrlGlyph.Text = string.Empty; } UrlGlyph.SizeToFit( ); // // clamp the yPos to the vertical bounds of our parent yPos = Math.Max(yPos, ParentNote.Padding.Top); // now left, which is easy xPos = Math.Max(xPos, ParentNote.Padding.Left); // Now do the right edge. This is tricky because we will allow this control to move forward // until it can't wrap any more. Then, we'll clamp its movement to the parent's edge. // Get the width of the widest child, which is always the citation plus glyph. float minRequiredWidth = UrlGlyph.Frame.Width + (BorderPaddingPx * 2) + Padding.Left + Padding.Width; // now, if the control cannot wrap any further, we want to clamp its movement // to the parent's right edge // Right Edge Check xPos = Math.Min(xPos, ParentSize.Width - ParentNote.Padding.Right - minRequiredWidth); float xOffset = xPos - Frame.Left; float yOffset = yPos - Frame.Top; base.AddOffset(xOffset, yOffset); // now update the actual width and height of the Quote based on the available width remaining // our width remaining is the parent's right edge minus the control's left edge minus all padding. float availableWidth = (ParentSize.Width - ParentNote.Padding.Right) - Frame.Left - Padding.Left - Padding.Width - (BorderPaddingPx * 2); QuoteLabel.Frame = new RectangleF(QuoteLabel.Frame.Left, QuoteLabel.Frame.Top, Math.Max(minRequiredWidth, availableWidth), 0); QuoteLabel.SizeToFit( ); Citation.Frame = new RectangleF(Citation.Frame.Left, Citation.Frame.Top, Math.Max(minRequiredWidth, availableWidth), 0); Citation.SizeToFit( ); UrlGlyph.Frame = new RectangleF(Citation.Frame.Right, Citation.Frame.Top, Math.Max(0, (availableWidth - Citation.Frame.Right)), 0); UrlGlyph.SizeToFit( ); // now that we know our text size, we can adjust the citation // for citation width, attempt to use quote width, but if there was no quote text, // the width will be 0, so we'll fallback to the citation width. RectangleF frame; if (string.IsNullOrEmpty(QuoteLabel.Text) != true) { // when taking the citation frame, put it at the left edge of the quote, // because if it's longer than the quote we'll want the bounding frame to use // its width as opposed to the quote's width. Citation.Frame = new RectangleF(QuoteLabel.Frame.Left, QuoteLabel.Frame.Bottom, Citation.Frame.Width, Citation.Frame.Height); UrlGlyph.Frame = new RectangleF(Citation.Frame.Right, Citation.Frame.Top - ((UrlGlyph.Frame.Height - Citation.Frame.Height) / 2), UrlGlyph.Frame.Width, UrlGlyph.Frame.Height); RectangleF citationGlyphFrame = Parser.CalcBoundingFrame(Citation.Frame, UrlGlyph.Frame); // get a bounding frame for the quote and citation frame = Parser.CalcBoundingFrame(QuoteLabel.Frame, citationGlyphFrame); // now right-adjust it IF it's smaller than the quote if (citationGlyphFrame.Width < QuoteLabel.Frame.Width) { Citation.Position = new PointF(QuoteLabel.Frame.Right - citationGlyphFrame.Width, Citation.Position.Y); UrlGlyph.Position = new PointF(Citation.Frame.Right, UrlGlyph.Frame.Top); } } else { Citation.Frame = new RectangleF(QuoteLabel.Frame.Left, QuoteLabel.Frame.Top, Citation.Frame.Width, Citation.Frame.Height); UrlGlyph.Frame = new RectangleF(Citation.Frame.Right, Citation.Frame.Top - ((UrlGlyph.Frame.Height - Citation.Frame.Height) / 2), UrlGlyph.Frame.Width, UrlGlyph.Frame.Height); // get a bounding frame for the quote and citation frame = Parser.CalcBoundingFrame(Citation.Frame, UrlGlyph.Frame); } Citation.TextAlignment = TextAlignment.Right; // reintroduce vertical padding frame.Height = frame.Height + Padding.Top + Padding.Height; // setup our bounding rect for the border // because we're basing it off of the largest control (quote or citation), // we need to reintroduce the border padding. frame = new RectangleF(frame.X - BorderPaddingPx - Padding.Left, frame.Y - BorderPaddingPx - Padding.Top, frame.Width + (Padding.Width * 2) + (BorderPaddingPx * 2), frame.Height + (Padding.Height) + BorderPaddingPx); // and store that as our bounds BorderView.Frame = frame; Frame = frame; SetDebugFrame(Frame); } }
public Quote(CreateParams parentParams, XmlReader reader) { Initialize( ); // Always get our style first mStyle = parentParams.Style; Styles.Style.ParseStyleAttributesWithDefaults(reader, ref mStyle, ref ControlStyles.mQuote); // check for attributes we support RectangleF bounds = new RectangleF( ); SizeF parentSize = new SizeF(parentParams.Width, parentParams.Height); ParseCommonAttribs(reader, ref parentSize, ref bounds); // Get margins and padding RectangleF padding; RectangleF margin; GetMarginsAndPadding(ref mStyle, ref parentSize, ref bounds, out margin, out padding); // apply margins to as much of the bounds as we can (bottom must be done by our parent container) ApplyImmediateMargins(ref bounds, ref margin, ref parentSize); Margin = margin; // create the font that either we or our parent defined QuoteLabel.SetFont(mStyle.mFont.mName, mStyle.mFont.mSize.Value); Citation.SetFont(mStyle.mFont.mName, mStyle.mFont.mSize.Value); QuoteLabel.TextColor = mStyle.mFont.mColor.Value; Citation.TextColor = mStyle.mFont.mColor.Value; Citation.BackgroundColor = 0; QuoteLabel.BackgroundColor = 0; UrlGlyph.Text = PrivateNoteConfig.CitationUrl_Icon; UrlGlyph.TextColor = mStyle.mFont.mColor.Value; UrlGlyph.SetFont(PrivateControlStylingConfig.Icon_Font_Secondary, mStyle.mFont.mSize.Value); UrlGlyph.BackgroundColor = 0; // check for border styling int borderPaddingPx = 0; if (mStyle.mBorderColor.HasValue) { BorderView.BorderColor = mStyle.mBorderColor.Value; } if (mStyle.mBorderRadius.HasValue) { BorderView.CornerRadius = mStyle.mBorderRadius.Value; } if (mStyle.mBorderWidth.HasValue) { BorderView.BorderWidth = mStyle.mBorderWidth.Value; borderPaddingPx = (int)Rock.Mobile.Graphics.Util.UnitToPx(mStyle.mBorderWidth.Value + PrivateNoteConfig.BorderPadding); } if (mStyle.mBackgroundColor.HasValue) { BorderView.BackgroundColor = mStyle.mBackgroundColor.Value; } // now calculate the available width based on padding. (Don't actually change our width) float availableWidth = bounds.Width - padding.Left - padding.Width - (borderPaddingPx * 2); // Set the bounds and position for the frame (except Height, which we'll calculate based on the text) QuoteLabel.Frame = new RectangleF(bounds.X + padding.Left + borderPaddingPx, bounds.Y + padding.Top + borderPaddingPx, availableWidth, 0); // expect the citation to be an attribute string result = reader.GetAttribute("Citation"); if (string.IsNullOrEmpty(result) == false) { // set and resize the citation to fit Citation.Text = result; Citation.Bounds = new RectangleF(bounds.X + padding.Left + borderPaddingPx, bounds.Y + padding.Top + borderPaddingPx, availableWidth, 0); Citation.SizeToFit( ); } // see if there's a Url attribute, which is where the user should be taken if they tap the link ActiveUrl = reader.GetAttribute("Url"); if (string.IsNullOrEmpty(ActiveUrl) == false) { UrlGlyph.Text = PrivateNoteConfig.CitationUrl_Icon; UrlGlyph.Bounds = new RectangleF(Citation.Frame.Right, Citation.Frame.Top, (availableWidth - Citation.Frame.Right), 0); UrlGlyph.SizeToFit( ); } string urlLaunchesExternalBrowser = reader.GetAttribute("UrlLaunchesExternalBrowser"); if (string.IsNullOrEmpty(urlLaunchesExternalBrowser) == false) { UrlLaunchesExternalBrowser = bool.Parse(urlLaunchesExternalBrowser); } string urlUsesRockImpersonation = reader.GetAttribute("UrlUsesRockImpersonation"); if (string.IsNullOrEmpty(urlUsesRockImpersonation) == false) { UrlUsesRockImpersonation = bool.Parse(urlUsesRockImpersonation); } bool finishedScripture = false; while (finishedScripture == false && reader.IsEmptyElement == false && reader.Read( )) { switch (reader.NodeType) { case XmlNodeType.Text: { // grab the text. remove any weird characters string text = Regex.Replace(reader.Value, @"\t|\n|\r", ""); // now break it into words so we can do word wrapping string[] words = text.Split(' '); foreach (string word in words) { // create labels out of each one if (string.IsNullOrEmpty(word) == false) { QuoteLabel.Text += word + " "; } } break; } case XmlNodeType.EndElement: { // if we hit the end of our label, we're done. //if( reader.Name == "Quote" || reader.Name == "Q" ) if (ElementTagMatches(reader.Name)) { finishedScripture = true; } break; } } } // adjust the text switch (mStyle.mTextCase) { case Styles.TextCase.Upper: { QuoteLabel.Text = QuoteLabel.Text.ToUpper( ); Citation.Text = Citation.Text.ToUpper( ); break; } case Styles.TextCase.Lower: { QuoteLabel.Text = QuoteLabel.Text.ToLower( ); Citation.Text = Citation.Text.ToLower( ); break; } } // We forced the text to fit within the width specified above, so this will simply calculate the height. QuoteLabel.SizeToFit( ); // now that we know our text size, we can adjust the citation // for citation width, attempt to use quote width, but if there was no quote text, // the width will be 0, so we'll fallback to the citation width. RectangleF frame; if (string.IsNullOrEmpty(QuoteLabel.Text) != true) { // when taking the citation frame, put it at the left edge of the quote, // because if it's longer than the quote we'll want the bounding frame to use // its width as opposed to the quote's width. Citation.Frame = new RectangleF(QuoteLabel.Frame.Left, QuoteLabel.Frame.Bottom, Citation.Frame.Width, Citation.Frame.Height); UrlGlyph.Frame = new RectangleF(Citation.Frame.Right, Citation.Frame.Top - ((UrlGlyph.Frame.Height - Citation.Frame.Height) / 2), UrlGlyph.Frame.Width, UrlGlyph.Frame.Height); RectangleF citationGlyphFrame = Parser.CalcBoundingFrame(Citation.Frame, UrlGlyph.Frame); // get a bounding frame for the quote and citation frame = Parser.CalcBoundingFrame(QuoteLabel.Frame, citationGlyphFrame); // now right-adjust it IF it's smaller than the quote if (citationGlyphFrame.Width < QuoteLabel.Frame.Width) { Citation.Position = new PointF(QuoteLabel.Frame.Right - citationGlyphFrame.Width, Citation.Position.Y); UrlGlyph.Position = new PointF(Citation.Frame.Right, UrlGlyph.Frame.Top); } } else { Citation.Frame = new RectangleF(QuoteLabel.Frame.Left, QuoteLabel.Frame.Top, Citation.Frame.Width, Citation.Frame.Height); UrlGlyph.Frame = new RectangleF(Citation.Frame.Right, Citation.Frame.Top - ((UrlGlyph.Frame.Height - Citation.Frame.Height) / 2), UrlGlyph.Frame.Width, UrlGlyph.Frame.Height); // get a bounding frame for the quote and citation frame = Parser.CalcBoundingFrame(Citation.Frame, UrlGlyph.Frame); } Citation.TextAlignment = TextAlignment.Right; // reintroduce vertical padding frame.Height = frame.Height + padding.Top + padding.Height; // setup our bounding rect for the border // because we're basing it off of the largest control (quote or citation), // we need to reintroduce the border padding. frame = new RectangleF(frame.X - borderPaddingPx - padding.Left, frame.Y - borderPaddingPx - padding.Top, frame.Width + (padding.Width * 2) + (borderPaddingPx * 2), frame.Height + (padding.Height) + borderPaddingPx); // and store that as our bounds BorderView.Frame = frame; Frame = frame; SetDebugFrame(Frame); }