Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

190-strange-coloring-remove-console-brush #227

Merged
merged 17 commits into from
Dec 25, 2024

Conversation

jinek
Copy link
Owner

@jinek jinek commented Dec 25, 2024

No description provided.

@jinek jinek requested a review from tomlm December 25, 2024 17:55
@jinek jinek linked an issue Dec 25, 2024 that may be closed by this pull request
@jinek jinek added the enhancement New feature or request label Dec 25, 2024
Copy link
Contributor

coderabbitai bot commented Dec 25, 2024

📝 Walkthrough

Walkthrough

This pull request encompasses a comprehensive set of changes across multiple files in the Consolonia project, focusing primarily on brush and color handling, symbol representation, and theme resource management. The modifications involve transitioning from ConsoleBrush to more standardized brush types like SolidColorBrush, simplifying color and background processing, and renaming methods for improved clarity. Key areas of change include pixel buffer implementation, drawing context, theme resources, and symbol-related classes. The changes aim to streamline color and brush handling, improve code readability, and enhance the consistency of visual rendering across the application.

Possibly related PRs

Suggested labels

bug, low priority

Suggested reviewers

  • tomlm

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs (1)

Line range hint 31-52: Commented-out Shade method

Since PixelBackgroundMode is removed, you should remove or refactor this method. Keeping it commented can lead to future confusion.

- /*public PixelBackground Shade()
- {
-     ...
- }*/
+ // Consider removing this method entirely, or reintroducing with a revised signature if needed.
🧹 Nitpick comments (15)
src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs (1)

100-107: Method name clarity regarding partial alpha.

NothingToDraw() correctly returns true for a fully transparent color or a whitespace symbol. However, consider clarifying how partial alpha should be treated. If the intention is that partial alpha might still be drawn, the current naming is fine; otherwise, rename the method to reflect how it handles partial transparency.

src/Consolonia.Core/Drawing/ConsoleBrush.cs (4)

10-10: Consider a more descriptive name for ConsoleBrush2
Naming the new static class ConsoleBrush2 is functional but not very descriptive. A more expressive name (e.g., ColorHelper or BrushColorResolver) could improve readability.


Line range hint 12-38: Address the TODO for brush opacity
Inside FromPosition, there's a TODO comment about applying brush opacity. Consider incorporating opacity calculations when deriving the final color from gradient brushes.

Would you like me to propose a quick snippet that applies opacity in your gradient calculations?


65-65: Reuse computations if performance is critical
In the radial gradient branch, the logic to compute distances is correct, but if you repeatedly call FromPosition in performance-critical loops, caching or reusing computed values (center, radius, etc.) might be beneficial.


83-83: Consider specialized logic for conic gradients
Currently, the conic gradient path blends horizontal and vertical interpolations the same way as linear gradients. Conic gradients sometimes require angle-based calculations for more accurate color transitions.

src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (2)

117-138: Unify blending logic for partially transparent layers
When the top pixel is not fully transparent (A≠0), the code branches into a distinct flow. Consider merging or simplifying the logic to handle partial transparency uniformly rather than special casing A=0xFF.


149-153: Remove or resurrect commented-out code
The commented-out Shade() method is a minor code smell. Deleting dead code or reintroducing it with tests helps maintain clarity.

src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs (2)

49-50: Ensure the partial alpha channel is tested thoroughly.

Here, #7FFF0000 indicates an alpha channel. Consider adding additional tests to verify partial transparency handling in PixelBackground, ensuring that rendering logic is accurate.


63-64: Check for potential duplication in color-based equality checks.

Repeated creation of similar PixelBackground instances with “#000000FF” might be simplified or consolidated into a helper function, reducing possible duplication in test logic.

src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs (1)

80-80: Reassure maintainers about the custom caret approach.

Explicitly setting a transparent brush for the Avalonia caret indicates that you’re managing the caret rendering yourself. Ensure that all required logic for a custom caret is properly tested and documented to avoid future confusion.

src/Consolonia.Themes/Templates/Controls/DialogWindow.axaml (1)

28-28: Use a dynamic resource for shading.

Replacing the static reference with ThemeShadeBrush provides theme adaptability. Ensure that ThemeShadeBrush is defined properly in the resource dictionaries and tested in various theme scenarios.

src/Tests/Consolonia.Core.Tests/PixelTests.cs (1)

171-174: Ensuring background is “not lighter” is sensible.
The new assertion that the background should not be lighter than the original is a suitable approach for partial shading. This adequately tests the darker shading logic, but consider adding boundary tests (e.g., fully opaque vs. fully transparent).

src/Consolonia.Core/Drawing/DrawingContextImpl.cs (3)

531-535: Potential performance consideration for large fills.

While using ConsoleBrush2.FromPosition(...) followed by pixel.Blend(...) provides flexibility, be mindful that filling large areas in a tight loop may introduce performance overhead. Consider bulk fill operations or region-based updates if performance becomes an issue.


666-674: Maintain code clarity when extracting color.

The flow that checks for a LineBrush and then falls back to a casted ISolidColorBrush is logical and compact. Any future brush expansions might require extracting shared color logic to a helper method.


745-745: Tab rendering logic is correct.

The approach of inserting multiple spaces for the tab character is straightforward. Consider making the tab size configurable if user needs vary.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9bfd9c and 6e693a4.

