// KeysConverter kc = new KeysConverter(); // char Message2CharANSI( Keys _key ) { // int keyValue = (int) _key; // keyValue &= 0x7F; // Ignore culture-specific characters // if ( keyValue < 32 ) // return '\0'; // Unsupported... // // if ( _key == Keys.Shift ) // return '\0'; // // Keys rawKey = (Keys) keyValue; // if ( rawKey == Keys.Space ) // return ' '; // // string C = kc.ConvertToString( rawKey ); // if ( C.Length != 1 ) // return '\0'; // Unsupported... // // // if ( (_key & Keys.Shift) != 0 ) // if ( Control.ModifierKeys == Keys.Shift ) // C = C.ToUpper(); // else // C = C.ToLower(); // // return C[0]; // } private void suggestionForm_SuggestionSelected(object sender, EventArgs e) { m_internalChange++; // Keep a copy of the matched selection as it will get treashed by the Select/Remove operations that follow EditedTag firstMatchedTag = m_firstUnRecognizedTag; EditedTag lastMatchedTag = m_lastUnRecognizedTag; // Select the first tag used for the match & assign the fiche firstMatchedTag.Fiche = m_matches[m_suggestionForm.SelectedSuggestionIndex]; // Remove orphan tags that were part of the match if (firstMatchedTag != lastMatchedTag) { EditedTag currentTag = firstMatchedTag.m_next; while (currentTag != lastMatchedTag && currentTag.m_next != null) { EditedTag tagToRemove = currentTag; currentTag = currentTag.m_next; DeleteTag(tagToRemove, true); } } SelectTag(firstMatchedTag.m_next); m_internalChange--; Invalidate(); }
void DeleteTag(EditedTag _tag, bool _selectPrevious) { if (_tag == null) { return; } if (_tag.m_next == null) { throw new Exception("Can't delete end tag!"); } m_internalChange++; // Link over tag if (m_selectedTag == _tag) { // SelectTag( _tag.m_previous != null ? _tag.m_previous : _tag.m_next ); m_selectedTag = _selectPrevious ? (_tag.m_previous != null ? _tag.m_previous : _tag.m_next) : (_tag.m_next != null ? _tag.m_next : _tag.m_previous); } _tag.Remove(); m_internalChange--; Invalidate(); UpdateSuggestionForm(); }
protected override void OnMouseDown(MouseEventArgs e) { Invalidate(); Focus(); // Select the proper tag according to where they were drawn last EditedTag currentTag = m_selectedTag.First; for (int tagIndex = 0; tagIndex < m_renderedRectangles.Length; tagIndex++) { RectangleF R = m_renderedRectangles[tagIndex]; if (R.Contains(e.Location)) { // Found the selected tag! float clickRatio = (float)(e.X - R.Left) / R.Width; if (currentTag.m_next != null && clickRatio > 0.66f) { currentTag = currentTag.m_next; // If the user clicks too far on the right then select next tag instead... } SelectTag(currentTag); return; } currentTag = currentTag.m_next; } // Select "after last tag" if none was found SelectTag(m_selectedTag.Last); base.OnMouseDown(e); }
/// <summary> /// Removes this tag from the linked-list /// </summary> public void Remove() { if (m_next != null) { m_next.m_previous = m_previous; } if (m_previous != null) { m_previous.m_next = m_next; } m_previous = m_next = null; }
protected override void OnPaintBackground(PaintEventArgs e) { if (m_internalChange > 0) { return; } // base.OnPaintBackground(pevent); e.Graphics.FillRectangle(m_brushBack, e.ClipRectangle); if (m_selectedTag == null) { return; // Nothing to paint... } List <RectangleF> renderedRectangles = new List <RectangleF>(); float X = this.Margin.Left; float Y = this.Margin.Top; int tagIndex = 0; EditedTag currentTag = m_selectedTag.First; while (currentTag != null) { SizeF textSize = e.Graphics.MeasureString(currentTag.m_tagString, this.Font, this.Width, m_stringFormat); RectangleF R = new RectangleF(X, Y, textSize.Width, textSize.Height); if (currentTag.Fiche != null) { R.X += 4; // Include a little margin for tags RectangleF backgroundR = R; backgroundR.X -= 2; backgroundR.Y -= 2; backgroundR.Width += 4; backgroundR.Height += 4; textSize.Width += 8; e.Graphics.FillRectangle(currentTag == m_selectedTag ? m_brushTagSelected : m_brushTag, backgroundR); } if (currentTag == m_selectedTag) { e.Graphics.DrawLine(Pens.Black, X, this.Margin.Top - 1, X, Height - this.Margin.Bottom - 1); } renderedRectangles.Add(R); X += textSize.Width; currentTag = currentTag.m_next; tagIndex++; } m_renderedRectangles = renderedRectangles.ToArray(); }
void SelectTag(EditedTag _tag) { if (_tag == m_selectedTag) { return; } m_selectedTag = _tag; Invalidate(); UpdateSuggestionForm(); }
/// <summary> /// Attempts to update the suggestion form with the currently entered string /// </summary> void UpdateSuggestionForm() { if (m_selectedTag == null) { m_suggestionForm.Visible = false; return; } // Retrieve the currently unrecognized tag for the character we just typed m_firstUnRecognizedTag = null; m_lastUnRecognizedTag = m_selectedTag.FirstUnRecognized; if (m_lastUnRecognizedTag == null) { m_suggestionForm.Visible = false; return; } string unRecognizedTagName = null; do { m_firstUnRecognizedTag = m_lastUnRecognizedTag; m_lastUnRecognizedTag = m_firstUnRecognizedTag.CollateUnRecognizedTags(out unRecognizedTagName); } while (!m_firstUnRecognizedTag.ContainsTag(m_lastUnRecognizedTag, m_selectedTag)); m_matches.Clear(); if (unRecognizedTagName != null) { // Handle auto-completion m_applicationForm.Database.FindNearestTagMatches(unRecognizedTagName, RecognizedTags, m_matches); if (m_matches.Count > 0) { // Show potential matches string[] matchStrings = new string[Math.Min(MAX_MATCHES, m_matches.Count)]; for (int matchIndex = 0; matchIndex < matchStrings.Length; matchIndex++) { matchStrings[matchIndex] = m_matches[matchIndex].Title; } m_suggestionForm.UpdateList(matchStrings, 10); } } if (!m_suggestionForm.Visible && m_matches.Count > 0) { m_suggestionForm.Show(this); this.Focus(); // We must keep the focus! } m_suggestionForm.Visible = m_matches.Count > 0; }
/// <summary> /// Checks if the list from this tag to the provided _endTag contains the _tag tag /// </summary> /// <param name="_endTag">Tag marking the end of the list</param> /// <param name="_tag">The tag to check as part of the linked-list</param> /// <returns></returns> public bool ContainsTag(EditedTag _endTag, EditedTag _tag) { EditedTag currentTag = this; while (currentTag != null && currentTag != _endTag) { if (currentTag == _tag) { return(true); // Found it } currentTag = currentTag.m_next; } return(false); }
protected override void OnKeyPress(KeyPressEventArgs e) { base.OnKeyPress(e); // BrainForm.Debug( "KeyPress => " + (((int) e.KeyChar) >= 32 ? e.KeyChar.ToString() // : ("0x" + ((int) e.KeyChar).ToString( "X2" ))) // ); // Create a brand new edited tag that will host the text typed in by the user EditedTag newTag = new EditedTag(null, m_selectedTag); newTag.m_tagString = e.KeyChar.ToString(); UpdateSuggestionForm(); Invalidate(); }
/// <summary> /// Starts from this tag and collate individual strings forkward until a tag separator is found so we obtain the full name of an unrecognized tag /// </summary> /// <param name="_tagName">The new unrecognized tag name</param> /// <returns>The tag where we ended up the collation</returns> public EditedTag CollateUnRecognizedTags(out string _tagName) { _tagName = null; bool isComplexName = false; EditedTag currentTag = this; while (currentTag != null) { if (currentTag.Fiche != null) { break; // This is a recognized tag, break here... } // Check for double-quotes that mark either the start or end of a complex tag name if (currentTag.m_tagString == "\"") { currentTag = currentTag.m_next; // Always skip double quote if (isComplexName) { break; // End marker! } else { isComplexName = true; // Start marker! } } else { // Check for space separators that mark the end of a simple tag name if (!isComplexName && (currentTag.m_tagString == " " || currentTag.m_tagString == "\t")) { // End marker that we need to skip currentTag = currentTag.m_next; break; } } // Append tag's string to current tag name and proceed _tagName += currentTag.m_tagString; currentTag = currentTag.m_next; } return(currentTag); }
/// <summary> /// Inserts THIS before _tag /// </summary> /// <param name="_tag"></param> public void InsertBefore(EditedTag _tag) { if (_tag == null) { m_next = null; m_previous = null; return; } m_next = _tag; m_previous = _tag.m_previous; if (m_next != null) { m_next.m_previous = this; } if (m_previous != null) { m_previous.m_next = this; } }
}; //, FormatFlags = StringFormatFlags.NoClip }; void Init() { m_suggestionForm.SuggestionSelected += suggestionForm_SuggestionSelected; m_brushBack = new SolidBrush(this.BackColor); m_brushTag = new SolidBrush(Color.IndianRed); m_brushTagSelected = new SolidBrush(Color.RosyBrown); m_stringFormat.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces; SetStyle(ControlStyles.Selectable, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.EnableNotifyMessage, true); SetStyle(ControlStyles.ContainerControl, false); this.DoubleBuffered = true; // Create the end tag (not editable, not deletable, can't go past it) m_selectedTag = new EditedTag(null, null); this.Select(); }
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (m_internalChange > 0) { return; } int tagIndex = 0; EditedTag currentTag = m_selectedTag.First; while (currentTag != null && tagIndex < m_renderedRectangles.Length) { RectangleF R = m_renderedRectangles[tagIndex++]; if (R.Contains(e.Location)) { HoveredTag = currentTag; return; } currentTag = currentTag.m_next; } HoveredTag = null; }
protected override void OnPaint(PaintEventArgs e) { if (m_internalChange > 0) { return; } // base.OnPaint(e); int tagIndex = 0; EditedTag currentTag = m_selectedTag.First; while (currentTag != null) { RectangleF R = m_renderedRectangles[tagIndex++]; e.Graphics.DrawString(currentTag.m_tagString, this.Font, Brushes.Black, R, m_stringFormat); currentTag = currentTag.m_next; } if (!m_suggestionForm.Visible || m_firstUnRecognizedTag == null || m_firstUnRecognizedTag.Index >= m_renderedRectangles.Length) { return; } // Locate either above or below the edit box depending on screen position Point screenBottomLeft = this.PointToScreen(Point.Empty); screenBottomLeft.Y += this.Height; // Bottom screenBottomLeft.X += (int)m_renderedRectangles[m_firstUnRecognizedTag.Index].X; // Advance to current edition position if (screenBottomLeft.Y + m_suggestionForm.Height > m_applicationForm.Bottom) { screenBottomLeft.Y -= this.Height - m_suggestionForm.Height; // Make the form pop above the text box instead, otherwise it will go too low } m_suggestionForm.Location = screenBottomLeft; }
protected override void OnLeave(EventArgs e) { HoveredTag = null; this.Invalidate(); base.OnLeave(e); }
public EditedTag(Fiche _fiche, EditedTag _nextTag) { InsertBefore(_nextTag); Fiche = _fiche; }