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

Add ability to define linestyle for each edge when drawing a linebrush. #246

Merged
merged 7 commits into from
Jan 4, 2025

Conversation

tomlm
Copy link
Collaborator

@tomlm tomlm commented Jan 4, 2025

Example:
LineStyle="SingleLine SingleLine DoubleLine DoubleLine"
Will produce single line on left and top side and double line on right bottom.

Pattern is same as Thickness definitions: Left Top Right Bottom
If you define partial then last definition will apply.
image

Added unit tests, assignment operators etc.

tomlm added 5 commits January 3, 2025 17:54
Example:
```LineStyle="SingleLine DoubleLine SingleLine DoubleLine"```
Will produce single line on left and right side and double line on top bottom.

Pattern is same as Thickness definitions: Left Top Right Bottom
If you define partial then last definition will apply.
Copy link
Contributor

coderabbitai bot commented Jan 4, 2025

📝 Walkthrough

Walkthrough

This pull request modifies the LineBrush class in the Consolonia.Controls namespace to change the type of LineStyleProperty and the LineStyle property from LineStyle to LineStyles. A new LineStyles class is introduced, which allows for multiple line styles to be defined for the Left, Top, Right, and Bottom sides. The DrawingContextImpl class is updated to streamline the drawing logic, accommodating the new LineStyles structure. Additionally, a new test class LineStylesTests is created to cover various functionalities of the LineStyles class, including parsing, construction, and serialization.

Possibly related PRs

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 bot commented Jan 4, 2025

Warning

Rate limit exceeded

@tomlm has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 28 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7afa196 and 5691e4e.

📒 Files selected for processing (5)
  • src/Consolonia.Core/Controls/LineBrush.cs (1 hunks)
  • src/Consolonia.Core/Controls/LineStyles.cs (1 hunks)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (9 hunks)
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryBorders.axaml (2 hunks)
  • src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LineStylesTests.cs (1 hunks)

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 bot commented Jan 4, 2025

📝 Walkthrough

Walkthrough

This pull request introduces a comprehensive enhancement to line style handling in the Consolonia framework. The changes primarily revolve around creating a new LineStyles class that allows for more granular control over line styles for different sides of an element (Left, Top, Right, Bottom). The modification extends from the LineBrush class, where the LineStyleProperty and LineStyle are updated to use the new LineStyles type. The implementation includes parsing capabilities, multiple constructors, and implicit conversion operators to provide flexible line style configuration. Corresponding updates were made in the DrawingContextImpl to support this new type, and comprehensive unit tests were added to validate the new LineStyles functionality.

Possibly related PRs

Suggested reviewers

  • jinek

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: 1

🧹 Nitpick comments (7)
src/Consolonia.Core/Controls/LineStyles.cs (2)

12-15: Consider validating empty or invalid input in Parse.
Currently, Parse directly calls the constructor that expects valid strings. Adding minimal validation (e.g., if (string.IsNullOrWhiteSpace(s))) could help avoid cryptic exceptions when receiving incorrect input from external sources.


42-50: Implicit operators enhance ease of use.
These implicit conversions from string and LineStyle to LineStyles reduce boilerplate code. Keep an eye out for ambiguous call scenarios when multiple conversions might apply.

src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LineStylesTests.cs (1)

11-19: Robust test ensures single-style strings apply to all edges.
The test coverage for "SingleLine" is good. It might be beneficial to also test an empty string scenario if the LineStyles.Parse method will handle it in the future.

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

154-178: Stream geometry handling is neatly separated for fills and strokes.
This block uses InferStrokePositions to decide which line to draw. The approach is clear. Just confirm that shapes with more complex geometry (e.g., non-rectangular shapes) don’t produce unexpected stroke outcomes.


210-214: Using sceneBrushContent for rendering is straightforward but lacks error handling.
Consider verifying sceneBrushContent.Size or other properties to ensure the content is valid before rendering.


477-501: Efficient brush-based rectangle filling with fallback brush logic.
The nested loops and ExecuteWithClipping(...) calls handle partial coverage. Ensure performance remains acceptable for large rectangles, as each pixel calls a lambda.