📒 Files selected for processing (25)
  • src/.editorconfig (1 hunks)
  • src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml (1 hunks)
  • src/Consolonia.Core/Drawing/ConsoleBrush.cs (4 hunks)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (5 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (4 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs (3 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs (1 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs (1 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs (1 hunks)
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs (2 hunks)
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs (1 hunks)
  • src/Consolonia.NUnit/UnitTestConsole.cs (1 hunks)
  • src/Consolonia.Themes/Fluent/FluentColors.axaml (1 hunks)
  • src/Consolonia.Themes/Material/MaterialColors.axaml (1 hunks)
  • src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml (2 hunks)
  • src/Consolonia.Themes/Templates/Controls/DataGrid.axaml (1 hunks)
  • src/Consolonia.Themes/Templates/Controls/DialogWindow.axaml (1 hunks)
  • src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs (2 hunks)
  • src/Consolonia.Themes/Templates/Controls/Popup.axaml (1 hunks)
  • src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml (1 hunks)
  • src/Consolonia.Themes/TurboVisionBlack/TurboVisionBlackColors.axaml (1 hunks)
  • src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml (1 hunks)
  • src/Example/Views/DataGridTestWindow.axaml (1 hunks)
  • src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs (3 hunks)
  • src/Tests/Consolonia.Core.Tests/PixelTests.cs (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs
  • src/.editorconfig
🧰 Additional context used
📓 Learnings (3)
src/Consolonia.Themes/TurboVisionBlack/TurboVisionBlackColors.axaml (1)
Learnt from: tomlm
PR: jinek/Consolonia#122
File: src/Consolonia.Themes.TurboVision/Themes/TurboVisionDark/TurboVisionDarkColors.axaml:5-28
Timestamp: 2024-11-12T04:11:38.190Z
Learning: In the project, using `Mode="Shaded"` in `ConsoleBrush` within theme files is intentional and does not cause runtime issues.
src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml (1)
Learnt from: tomlm
PR: jinek/Consolonia#122
File: src/Consolonia.Themes.TurboVision/Themes/TurboVisionDark/TurboVisionDarkColors.axaml:5-28
Timestamp: 2024-11-12T04:11:38.190Z
Learning: In the project, using `Mode="Shaded"` in `ConsoleBrush` within theme files is intentional and does not cause runtime issues.
src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml (1)
Learnt from: tomlm
PR: jinek/Consolonia#122
File: src/Consolonia.Themes.TurboVision/Themes/TurboVisionDark/TurboVisionDarkColors.axaml:5-28
Timestamp: 2024-11-12T04:11:38.190Z
Learning: In the project, using `Mode="Shaded"` in `ConsoleBrush` within theme files is intentional and does not cause runtime issues.
🔇 Additional comments (66)
src/Consolonia.Themes/Templates/Controls/Popup.axaml (1)

10-11: Use of dynamic resource for background is consistent with theme refactoring.

The usage of {DynamicResource ThemeTransparentBrush} aligns well with the pull request's efforts to standardize brush handling and enable runtime theme adaptability. No issues found regarding performance or logic here.

src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs (1)

50-50: Great use of string.IsNullOrWhiteSpace.

This helps ensure that tabs, newlines, and other whitespace characters are correctly identified.

src/Consolonia.Core/Drawing/ConsoleBrush.cs (1)

87-87: Handle unexpected IBrush types more gracefully
The cast to ISolidColorBrush might throw if the brush is not what you expect. A more explicit check or exception could improve clarity.

src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (3)

43-43: Defaulting to new PixelBackground()
Initializing a default background helps simplify usage now that background modes have been removed. The approach is clean and straightforward.


106-116: Verify partial alpha assumptions
The blending logic for pixelAbove with a fully transparent background (A=0) is correct, but ensure partial alpha edge cases are handled properly (e.g., if background alpha is between 0 and 255).


163-187: Alpha blending formula is clear and correct
Your conversion from [0..255] to [0..1] and subsequent compositing approach is well-executed. This is a solid implementation of alpha blending.

src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml (1)

7-7: Switch to dynamic resource for theme adaptation
Using {DynamicResource ThemeShadeBrush} allows runtime theme changes. Great choice for dynamic theming.

src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml (1)

6-29: Transition to SolidColorBrush
Replacing ConsoleBrush with SolidColorBrush aligns with the broader refactor away from custom brush classes. The partial transparency in ThemeShadeBrush (#7F000000) also supports subtle overlay effects.

src/Consolonia.Themes/TurboVisionBlack/TurboVisionBlackColors.axaml (1)

7-30: Consistent replacement with SolidColorBrush
These changes mirror the transition done in other themes, ensuring uniform usage of SolidColorBrush for color definitions. The partial alpha in ThemeShadeBrush (#7F000000) remains consistent for shading purposes.

src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml (13)

7-7: Good transition to a standard SolidColorBrush

Replaces the custom ConsoleBrush with SolidColorBrush for ThemeForegroundBrush. This helps maintain consistency across different Avalonia theming mechanisms.


9-10: Clarify the background color choice

Switching the background to Gray is consistent with console applications, but verify whether it integrates well with other theme colors in various UI components.


11-12: Consistent usage of SolidColorBrush

The Cyan chooser background is now a SolidColorBrush, which aligns with the removal of ConsoleBrush. Make sure this color stands out appropriately in the new brush system.


13-14: Confirm the color choice for action backgrounds

ForestGreen is a strong color. Confirm it remains readable with typical foreground text or icons.


15-16: DarkBlue selection background

No technical issues identified. Check that text and icon contrasts are still clear while selected.


17-18: ThemeSelectionForegroundBrush set to White

White on DarkBlue is readable. Looks good.


19-20: White alternative background color

Confirm no overlap with the main background color or selection color for a good user experience.


21-22: ThemeBorderBrush uses DarkGray

Suitable choice for delineation if the overall background is lighter.


23-24: NoDisturbBrush also set to DarkGray

Verify that “NoDisturb” usage isn't confused with typical border usage where the same color is used.


25-26: Semi-transparent black shade

Hex #7F000000 indicates partial transparency. Ensure alpha blending is handled properly by the UI.


27-28: PseudoShadeBrush set to Black

No risk or conflict is apparent. Just confirm no blending logic is needed.


29-29: Error brush color changed to Red

Straightforward. Good for alerting.


31-32: ThemeTransparentBrush with alpha set to zero

Good standard approach to define a fully transparent brush.

src/Consolonia.Themes/Material/MaterialColors.axaml (12)

8-8: Foreground brush set to a dark shade (#212121)

Ensures good contrast on light backgrounds.


11-12: ThemeBackgroundBrush switched to white

No issues. White is standard for material designs.


14-15: Chooser background set to #0288D1

Consistent with Material's Light Blue 700. Approved.


17-18: Action background set to #4CAF50

Aligns with Material Green 500. No issues noted.


20-21: Selection background changed to #B0BEC5

Part of the Blue Grey palette. Confirm text color is still visible.


23-24: Selection foreground set to #FFFFFF

White on #B0BEC5 is acceptable.


26-27: Alternative background #CFD8DC

Still in the Blue Grey family. Looks consistent.


29-30: Border brush #BDBDBD

Material Grey 400, consistent with guidelines.


32-33: NoDisturbBrush #FFC107

Amber 500 for emphasis. No issues with switching to SolidColorBrush here.


35-36: ThemeShadeBrush with partial opacity (#7F757575)

Remains consistent with the material design's semi-transparent shades.


38-39: PseudoShadeBrush #90A4AE

Blue Grey 300, no conflicts noted.


41-42: Error brush #F44336

Material Red 500, consistent with standard error highlighting.

src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs (3)

9-9: Debugger display only references Color

Removing Mode from the display is consistent since the property is dropped.


28-28: Equality now compares only Color

Eliminating Mode references simplifies the data structure.


61-61: GetHashCode now uses only Color

Consistent with the new, reduced property set.

src/Consolonia.Themes/Fluent/FluentColors.axaml (12)

8-9: Foreground brush #323130

A valid dark color for neutral text in Fluent styling.


11-12: Background brush #FFFFFF

White is a standard background in Fluent design.


14-15: Chooser background #0078D4

Fluent Communication Blue. Good consistency.


17-18: Action background #0078D4

Same color as chooser background, which simplifies the palette.


20-21: Selection background #EDEBE9

Recognizable neutral color in Fluent.


23-24: Selection foreground #323130

Dark color on a light background. Good contrast.


26-27: Alternative background #F3F2F1

Matches Fluent’s light grey neutrals.


29-30: Border brush #D2D2D2

Adheres to Fluent neutral stroke guidelines.


32-33: NoDisturbBrush #FFB900

Corresponds to Fluent Yellow (Warning).


35-36: Shade brush with partial opacity (#7F767676)

Consistent semi-transparent shade.


38-39: PseudoShadeBrush #A0A0A0

Medium gray, workable for subtle shading.


41-42: Error brush #D83B01

Maps to Fluent Red-Orange for errors.

src/Tests/Consolonia.Core.Tests/PixelBackgroundTests.cs (1)

34-35: Confirm consistency of color parsing across the codebase.

Using Color.Parse("#000000FF") is functionally equivalent to Colors.Blue in some contexts, but not always obvious at first glance. Verify that other references to opaque black/blue are consistent throughout the tests and related code, ensuring no confusion arises from hex-based color literals.

src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs (2)

61-61: Confirm that only transparent brushes are supported for the caret.

This exception enforces a fully transparent caret brush. Ensure that external code or XAML files do not inadvertently supply non-transparent brushes, which could break the control’s caret rendering logic.


79-79: [Skip] Empty line change.

No action needed.

src/Example/Views/DataGridTestWindow.axaml (1)

48-48: Foreground has been simplified to “Gray.”

This straightforward change aligns with standard styling practices and avoids extraneous brush wrappers. Looks good.

src/Consolonia.Themes/Templates/Controls/DialogWindow.axaml (1)

31-31: Switch to fully transparent dynamic brush.

Transitioning from a static “transparent” console brush to ThemeTransparentBrush aligns with the rest of the dynamic resource approach. Validate that ThemeTransparentBrush is truly transparent and not overridden in any specialized theme.

src/Consolonia.NUnit/UnitTestConsole.cs (1)

74-74: Use of simpler PixelBackground constructor looks correct.
Eliminating the background mode parameter in PixelBackground aligns with the broader refactoring toward a color-centric approach. Ensure that no other parts of the code still rely on the removed mode logic for rendering or theming decisions.

✅ Verification successful

All PixelBackground constructor usages are correctly using the color-only version

Based on the search results, all instances of PixelBackground constructor usage across the codebase are correctly using either the parameterless constructor or the color-only constructor variant. The search shows:

  • Test files (PixelBackgroundTests.cs, PixelTests.cs) use the constructors with either no parameters or just color
  • Core implementation files (Pixel.cs, DrawingContextImpl.cs) also use the simplified constructors
  • The commented-out code in PixelBackground.cs shows the old mode-based constructor that was removed
  • The usage in UnitTestConsole.cs (the file under review) correctly uses the color-only constructor

This confirms that the refactoring to eliminate the background mode parameter has been consistently applied throughout the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify references to the old PixelBackground constructor with the Mode argument.
rg -A 2 $'PixelBackground\\('

Length of output: 13137

src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml (2)

36-36: Consistent usage of theme-based resources.
Applying {DynamicResource ThemeTransparentBrush} here maintains uniform theming logic across pressed and default states. Verify that these changes do not introduce any visual regressions in pressed states.


25-25: Adoption of DynamicResource for background transparency.
Replacing the static resource usage with {DynamicResource ThemeTransparentBrush} improves flexibility when switching themes at runtime. Confirm that ThemeTransparentBrush is defined and tested for all relevant theme dictionaries to prevent potential runtime errors.

✅ Verification successful

DynamicResource usage for ThemeTransparentBrush is properly defined and used consistently

The verification confirms that ThemeTransparentBrush is:

  • Properly defined in src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml as a transparent color brush (#00000000)
  • Used consistently across multiple controls (ListBoxItem, CalendarItem, Popup, DataGrid, DialogWindow) with DynamicResource
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Searching for the ThemeTransparentBrush definition across the codebase
rg -A 3 "ThemeTransparentBrush"

Length of output: 3882

src/Tests/Consolonia.Core.Tests/PixelTests.cs (2)

146-146: Partial transparency shading test coverage.
Using Color.Parse("#7F000000") for partially transparent backgrounds aligns with the removal of PixelBackgroundMode.Shaded. Ensure that existing tests adequately validate the expected blending outcomes with partial transparency.

Also applies to: 164-164


149-149: Foreground shading logic looks correct.
The test asserts that the new foreground is darker than the original, which is consistent with partial transparency layering. This approach is valid as long as the same logic is reflected in other shading scenarios.

src/Consolonia.Themes/Templates/Controls/DataGrid.axaml (1)

283-284: Switch to DynamicResource for RowBackground.
Replacing the explicit ConsoleBrush with {DynamicResource ThemeTransparentBrush} is in line with the updated theming approach. Verify that ThemeTransparentBrush is available for DataGrid usage in all supported themes.

✅ Verification successful

Let me verify the availability of ThemeTransparentBrush in the themes.


Let me try a different approach to find the resource definition.


Resource availability confirmed for DataGrid's RowBackground

The ThemeTransparentBrush is properly defined in TurboVisionDefaultColors.axaml as a transparent color brush (#00000000) and is consistently used across multiple controls in the theme, including DataGrid, Popup, DialogWindow, CalendarItem, and ListBoxItem. The usage of this brush for DataGrid's RowBackground is appropriate and follows the established theming pattern in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Confirm the presence and usage of 'ThemeTransparentBrush' in DataGrid contexts
rg -A 5 "DataGrid" | rg "ThemeTransparentBrush"

Length of output: 168


Script:

#!/bin/bash
# Search for ThemeTransparentBrush definition in theme files
rg "ThemeTransparentBrush" --type xaml

Length of output: 67


Script:

#!/bin/bash
# Search for ThemeTransparentBrush definition in all files
rg "ThemeTransparentBrush" -A 3

Length of output: 3882

src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs (1)

603-606: Nice transition to SolidColorBrush.

Replacing the ConsoleBrush instances with SolidColorBrush is consistent with your broader refactor, and correctly sets the color for varying GDP thresholds.

src/Consolonia.Core/Drawing/DrawingContextImpl.cs (2)

655-657: Confirm pen brush usage constraints.

This conditional checks for LineBrush or ISolidColorBrush, disallowing other brush types. Verify if you intend to handle additional pen brush types (e.g., gradients) or confirm such usage is out of scope.


725-726: Approve usage of ISolidColorBrush check.

It is correct to raise “not supported” exceptions for unrecognized brush types. This aligns with the platform’s constraints and helps maintain robust error handling.

src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs (3)

52-52: Replacing ConsoleBrush with IBrush broadens flexibility.

Allowing different brush implementations decouples color handling from console-specific logic, making it more adaptable to various rendering scenarios.


62-62: SolidColorBrush assignment looks good.

By assigning a new SolidColorBrush upon color update, you ensure the UI reflects the latest color values.


66-66: Notify property changed after updating _brush.

Raising PropertyChanged here properly informs the UI about brush changes, preserving binding synchronization.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs (1)

109-111: Consider renaming the test method and adding null coverage.

The test method name “IsWhiteSpace” no longer aligns with the new “NothingToDraw” logic. Also, consider adding a scenario that checks how NothingToDraw behaves if the symbol text is null, ensuring full coverage of your use cases.

You could rename the test and add a new test case, for example:

-[Test]
-public void IsWhiteSpace()
+[Test]
+public void NothingToDrawTest()
 {
     Assert.That(new SimpleSymbol(string.Empty).NothingToDraw(), Is.True);
     Assert.That(new SimpleSymbol(" ").NothingToDraw(), Is.False);
     Assert.That(new SimpleSymbol("a").NothingToDraw(), Is.False);
+    Assert.That(new SimpleSymbol(null).NothingToDraw(), Is.True);
 }

Would you like me to open a new issue to track this enhancement?

src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (2)

152-176: LGTM: Improved alpha compositing implementation

The new implementation correctly follows standard alpha compositing formulas with proper range handling.

Consider caching frequently used division results to optimize performance:

 private static Color MergeColors(Color target, Color source)
 {
     // Convert alpha from [0..255] to [0..1]
     float fgAlpha = source.A / 255f;
     float bgAlpha = target.A / 255f;
+    float invFgAlpha = 1 - fgAlpha;  // Cache this value
 
     // Compute output alpha
-    float outAlpha = fgAlpha + bgAlpha * (1 - fgAlpha);
+    float outAlpha = fgAlpha + bgAlpha * invFgAlpha;
 
     // If there's no alpha in the result, return transparent
     if (outAlpha <= 0f)
     {
         return Color.FromArgb(0, 0, 0, 0);
     }
 
+    float invOutAlpha = 1 / outAlpha;  // Cache division result
     // Calculate the composited color channels, also converting channels to [0..1]
-    float outR = (source.R / 255f * fgAlpha + target.R / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha;
-    float outG = (source.G / 255f * fgAlpha + target.G / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha;
-    float outB = (source.B / 255f * fgAlpha + target.B / 255f * bgAlpha * (1 - fgAlpha)) / outAlpha;
+    float outR = (source.R / 255f * fgAlpha + target.R / 255f * bgAlpha * invFgAlpha) * invOutAlpha;
+    float outG = (source.G / 255f * fgAlpha + target.G / 255f * bgAlpha * invFgAlpha) * invOutAlpha;
+    float outB = (source.B / 255f * fgAlpha + target.B / 255f * bgAlpha * invFgAlpha) * invOutAlpha;

110-110: Address the TODO comment about alpha comparison

The TODO suggests extracting the alpha comparison to an extension method, which would improve code reusability.

Would you like me to help implement an extension method for approximate alpha comparison? This could include:

  • Handling floating-point comparison tolerance
  • Proper normalization of alpha values
  • Unit tests for the extension method
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e693a4 and 275069e.

📒 Files selected for processing (6)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs (1 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/ISymbol.cs (1 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (3 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs (1 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs (1 hunks)
  • src/Tests/Consolonia.Core.Tests/SimpleSymbolTests.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelForeground.cs
🔇 Additional comments (7)
src/Consolonia.Core/Drawing/PixelBufferImplementation/ISymbol.cs (1)

18-18: Renaming to a more descriptive method name is a good improvement.
"NothingToDraw" more accurately conveys what the method checks for, enhancing code clarity. Keep it consistent across all symbol implementations.

src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs (2)

36-36: Method name aligns well with the broader refactor.
Returning true when UpRightDownLeft is EmptySymbol clarifies that there's no meaningful box drawing to render.


43-43: Dependence on the new "NothingToDraw" method.
This check is consistent with the interface rename and ensures that blending logic respects the newly introduced condition.

src/Consolonia.Core/Drawing/PixelBufferImplementation/SimpleSymbol.cs (2)

48-48: Readability improvement with the new name.
Returning true when Text is null or empty clearly indicates there's nothing to draw on screen.


55-55: Consistent usage of the "NothingToDraw" method in blending logic.
This short-circuit evaluation ensures that an empty or blank symbol is preserved only if the upper symbol has nothing to draw, maintaining the intended layering behavior.

src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (2)

43-43: LGTM: Constructor simplified

The simplified background initialization aligns with the PR's objective of removing complex brush handling.


131-135: Verify the necessity of clearing foreground on opaque background

When the background is fully opaque (A=0xFF), the code discards the foreground completely. While this might be intentional for optimization, it could potentially lose important foreground information. Consider whether preserving the foreground symbol might be necessary for certain UI scenarios.

Run this script to find potential UI components that might be affected:

@jinek jinek marked this pull request as ready for review December 25, 2024 18:18
@jinek
Copy link
Owner Author

jinek commented Dec 25, 2024

Should not close this one #190

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
src/Consolonia.Core/Drawing/ConsoleBrush.cs (1)

Line range hint 67-84: Fix incorrect conic gradient implementation.

The current implementation treats conic gradients like linear gradients, which is mathematically incorrect. Conic gradients should interpolate based on the angle around a center point.

 case IConicGradientBrush conicBrush:
 {
     if (width <= 0)
         width = 1;
     if (height <= 0)
         height = 1;
-    // Calculate the relative position within the gradient
-    double horizontalRelativePosition = (double)x / width;
-    double verticalRelativePosition = (double)y / height;
+    // Calculate angle from center point
+    double centerX = conicBrush.Center.X * width;
+    double centerY = conicBrush.Center.Y * height;
+    double angle = Math.Atan2(y - centerY, x - centerX);
+    
+    // Normalize angle to [0,1] range
+    double normalizedAngle = (angle + Math.PI) / (2 * Math.PI);
+    
+    // Adjust for rotation
+    normalizedAngle = (normalizedAngle + conicBrush.Angle / 360.0) % 1.0;
     
-    // Interpolate horizontal and vertical colors
-    Color horizontalColor = InterpolateColor(conicBrush, horizontalRelativePosition);
-    Color verticalColor = InterpolateColor(conicBrush, verticalRelativePosition);
-
-    // Average the two colors to get the final color
-    Color color = BlendColors(horizontalColor, verticalColor);
+    return InterpolateColor(conicBrush, normalizedAngle);
🧹 Nitpick comments (4)
src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs (1)

Line range hint 1-43: Consider documenting migration steps.

The removal of Mode-related functionality is a breaking change. Consider adding migration notes or an upgrade guide to help users transition from the old API to the simplified version.

Would you like me to help draft migration documentation or create a GitHub issue to track this task?

src/Consolonia.Core/Drawing/ConsoleBrush.cs (3)

Line range hint 23-39: Consider optimizing linear gradient calculation.

The current implementation interpolates and blends both horizontal and vertical colors for every pixel. For straight gradients (angle = 0° or 90°), we could optimize by using only the relevant axis.

 case ILinearGradientBrush gradientBrush:
 {
     if (width <= 0)
         width = 1;
     if (height <= 0)
         height = 1;
+    // Optimize for straight gradients
+    if (Math.Abs(gradientBrush.StartPoint.X - gradientBrush.EndPoint.X) < double.Epsilon)
+        return InterpolateColor(gradientBrush, verticalRelativePosition);
+    if (Math.Abs(gradientBrush.StartPoint.Y - gradientBrush.EndPoint.Y) < double.Epsilon)
+        return InterpolateColor(gradientBrush, horizontalRelativePosition);
+
     // Calculate the relative position within the gradient
     double horizontalRelativePosition = (double)x / width;

Line range hint 40-66: Improve readability of radial gradient calculations.

The mathematical calculations are correct but could be more maintainable with extracted helper methods and improved variable naming.

 case IRadialGradientBrush radialBrush:
 {
+    private static double CalculateNormalizedDistance(
+        double x, double y, double width, double height,
+        IRadialGradientBrush brush)
+    {
     // Calculate the normalized center coordinates
-    double centerX = radialBrush.Center.Point.X * width;
-    double centerY = radialBrush.Center.Point.Y * height;
+    double centerX = brush.Center.Point.X * width;
+    double centerY = brush.Center.Point.Y * height;

     // Calculate the distance from the center
     double dx = x - centerX;
     double dy = y - centerY;

     // Calculate the distance based on separate X and Y radii
-    double distanceX = dx / (width * radialBrush.RadiusX.Scalar);
-    double distanceY = dy / (height * radialBrush.RadiusY.Scalar);
+    double normalizedX = dx / (width * brush.RadiusX.Scalar);
+    double normalizedY = dy / (height * brush.RadiusY.Scalar);
-    double distance = Math.Sqrt(distanceX * distanceX + distanceY * distanceY);
+    double distance = Math.Sqrt(normalizedX * normalizedX + normalizedY * normalizedY);

     // Normalize the distance
-    double normalizedDistance = distance /
-                                Math.Sqrt(radialBrush.RadiusX.Scalar * radialBrush.RadiusX.Scalar +
-                                          radialBrush.RadiusY.Scalar * radialBrush.RadiusY.Scalar);
+    double maxRadius = Math.Sqrt(
+        brush.RadiusX.Scalar * brush.RadiusX.Scalar +
+        brush.RadiusY.Scalar * brush.RadiusY.Scalar);
+    return Math.Min(Math.Max(distance / maxRadius, 0), 1);
+    }

Line range hint 94-133: Consider using proper alpha compositing for color blending.

The current color blending uses simple averaging, which might not produce visually correct results. Consider implementing proper alpha compositing using the Porter-Duff algorithm.

 private static Color BlendColors(Color color1, Color color2)
 {
-    int r = (color1.R + color2.R) / 2;
-    int g = (color1.G + color2.G) / 2;
-    int b = (color1.B + color2.B) / 2;
-    int a = (color1.A + color2.A) / 2;
+    float alpha1 = color1.A / 255f;
+    float alpha2 = color2.A / 255f;
+    float outAlpha = alpha1 + alpha2 * (1 - alpha1);
+    
+    if (outAlpha < float.Epsilon)
+        return Color.FromArgb(0, 0, 0, 0);
+    
+    float r = (color1.R * alpha1 + color2.R * alpha2 * (1 - alpha1)) / outAlpha;
+    float g = (color1.G * alpha1 + color2.G * alpha2 * (1 - alpha1)) / outAlpha;
+    float b = (color1.B * alpha1 + color2.B * alpha2 * (1 - alpha1)) / outAlpha;
+    
+    return Color.FromArgb(
+        (byte)(outAlpha * 255),
+        (byte)Math.Round(r),
+        (byte)Math.Round(g),
+        (byte)Math.Round(b));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 275069e and 8a04477.

📒 Files selected for processing (15)
  • src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml (1 hunks)
  • src/Consolonia.Core/Drawing/ConsoleBrush.cs (4 hunks)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (5 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs (1 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (3 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs (2 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs (1 hunks)
  • src/Consolonia.Themes/Fluent/FluentColors.axaml (1 hunks)
  • src/Consolonia.Themes/Material/MaterialColors.axaml (1 hunks)
  • src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml (3 hunks)
  • src/Consolonia.Themes/Templates/Controls/DataGrid.axaml (1 hunks)
  • src/Consolonia.Themes/Templates/Controls/Popup.axaml (1 hunks)
  • src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml (1 hunks)
  • src/Consolonia.Themes/TurboVisionBlack/TurboVisionBlackColors.axaml (1 hunks)
  • src/Example/Views/DataGridTestWindow.axaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs
  • src/Consolonia.Themes/Templates/Controls/Popup.axaml
  • src/Consolonia.Core/Controls/Dialog/DialogWrap.axaml
  • src/Example/Views/DataGridTestWindow.axaml
  • src/Consolonia.Themes/Templates/Controls/CalendarItem.axaml
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/DrawingBoxSymbol.cs
  • src/Consolonia.Themes/Templates/Controls/DataGrid.axaml
  • src/Consolonia.Themes/Material/MaterialColors.axaml
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs
  • src/Consolonia.Themes/Fluent/FluentColors.axaml
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs
  • src/Consolonia.Themes/TurboVisionBlack/TurboVisionBlackColors.axaml
  • src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml
🔇 Additional comments (6)
src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs (4)

9-10: Well-structured immutable type declaration!

The readonly struct with primary constructor syntax and appropriate debugger display is a good choice for this value type.


18-18: LGTM! Well-designed immutable property.

The Color property is properly implemented as init-only with JSON serialization support.


Line range hint 21-42: Verify the impact of simplified equality comparison.

The equality implementation is correct but removing Mode from the comparison could affect existing collections or lookups that depend on the previous behavior.

✅ Verification successful

Let me try another search strategy to verify the impact.


The equality implementation change is safe to proceed with

Based on the search results:

  1. PixelBackground is only used as a value type within the Pixel struct and never as a key in collections.
  2. The test suite (PixelBackgroundTests.cs) already verifies the new equality behavior that only compares Color.
  3. The removal of Mode from equality comparison aligns with the type's current usage, where it's only used for color-based comparisons in blending operations and pixel manipulations.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for collections or dictionaries using PixelBackground as key
# that might be affected by the changed equality behavior

echo "Searching for collections using PixelBackground..."
rg "Dictionary<PixelBackground" 
rg "HashSet<PixelBackground"
rg "IEqualityComparer<PixelBackground"

echo "Searching for custom comparers..."
ast-grep --pattern 'class $_ : IEqualityComparer<PixelBackground>'

Length of output: 362


Script:

#!/bin/bash
# Search for any usage of PixelBackground in collections or comparisons
echo "Searching for PixelBackground usage in collections..."
rg "PixelBackground" -B 2 -A 2

# Search for any equality comparisons with PixelBackground
echo "Searching for equality comparisons..."
ast-grep --pattern '$_.Equals($_)' | rg -i "pixelbackground"
ast-grep --pattern '$_ == $_' | rg -i "pixelbackground"

Length of output: 24581


12-14: Verify the impact of removed constructors.

While the simplified constructor is cleaner, we should verify that removing the mode-related constructors hasn't broken existing usage.

✅ Verification successful

Let me verify the usage of the constructor in the found instance.


Let me check one more thing to see the complete constructor set in PixelBackground.cs.


Constructor changes are safe and well-implemented

The verification shows that the constructor changes are safe:

  1. The primary constructor PixelBackground(Color color) is defined as a primary constructor in the struct declaration
  2. The default constructor :this(Colors.Transparent) properly chains to it
  3. The only usage found (Pixel.cs) uses the primary constructor with a single Color parameter, which is still supported

The removal of mode-related constructors hasn't impacted any existing code as there are no instances of multi-parameter constructor calls in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining direct instantiations of PixelBackground with multiple parameters
# that might be affected by the constructor removal

echo "Searching for potential broken instantiations..."
rg "new PixelBackground\([^)]+,[^)]+\)" 

echo "Searching for potential broken static factory methods..."
ast-grep --pattern 'PixelBackground $name($$$) { 
  return new PixelBackground($$$);
}'

Length of output: 537


Script:

#!/bin/bash
# Check the context of the PixelBackground usage in Pixel.cs
echo "Checking Pixel.cs context:"
rg -B 5 -A 5 "new PixelBackground\(MergeColors" src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs

# Also check if there are any other constructors in PixelBackground.cs
echo -e "\nChecking PixelBackground.cs constructors:"
ast-grep --pattern 'public PixelBackground($$$) {
  $$$
}'

Length of output: 775


Script:

#!/bin/bash
# Get the full content of PixelBackground.cs to see all constructors
echo "Checking full PixelBackground.cs content:"
cat src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackground.cs

Length of output: 1342

src/Consolonia.Core/Drawing/ConsoleBrush.cs (2)

10-11: LGTM! Good refactoring to static utility class.

The change from an instance-based ConsoleBrush to a static BrushExtensions utility class is a good architectural decision that better reflects the nature of these operations.


Line range hint 12-22: Address TODO comment regarding brush opacity.

The input validation is thorough, but the brush opacity handling is currently missing as noted in the TODO comment.

Would you like me to help implement the brush opacity handling? Let's verify the impact first:

✅ Verification successful

TODO for brush opacity can be safely removed

Based on the codebase analysis:

  1. The platform explicitly doesn't support opacity operations as seen in DrawingContextImpl.cs where PushOpacity raises a "not supported" exception when opacity is not 1.0
  2. All concrete brush implementations (MoveConsoleCaretToPositionBrush, LineBrush) have a fixed opacity of 1.0
  3. The console environment appears to be designed for full opacity operations only

The TODO comment can be removed as opacity handling is intentionally not supported in this console-based implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for brush opacity usage in the codebase
rg -l 'Opacity\s*[=:]' | grep -i '\.axaml$'

Length of output: 45


Script:

#!/bin/bash
# Let's check for brush opacity in the codebase more broadly
rg -i "opacity" --type cs -A 3

# Also check for IBrush interface definition
ast-grep --pattern 'interface IBrush {
  $$$
}'

Length of output: 4170


Script:

#!/bin/bash
# Let's check the IBrush interface definition specifically
rg "interface IBrush" -A 10

# And check for any Color-related opacity handling
ast-grep --pattern 'class Color {
  $$$
}'

Length of output: 74

src/Consolonia.Core/Drawing/ConsoleBrush.cs Show resolved Hide resolved
@jinek jinek enabled auto-merge (squash) December 25, 2024 19:10
Copy link
Collaborator

@tomlm tomlm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My feedback are suggestions/comments, but this looks good.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename file?

src/Consolonia.Core/Drawing/ConsoleBrush.cs Outdated Show resolved Hide resolved
@jinek jinek disabled auto-merge December 25, 2024 20:39
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (10)
src/Tests/Consolonia.Core.Tests/PixelTests.cs (2)

146-149: LGTM! Consider using a named constant for better readability.

The change from PixelBackgroundMode.Shaded to an explicit color value makes the test more precise. However, the hex color could be made more readable.

Consider defining a constant at the class level for better readability:

 public class PixelTests
 {
+    private static readonly Color SemiTransparentBlack = Color.Parse("#7F000000");
     // ... rest of the tests

177-195: LGTM! Consider enhancing assertion messages.

The new tests cover important edge cases for text visibility. However, the assertions could be more descriptive.

Consider using more descriptive assertions:

-            Assert.True(newPixel.Foreground.Symbol.Text == "x");
+            Assert.That(newPixel.Foreground.Symbol.Text, Is.EqualTo("x"), 
+                "Text should remain visible through semi-transparent background");
-            Assert.True(newPixel.Foreground.Symbol.Text == "x");
+            Assert.That(newPixel.Foreground.Symbol.Text, Is.EqualTo("x"), 
+                "Text should remain visible when covered by a null character with semi-transparent background");
src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (4)

110-110: TODO comment needs to be addressed

The TODO comment suggests implementing an approximate alpha comparison. This should be extracted into an extension method for better maintainability.

Would you like me to help implement the alpha comparison extension method?


119-134: Optimize the non-transparent background handling logic

The current implementation can be simplified by restructuring the conditional blocks.

Consider this refactoring to improve readability:

 if (!pixelAbove.Foreground.NothingToDraw())
 {
     newForeground = pixelAbove.Foreground;
 }
 else if (pixelAbove.Background.Color.A == 0xFF)
 {
     // non-transparent layer above
     newForeground = new PixelForeground();
 }
 else
 {
     newForeground = new PixelForeground(Foreground.Symbol,
         MergeColors(Foreground.Color, pixelAbove.Background.Color),
         Foreground.Weight,
         Foreground.Style,
         Foreground.TextDecoration);
 }

136-136: Consider simplifying caret handling

As suggested in previous reviews, the caret handling could be moved to the PixelBuffer level since Avalonia typically only has a single focus point.

This would simplify the Pixel struct and improve memory usage. Consider creating a separate PR to implement this architectural improvement.


150-172: LGTM: Well-implemented alpha blending

The color merging implementation is mathematically correct and handles edge cases properly. The comments clearly explain each step of the process.

Consider adding a reference to the alpha compositing formula being used (e.g., Porter-Duff over operator) in the method's XML documentation.

src/Consolonia.Core/Drawing/ConsoleBrush.cs (3)

7-10: LGTM! Good architectural improvement.

The transition to a static utility class with a focused responsibility of converting brushes to colors is a solid architectural decision. The new method signature returning Color directly is more straightforward and eliminates unnecessary object creation.


11-11: TODO: Implement brush opacity handling.

The brush opacity is currently not being applied. This could affect the visual appearance of rendered elements.

Would you like me to help implement the brush opacity handling? I can provide a solution that properly applies the opacity value from the brush to the resulting color.


88-89: Remove unnecessary TODO comment.

Based on previous feedback, RaiseNotSupported already throws an exception by default, so the TODO comment about allowing it to return a result is unnecessary.

-    ConsoloniaPlatform.RaiseNotSupported(751, brush); //todo: allow RaiseNotSupported to return a result
-    return new Color();
+    ConsoloniaPlatform.RaiseNotSupported(751, brush);
src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs (1)

602-605: LGTM! Consider extracting color constants.

The conversion from ConsoleBrush to SolidColorBrush is correct. However, consider extracting the color values into constants for better maintainability.

+    private static readonly Color LowGdpColor = Colors.Yellow;
+    private static readonly Color MediumGdpColor = Colors.DarkGoldenrod;
+    private static readonly Color HighGdpColor = Colors.Green;
+
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     {
         if (value is int gdp)
         {
             if (gdp <= 5000)
-                return new SolidColorBrush(Colors.Yellow);
+                return new SolidColorBrush(LowGdpColor);
             if (gdp <= 10000)
-                return new SolidColorBrush(Colors.DarkGoldenrod);
-            return new SolidColorBrush(Colors.Green);
+                return new SolidColorBrush(MediumGdpColor);
+            return new SolidColorBrush(HighGdpColor);
         }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a04477 and 99959c8.

📒 Files selected for processing (11)
  • src/Consolonia.Core/Drawing/ConsoleBrush.cs (4 hunks)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (5 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (3 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs (1 hunks)
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs (2 hunks)
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryDataGrid.axaml.cs (1 hunks)
  • src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs (2 hunks)
  • src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml (1 hunks)
  • src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml (1 hunks)
  • src/Example/Views/DataGridTestWindow.axaml (1 hunks)
  • src/Tests/Consolonia.Core.Tests/PixelTests.cs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/PixelBackgroundMode.cs
  • src/Consolonia.Themes/Templates/Controls/Helpers/ConsoloniaTextPresenter.cs
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryColors.axaml.cs
  • src/Example/Views/DataGridTestWindow.axaml
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs
  • src/Consolonia.Themes/Templates/TurboVisionDefaultColors.axaml
  • src/Consolonia.Themes/TurboVisionDark/TurboVisionDarkColors.axaml
🧰 Additional context used
📓 Learnings (1)
src/Consolonia.Core/Drawing/ConsoleBrush.cs (1)
Learnt from: jinek
PR: jinek/Consolonia#227
File: src/Consolonia.Core/Drawing/ConsoleBrush.cs:86-92
Timestamp: 2024-12-25T18:38:21.666Z
Learning: `ConsoloniaPlatform.RaiseNotSupported(...)` already throws an exception by default, so there is no need to add another explicitly thrown exception in this scenario.
🔇 Additional comments (3)
src/Tests/Consolonia.Core.Tests/PixelTests.cs (1)

164-174: LGTM! Improved test accuracy for edge cases.

The assertion change from "darker than" to "not lighter than" is a good improvement that correctly handles edge cases, particularly when the background is already black.

src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (1)

43-43: LGTM: Constructor simplification

The constructor now uses a simpler initialization approach with a default PixelBackground, which aligns well with the PR's goal of removing console brush complexity.

src/Consolonia.Core/Drawing/ConsoleBrush.cs (1)

Line range hint 93-134: LGTM! Solid implementation of color calculations.

The color interpolation and blending logic is well-implemented with proper handling of edge cases and mathematical calculations.

Copy link
Collaborator

@tomlm tomlm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
I think this used to show compound unicode chars. Shoot, I just checked main and main does the same thing.

We have a regression in unicode rendering of compound characters.
#229 filed

tomlm
tomlm previously approved these changes Dec 25, 2024
Copy link
Collaborator

@tomlm tomlm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the unicode regression is not yours. i will file a bug against myself to investigate.

@jinek
Copy link
Owner Author

jinek commented Dec 25, 2024

My feedback are suggestions/comments, but this looks good.

fixed several

@jinek jinek enabled auto-merge (squash) December 25, 2024 21:46
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/Consolonia.Core/Drawing/BrushExtensions.cs (2)

7-7: Consider syncing file name with class name.

Although this likely doesn't cause functional problems, it's best practice to match the file name with the class name.


88-89: Consider throwing or returning a default color more explicitly.

Using RaiseNotSupported then returning a zeroed color might mask errors downstream. Evaluate throwing an exception or returning a fallback color with clear intent.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99959c8 and f8adc28.

📒 Files selected for processing (3)
  • src/Consolonia.Core/Drawing/BrushExtensions.cs (4 hunks)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (5 hunks)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs
🔇 Additional comments (5)
src/Consolonia.Core/Drawing/BrushExtensions.cs (5)

9-9: Extension method signature looks good.

The FromPosition extension method follows a clear pattern for retrieving the color from any brush at a given coordinate.


36-36: Check horizontal-vertical averaging logic for linear gradients.

Averaging the horizontal and vertical interpolations may yield unintended colors for strictly linear gradients. Consider verifying that this behavior matches design requirements.


63-63: Radial gradient logic appears consistent but ensure performance.

Calculating distance with repeated square-root operations can be slightly heavier. This is likely fine for general usage, but be aware if performance-critical contexts arise.


81-81: Potentially misleading name for conic gradient logic.

Currently, the logic mimics the linear gradient approach by blending horizontal and vertical colors. Confirm if this superficial approach meets requirements for a true conic gradient effect.


84-86: Directly returning the solid color brush value is straightforward.

No issues found; the code accurately fetches and returns the Color property.

@jinek jinek mentioned this pull request Dec 25, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (2)

110-110: TODO: Extract transparency check to extension method

The TODO comment suggests extracting the transparency check to an extension method. This would improve code reusability and readability.

Consider adding an extension method like:

+ public static class ColorExtensions 
+ {
+     public static bool IsFullyTransparent(this Color color, float threshold = 0.0f) 
+     {
+         return color.A <= threshold * 255;
+     }
+ }

Then update the check:

- if (pixelAbove.Background.Color.A == 0x0)
+ if (pixelAbove.Background.Color.IsFullyTransparent())

152-174: Replace ChatGPT attribution with technical documentation

The color merging implementation is correct and uses proper alpha blending formulas. However, the ChatGPT attribution should be replaced with technical documentation explaining the alpha blending formula and its mathematical basis.

Consider replacing the comment with:

- // by chatGPT o1
+ // Alpha blending implementation using the Porter-Duff 'over' operator
+ // Formula: C_out = (C_s * α_s + C_b * α_b * (1 - α_s)) / α_out
+ // where α_out = α_s + α_b * (1 - α_s)
+ // C_s: source color, C_b: backdrop color, α_s: source alpha, α_b: backdrop alpha
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8adc28 and 1c32687.

📒 Files selected for processing (1)
  • src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (3 hunks)
🔇 Additional comments (2)
src/Consolonia.Core/Drawing/PixelBufferImplementation/Pixel.cs (2)

43-43: LGTM: Constructor simplification aligns with architectural changes

The simplified background initialization aligns with the architectural changes to remove background modes in favor of color-based backgrounds.


106-138: LGTM: Improved blending logic with clear separation of concerns

The blending logic has been improved with:

  • Clear separation between transparent and non-transparent cases
  • Special optimization for fully opaque backgrounds
  • Proper color merging for semi-transparent cases

@tomlm tomlm self-requested a review December 25, 2024 23:20
@jinek jinek merged commit 2dd81ad into main Dec 25, 2024
3 checks passed
@jinek jinek deleted the 190-strange-coloring-remove-console-brush branch December 25, 2024 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants