| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- namespace Terminal.Gui.Views;
- public partial class TextView
- {
- internal void ApplyCellsAttribute (Attribute attribute)
- {
- if (!ReadOnly && SelectedLength > 0)
- {
- int startRow = Math.Min (SelectionStartRow, CurrentRow);
- int endRow = Math.Max (CurrentRow, SelectionStartRow);
- int startCol = SelectionStartRow <= CurrentRow ? SelectionStartColumn : CurrentColumn;
- int endCol = CurrentRow >= SelectionStartRow ? CurrentColumn : SelectionStartColumn;
- List<List<Cell>> selectedCellsOriginal = [];
- List<List<Cell>> selectedCellsChanged = [];
- for (int r = startRow; r <= endRow; r++)
- {
- List<Cell> line = GetLine (r);
- selectedCellsOriginal.Add ([.. line]);
- for (int c = r == startRow ? startCol : 0;
- c < (r == endRow ? endCol : line.Count);
- c++)
- {
- Cell cell = line [c]; // Copy value to a new variable
- cell.Attribute = attribute; // Modify the copy
- line [c] = cell; // Assign the modified copy back
- }
- selectedCellsChanged.Add ([.. GetLine (r)]);
- }
- GetSelectedRegion ();
- IsSelecting = false;
- _historyText.Add (
- [.. selectedCellsOriginal],
- new Point (startCol, startRow)
- );
- _historyText.Add (
- [.. selectedCellsChanged],
- new Point (startCol, startRow),
- TextEditingLineStatus.Attribute
- );
- }
- }
- private Attribute? GetSelectedCellAttribute ()
- {
- List<Cell> line;
- if (SelectedLength > 0)
- {
- line = GetLine (SelectionStartRow);
- if (line [Math.Min (SelectionStartColumn, line.Count - 1)].Attribute is { } attributeSel)
- {
- return new (attributeSel);
- }
- return GetAttributeForRole (VisualRole.Active);
- }
- line = GetCurrentLine ();
- if (line [Math.Min (CurrentColumn, line.Count - 1)].Attribute is { } attribute)
- {
- return new (attribute);
- }
- return GetAttributeForRole (VisualRole.Active);
- }
- /// <summary>Invoked when the normal color is drawn.</summary>
- public event EventHandler<CellEventArgs>? DrawNormalColor;
- /// <summary>Invoked when the ready only color is drawn.</summary>
- public event EventHandler<CellEventArgs>? DrawReadOnlyColor;
- /// <summary>Invoked when the selection color is drawn.</summary>
- public event EventHandler<CellEventArgs>? DrawSelectionColor;
- /// <summary>
- /// Invoked when the used color is drawn. The Used Color is used to indicate if the <see cref="Key.InsertChar"/>
- /// was pressed and enabled.
- /// </summary>
- public event EventHandler<CellEventArgs>? DrawUsedColor;
- /// <inheritdoc/>
- protected override bool OnDrawingContent ()
- {
- _isDrawing = true;
- SetAttributeForRole (Enabled ? VisualRole.Editable : VisualRole.Disabled);
- (int width, int height) offB = OffSetBackground ();
- int right = Viewport.Width + offB.width;
- int bottom = Viewport.Height + offB.height;
- var row = 0;
- for (int idxRow = _topRow; idxRow < _model.Count; idxRow++)
- {
- List<Cell> line = _model.GetLine (idxRow);
- int lineRuneCount = line.Count;
- var col = 0;
- Move (0, row);
- for (int idxCol = _leftColumn; idxCol < lineRuneCount; idxCol++)
- {
- string text = idxCol >= lineRuneCount ? " " : line [idxCol].Grapheme;
- int cols = text.GetColumns (false);
- if (idxCol < line.Count && IsSelecting && PointInSelection (idxCol, idxRow))
- {
- OnDrawSelectionColor (line, idxCol, idxRow);
- }
- else if (idxCol == CurrentColumn && idxRow == CurrentRow && !IsSelecting && !Used && HasFocus && idxCol < lineRuneCount)
- {
- OnDrawUsedColor (line, idxCol, idxRow);
- }
- else if (ReadOnly)
- {
- OnDrawReadOnlyColor (line, idxCol, idxRow);
- }
- else
- {
- OnDrawNormalColor (line, idxCol, idxRow);
- }
- if (text == "\t")
- {
- cols += TabWidth + 1;
- if (col + cols > right)
- {
- cols = right - col;
- }
- for (var i = 0; i < cols; i++)
- {
- if (col + i < right)
- {
- AddRune (col + i, row, (Rune)' ');
- }
- }
- }
- else
- {
- AddStr (col, row, text);
- // Ensures that cols less than 0 to be 1 because it will be converted to a printable rune
- cols = Math.Max (cols, 1);
- }
- if (!TextModel.SetCol (ref col, Viewport.Right, cols))
- {
- break;
- }
- if (idxCol + 1 < lineRuneCount && col + line [idxCol + 1].Grapheme.GetColumns () > right)
- {
- break;
- }
- }
- if (col < right)
- {
- SetAttributeForRole (ReadOnly ? VisualRole.ReadOnly : VisualRole.Editable);
- ClearRegion (col, row, right, row + 1);
- }
- row++;
- }
- if (row < bottom)
- {
- SetAttributeForRole (ReadOnly ? VisualRole.ReadOnly : VisualRole.Editable);
- ClearRegion (Viewport.Left, row, right, bottom);
- }
- _isDrawing = false;
- return false;
- }
- /// <summary>
- /// Sets the <see cref="View.Driver"/> to an appropriate color for rendering the given <paramref name="idxCol"/>
- /// of the current <paramref name="line"/>. Override to provide custom coloring by calling
- /// <see cref="View.SetAttribute"/> Defaults to <see cref="Scheme.Normal"/>.
- /// </summary>
- /// <param name="line">The line.</param>
- /// <param name="idxCol">The col index.</param>
- /// <param name="idxRow">The row index.</param>
- protected virtual void OnDrawNormalColor (List<Cell> line, int idxCol, int idxRow)
- {
- (int Row, int Col) unwrappedPos = GetUnwrappedPosition (idxRow, idxCol);
- var ev = new CellEventArgs (line, idxCol, unwrappedPos);
- DrawNormalColor?.Invoke (this, ev);
- if (line [idxCol].Attribute is { })
- {
- Attribute? attribute = line [idxCol].Attribute;
- SetAttribute ((Attribute)attribute!);
- }
- else
- {
- SetAttribute (GetAttributeForRole (VisualRole.Normal));
- }
- }
- /// <summary>
- /// Sets the <see cref="View.Driver"/> to an appropriate color for rendering the given <paramref name="idxCol"/>
- /// of the current <paramref name="line"/>. Override to provide custom coloring by calling
- /// <see cref="View.SetAttribute(Attribute)"/> Defaults to <see cref="Scheme.Focus"/>.
- /// </summary>
- /// <param name="line">The line.</param>
- /// <param name="idxCol">The col index.</param>
- /// ///
- /// <param name="idxRow">The row index.</param>
- protected virtual void OnDrawReadOnlyColor (List<Cell> line, int idxCol, int idxRow)
- {
- (int Row, int Col) unwrappedPos = GetUnwrappedPosition (idxRow, idxCol);
- var ev = new CellEventArgs (line, idxCol, unwrappedPos);
- DrawReadOnlyColor?.Invoke (this, ev);
- Attribute? cellAttribute = line [idxCol].Attribute is { } ? line [idxCol].Attribute : GetAttributeForRole (VisualRole.ReadOnly);
- if (cellAttribute!.Value.Foreground == cellAttribute.Value.Background)
- {
- SetAttribute (new (cellAttribute.Value.Foreground, cellAttribute.Value.Background, cellAttribute.Value.Style));
- }
- else
- {
- SetAttributeForRole (VisualRole.ReadOnly);
- }
- }
- /// <summary>
- /// Sets the <see cref="View.Driver"/> to an appropriate color for rendering the given <paramref name="idxCol"/>
- /// of the current <paramref name="line"/>. Override to provide custom coloring by calling
- /// <see cref="View.SetAttribute(Attribute)"/> Defaults to <see cref="Scheme.Focus"/>.
- /// </summary>
- /// <param name="line">The line.</param>
- /// <param name="idxCol">The col index.</param>
- /// ///
- /// <param name="idxRow">The row index.</param>
- protected virtual void OnDrawSelectionColor (List<Cell> line, int idxCol, int idxRow)
- {
- (int Row, int Col) unwrappedPos = GetUnwrappedPosition (idxRow, idxCol);
- var ev = new CellEventArgs (line, idxCol, unwrappedPos);
- DrawSelectionColor?.Invoke (this, ev);
- if (line [idxCol].Attribute is { })
- {
- Attribute? attribute = line [idxCol].Attribute;
- Attribute? active = GetAttributeForRole (VisualRole.Active);
- SetAttribute (new (active!.Value.Foreground, active.Value.Background, attribute!.Value.Style));
- }
- else
- {
- SetAttributeForRole (VisualRole.Active);
- }
- }
- /// <summary>
- /// Sets the <see cref="View.Driver"/> to an appropriate color for rendering the given <paramref name="idxCol"/>
- /// of the current <paramref name="line"/>. Override to provide custom coloring by calling
- /// <see cref="View.SetAttribute(Attribute)"/> Defaults to <see cref="Scheme.HotFocus"/>.
- /// </summary>
- /// <param name="line">The line.</param>
- /// <param name="idxCol">The col index.</param>
- /// ///
- /// <param name="idxRow">The row index.</param>
- protected virtual void OnDrawUsedColor (List<Cell> line, int idxCol, int idxRow)
- {
- (int Row, int Col) unwrappedPos = GetUnwrappedPosition (idxRow, idxCol);
- var ev = new CellEventArgs (line, idxCol, unwrappedPos);
- DrawUsedColor?.Invoke (this, ev);
- if (line [idxCol].Attribute is { })
- {
- Attribute? attribute = line [idxCol].Attribute;
- SetValidUsedColor (attribute!);
- }
- else
- {
- SetValidUsedColor (GetAttributeForRole (VisualRole.Focus));
- }
- }
- private void DoSetNeedsDraw (Rectangle rect)
- {
- if (_wrapNeeded)
- {
- SetNeedsDraw ();
- }
- else
- {
- // BUGBUG: customized rect aren't supported now because the Redraw isn't using the Intersect method.
- //SetNeedsDraw (rect);
- SetNeedsDraw ();
- }
- }
- private Attribute? GetSelectedAttribute (int row, int col)
- {
- if (!InheritsPreviousAttribute || (Lines == 1 && GetLine (Lines).Count == 0))
- {
- return null;
- }
- List<Cell> line = GetLine (row);
- int foundRow = row;
- while (line.Count == 0)
- {
- if (foundRow == 0 && line.Count == 0)
- {
- return null;
- }
- foundRow--;
- line = GetLine (foundRow);
- }
- int foundCol = foundRow < row ? line.Count - 1 : Math.Min (col, line.Count - 1);
- Cell cell = line [foundCol];
- return cell.Attribute;
- }
- /// <inheritdoc/>
- protected override bool OnGettingAttributeForRole (in VisualRole role, ref Attribute currentAttribute)
- {
- if (role == VisualRole.Normal)
- {
- currentAttribute = GetAttributeForRole (VisualRole.Editable);
- return true;
- }
- return base.OnGettingAttributeForRole (role, ref currentAttribute);
- }
- }
|