722-735: Tab handling is thorough but could be user-configurable.
The constant tabSize = 8 might not suit all use cases. You might consider a method parameter or global setting if your app deals with text editors or text-based UIs.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7afa196 and 5691e4e.

📒 Files selected for processing (5)
  • src/Consolonia.Core/Controls/LineBrush.cs (1 hunks)
  • src/Consolonia.Core/Controls/LineStyles.cs (1 hunks)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (9 hunks)
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryBorders.axaml (2 hunks)
  • src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LineStylesTests.cs (1 hunks)
🔇 Additional comments (14)
src/Consolonia.Core/Controls/LineBrush.cs (2)

16-17: Use of LineStyles for LineStyleProperty is well-aligned with the new feature.
This update correctly shifts from a single LineStyle to the more granular LineStyles. Make sure to confirm that any existing bindings in XAML (or code) referencing LineStyleProperty are updated accordingly.


25-25: Property rename from LineStyle to LineStyles is consistent with the property type change.
The new property type and name match usage patterns in the rest of the codebase. Ensure the property usage is thoroughly tested, especially with partial style definitions (e.g., only specifying two edges).

src/Consolonia.Core/Controls/LineStyles.cs (2)

22-32: Parsing flexible tokens is helpful; consider stricter error checks.
The code splits on spaces and commas, then parses each token into LineStyle without catching potential ArgumentException from Enum.Parse. If user input contains invalid tokens, it will throw. You may want to catch or rethrow a more meaningful error.


34-40: Smart fallback logic for partial constructor arguments.
Using default values (??) to progressively assign Top, Right, and Bottom is a neat approach. Ensure there's a test scenario that specifically verifies each fallback scenario.

src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LineStylesTests.cs (3)

41-49: Quad-style test covers all four edges.
Great way to confirm the fallback logic doesn’t kick in. The usage of spaces vs. commas is well-tested.


51-56: Exception test ensures robust error handling.
Verifies that too many style tokens result in an ArgumentException. Consider testing invalid token text (e.g., "SingleLine,NotAStyle") to confirm Enum.Parse exceptions are also as expected.


150-157: JSON serialization test ensures long-term maintainability.
Serialization coverage is often overlooked, so it’s great to see it tested here. If backward compatibility is needed, you might confirm stable JSON property names or consider a custom contract resolver.

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

99-129: Quad-pixel approach for bitmap drawing is well-structured but watch for indexing issues.
The loops skip in increments of two, then reindex by /2 for the final px and py. Consider adding upper-bound checks or logging to prevent accidental out-of-bounds errors if bitmap.Info.Width or .Height is odd.


216-225: Caret reposition logic is direct.
Nice approach. If future expansions require multiple caret positions or multi-line caret movement, consider factoring this logic into a dedicated class or method.


518-531: Segmented line logic for top, right, bottom, left is consistent with new LineStyles.
Good alignment with the new enumerations. For unknown or diagonal lines, the fallback to SingleLine is a reasonable default.


617-622: Signature change to ExtractColorOrNullWithPlatformCheck(IPen pen, out LineStyles lineStyles) is a good step forward.
You replaced LineStyle? with LineStyles, ensuring a default always exists. Make sure consumers of ExtractColorOrNullWithPlatformCheck handle the possibility that the returned Color? can be null.


745-803: Wide glyph handling logic is comprehensive.
You carefully reset overlapped characters and handle multi-width emojis properly. Testing with complex scripts and combining characters can help ensure no edge cases remain.

src/Consolonia.Gallery/Gallery/GalleryViews/GalleryBorders.axaml (2)

58-65: Excellent implementation of the mixed line styles feature!

The new Border element effectively demonstrates the ability to define different line styles for each edge. The syntax "SingleLine SingleLine DoubleLine DoubleLine" follows a clear left-top-right-bottom pattern, making it intuitive for users. The accompanying TextBlock provides clear documentation of the feature.


82-82: LGTM: Color change improves visual distinction

Changing the brush color to "Red" helps in better distinguishing this border example from others in the gallery.

src/Consolonia.Core/Drawing/DrawingContextImpl.cs Outdated Show resolved Hide resolved
Copy link
Contributor

coderabbitai bot commented Jan 4, 2025

Caution

Review failed

The head commit changed during the review from 5dff566 to 1635f65.


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.

@tomlm tomlm enabled auto-merge (squash) January 4, 2025 02:30
@tomlm tomlm requested a review from jinek January 4, 2025 02:30
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/Consolonia.Core/Drawing/DrawingContextImpl.cs (1)

166-177: Use helper method or dictionary to condense repeated block checks.

This block handles each rectangle line position with multiple if-else statements. Consider replacing the chain of conditionals with a more concise approach (e.g., a lookup table) to reduce repetition and improve readability.

src/Consolonia.Core/Controls/LineStyles.cs (1)

17-27: Parsing logic is robust for partial/complete definitions.

Splitting the string and assigning the leftover style to subsequent sides is a straightforward approach. Consider validating the tokens to gracefully handle invalid enums or trailing whitespace.

src/Consolonia.Gallery/Gallery/GalleryViews/GalleryBorders.axaml (1)

82-82: Potential styling consistency check.

Changing the brush for this border to “Red” might conflict with surrounding examples. Ensure it’s intentional if you want consistent theming across the gallery.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7afa196 and 1635f65.

📒 Files selected for processing (5)
  • src/Consolonia.Core/Controls/LineBrush.cs (1 hunks)
  • src/Consolonia.Core/Controls/LineStyles.cs (1 hunks)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (4 hunks)
  • src/Consolonia.Gallery/Gallery/GalleryViews/GalleryBorders.axaml (2 hunks)
  • src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LineStylesTests.cs (1 hunks)
🔇 Additional comments (30)
src/Consolonia.Core/Drawing/DrawingContextImpl.cs (5)

518-519: Ensure we handle null pen scenarios gracefully.

The ExtractColorOrNullWithPlatformCheck call is made unconditionally. If pen might be null, you could encounter null references outside of the null check. Verify that upstream logic prevents a null pen from reaching here.


525-532: Switch expression usage is clear and efficient.

The new switch expression picking the correct side’s style is well-structured. Great job keeping it readable.


536-536: Separate logic for edge lines vs. normal lines.

Calling DrawEdgeLine is a good approach to keep specialized logic separate. No issues spotted.


541-547: Inline comments improve clarity.

The inline comments (“//beginning”, “//line”, “//ending”) clarify the line-drawing segments. This is good for maintainability.


Line range hint 618-647: Leverage consistent defaults for missing brush references.

When no suitable brush is found (or pen doesn't match expected types), the method returns null or uses a default LineStyles. Confirm that callers handle a null return gracefully to avoid silent rendering failures.

src/Consolonia.Core/Controls/LineBrush.cs (2)

16-17: Property name aligns with multi-style usage.

Renaming to LineStyleProperty of type LineStyles makes sense given the new multi-side feature.


25-25: Expanding the property to multiple sides.

Switching from a single LineStyle to LineStyles is consistent with the new design. Good job integrating the updated type.

src/Consolonia.Core/Controls/LineStyles.cs (7)

1-9: Namespace and directives are clean.

Imports and namespace structure look consistent with the rest of the codebase.


12-15: Default constructor establishing reasonable defaults.

All sides default to SingleLine, which is intuitive for minimal configuration.


29-36: Param-based constructor handles null values gracefully.

Falling back to the preceding side’s style if a parameter is not provided is a neat approach. Well done.


38-41: Properties are straightforward.

Exposing each side (Left, Top, Right, Bottom) is essential for fine-grained control.


43-46: Parse method convenient for direct string usage.

Encapsulation of parsing logic behind Parse helps standardize line style creation.


48-51: Implicit operator from string.

This makes calling code more succinct, allowing direct assignment from a string.


53-56: Implicit operator from single LineStyle.

Automatically converting a single LineStyle to a LineStyles object is consistent with the other usage patterns.

src/Consolonia.Gallery/Gallery/GalleryViews/GalleryBorders.axaml (1)

58-65: Demonstrates multiple line styles on different edges.

Using "SingleLine SingleLine DoubleLine DoubleLine" is a helpful example. This clarifies how the new multi-side feature can be configured in XAML.

src/Tests/Consolonia.Core.Tests/WithLifetimeFixture/LineStylesTests.cs (15)

11-19: Single style test coverage.

Validates that a single token sets all sides consistently to SingleLine.


21-29: Double style test ensures fallback behavior.

Confirms that the second style is applied to remaining edges.


31-39: Triple style test extends fallback logic.

Checks partial override for sides, verifying correct inheritance rules.


41-49: Quad style test ensures all sides can be distinct.

Demonstrates full coverage for Left, Top, Right, Bottom. Good scenario coverage.


51-55: Validation of invalid input.

Confirming an ArgumentException for too many tokens is an important negative test.


57-65: Empty constructor test.

Verifies default values are all SingleLine. Straightforward and vital.


67-75: Single constructor param test.

Checks if all sides match the single provided style. This is an essential scenario.


77-85: Two-parameter constructor test.

Ensures leftover sides inherit from the last non-null style. Nicely tested.


87-95: Three-parameter constructor test.

Similarly checks partial definition logic. Good thorough coverage.


97-105: Four-parameter constructor test.

Verifies each side can be independently set. No issues here.


107-115: Constructor with final null parameter.

Ensures the bottom style defaults to the third parameter correctly.


117-125: Constructor with all null.

Asserts that all sides remain SingleLine. Good boundary test.


127-135: Implicit conversion from string test.

Verifies that string-based initialization yields correct side assignments via the implicit operator.


137-145: Implicit conversion from enum test.

Checks that a single LineStyle automatically populates all sides, as intended.


147-157: JSON serialization round-trip.

Ensures that LineStyles can be serialized and deserialized without losing data. Perfect approach to maintain state across application boundaries.

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/DrawingContextImpl.cs (2)

165-176: Consider using a switch expression for better readability.

The repeated if-else chain can be simplified using a switch expression for a more concise and maintainable code.

-            if (strokePosition == RectangleLinePosition.Left)
-                DrawBoxLineInternal(pen, stroke, RectangleLinePosition.Left);
-            else if (strokePosition == RectangleLinePosition.Right)
-                DrawBoxLineInternal(pen, stroke, RectangleLinePosition.Right);
-            else if (strokePosition == RectangleLinePosition.Top)
-                DrawBoxLineInternal(pen, stroke, RectangleLinePosition.Top);
-            else if (strokePosition == RectangleLinePosition.Bottom)
-                DrawBoxLineInternal(pen, stroke, RectangleLinePosition.Bottom);
+            DrawBoxLineInternal(pen, stroke, strokePosition switch
+            {
+                RectangleLinePosition.Left => RectangleLinePosition.Left,
+                RectangleLinePosition.Right => RectangleLinePosition.Right,
+                RectangleLinePosition.Top => RectangleLinePosition.Top,
+                RectangleLinePosition.Bottom => RectangleLinePosition.Bottom,
+                _ => strokePosition
+            });

Line range hint 620-646: Remove unnecessary initialization of lineStyles.

The initialization of lineStyles to null on line 622 is unnecessary as it's always assigned a value before being returned.

-        private static Color? ExtractColorOrNullWithPlatformCheck(IPen pen, out LineStyles lineStyles)
-        {
-            lineStyles = null;
+        private static Color? ExtractColorOrNullWithPlatformCheck(IPen pen, out LineStyles lineStyles)
+        {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1635f65 and a823d38.

📒 Files selected for processing (1)
  • src/Consolonia.Core/Drawing/DrawingContextImpl.cs (4 hunks)
🔇 Additional comments (1)
src/Consolonia.Core/Drawing/DrawingContextImpl.cs (1)

517-531: LGTM! Clean implementation of multi-edge line styles.

The implementation elegantly handles different line styles for each edge position with a clear switch expression and sensible default.

@tomlm tomlm merged commit 74d9550 into main Jan 4, 2025
2 checks passed
@tomlm tomlm deleted the tomlm/lineStyles branch January 4, 2025 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants