Pablo-Gonzalez-Calderon / showybox-package

A Typst package for creating colorful and customizable boxes
MIT License
49 stars 5 forks source link

Add ability to change each corner to be sharp/round (separate for frame and boxed title) #16

Closed Andrew15-5 closed 11 months ago

Andrew15-5 commented 11 months ago

From tcolorbox's documentation v5.1.1, Section 4.8:

image

This can be seen as overkill, because there are a lot of values + the naming scheme is not very friendly, as not all people use compass directions to denote direction (I think it's only an American thing). Especially if you don't go anywhere, like with drawing corners. It may be cool to be more compatible with the LaTeX's package, but readability should be a priority in Typst.

I think that alternative values can be used:

But downhill and uphill can be confusing, so we can exclude those (they can stay) and add an array of the written values:

#showybox(
  frame: (
    sharp-corners: ( // Make 3 out of 4 corners sharp
      "top",
      "bottom-left",
    ),
  ),
)[body content]

The sharp-corners/round-corners properties are pretty readable, but if 2 separate properties (with identical content) are not good, then we can make something like:

#showybox(
  frame: (
    corners-style: "sharp", // "round" | "sharp" (default: "round"),
    // or
    sharp-corners: true, // boolean (default: false),
    // or
    round-corners: false, // boolean (default: true),
    corners: ( // Make 3 out of 4 corners sharp (default: "all")
      "top",
      "bottom-left",
    ),
  ),
)[body content]
Pablo-Gonzalez-Calderon commented 11 months ago

Actually, this feature is already possible with v1.1.0 current properties, using radius. But it's only available in untitled showyboxes (jus now I've realized that).

I made a little change to the code, and now it's fully possible to do that without adding a new propertie:

#showybox(
  frame: (
    radius: (top-left: 0pt, bottom-right: 0pt, rest: 10pt),
    thickness: 3pt
  ),
  title: "Sharp corners",
  width: 50%,
)[#lorem(10)]

#showybox(
  frame: (
    radius: (top: 5pt),
    thickness: 3pt
  ),
  title: "Sharp corners",
  width: 50%,
)[#lorem(10)]

#showybox(
  frame: (
    radius: (top: 5pt),
    thickness: 3pt
  ),
  title-style: (
    boxed: true
  ),
  boxed-style: (
    anchor: (x: center)
  ),
  title: "Sharp corners",
  width: 50%,
)[#lorem(10)]

will look like image

Andrew15-5 commented 11 months ago

But radius applies to both frame and title. This is very inconvenient. If radius can't be applied only to the boxed title, then this should be fixed.

Pablo-Gonzalez-Calderon commented 11 months ago

Hmm, thats true.

Maybe adding a radius option inside boxed-style would help to fix that 🧐

Andrew15-5 commented 11 months ago

You should re-open the issue then (I can't do that).

Pablo-Gonzalez-Calderon commented 11 months ago

Finally, with some changes, it's possible to have separate radii for both the boxed title and the frame: image

(last two showyboxes' code is...)

#showybox(
  frame: (
    radius: (top: 5pt),
    thickness: 3pt
  ),
  title-style: (
    boxed: true
  ),
  boxed-style: (
    anchor: (x: center)
  ),
  title: "Sharp corners",
  width: 50%,
)[#lorem(10)]

#showybox(
  frame: (
    radius: (top: 5pt),
    thickness: 3pt,
  ),
  title-style: (
    boxed: true
  ),
  boxed-style: (
    anchor: (x: center),
    radius: 0pt
  ),
  shadow: (
    offset: 4pt,
  ),
  title: "Sharp corners",
  width: 50%,
)[#lorem(10)]

I think this solves the issue, unless you have something to say 🧐

Andrew15-5 commented 11 months ago

Finally, with some changes, it's possible to have separate radii for both the boxed title and the frame: image

Why the top-left corner of the frame isn't fully filled in the 1st example?

Pablo-Gonzalez-Calderon commented 11 months ago

It seems like a border-case. It's because of the radius dictionary that block() can handle. There, you can put a top-"align" (e.g. top-left) alignment, but alignment type can't handle those types of align (list of valid aligns are here).

I changed a little bit the code, so top-left and top-right alignments are gotten while setting title's top radius. And, if any of them is not present, it uses top alignment to replace it (if present).

Now, the title looks good: image

I will clean a little bit the code, and push the commits from my local repo to GitHub. So, a better testing of the feature can be done

Andrew15-5 commented 11 months ago

I've tested my issue example. It works! I've noticed that boxed-style(offset) only works with boxed-style(anchor(y: top | horizon)), but not with bottom. Is this intentional? In any case, why make such limitation?

Pablo-Gonzalez-Calderon commented 11 months ago

I've tested my issue example. It works! I've noticed that boxed-style(offset) only works with boxed-style(anchor(y: top | horizon)), but not with bottom. Is this intentional? In any case, why make such limitation?

That's weird 🧐, I'll take a look to the code. bottom boxed titles are drawn differently from horizon and top because there's no need for moving the showybox top border, maybe that's the problem. Probably is a one-line fix

Andrew15-5 commented 11 months ago

Another thing that is bothering me is the opposite behavior of anchor(y: top and bottom). The anchor is the Y coordinate of the title box that should be clipped/pinned to the center of the top border of the frame. When anchor: (y: horizon) is used, the center of the title box (Y coordinate) is connected to the top border of the frame. If anchor: (y: bottom) is used, then the bottom of the title box should be connected to the border of the frame. And with anchor: (y: top) — the top of the title box should be connected.

As I said, basically, the top and bottom anchor(y) should be swapped (their logic/behavior). You can see how anchor property is used and behave in cetz package.

Pablo-Gonzalez-Calderon commented 11 months ago

I've tested my issue example. It works! I've noticed that boxed-style(offset) only works with boxed-style(anchor(y: top | horizon)), but not with bottom. Is this intentional? In any case, why make such limitation?

That's weird 🧐, I'll take a look to the code. bottom boxed titles are drawn differently from horizon and top because there's no need for moving the showybox top border, maybe that's the problem. Probably is a one-line fix

It was a missing move element to implement. Now it's working. Here's an example 😉

image

Pablo-Gonzalez-Calderon commented 11 months ago

Another thing that is bothering me is the opposite behavior of anchor(y: top and bottom). The anchor is the Y coordinate of the title box that should be clipped/pinned to the center of the top border of the frame. When anchor: (y: horizon) is used, the center of the title box (Y coordinate) is connected to the top border of the frame. If anchor: (y: bottom) is used, then the bottom of the title box should be connected to the border of the frame. And with anchor: (y: top) — the top of the title box should be connected.

As I said, basically, the top and bottom anchor(y) should be swapped (their logic/behavior). You can see how anchor property is used and behave in cetz package.

Yeah, it makes more sense. I don't have really internalized the word "anchor" in my mind, so I always think of it as align 🤣. I've just pushed a version with the change 😉

Andrew15-5 commented 11 months ago

Cool! Now everything is working. But we still need y: horizon to be in the center. We have 2 options:

I think the 2nd option is better, since center is more applicable than horizon and it is present in anchor(x). The current horizon behavior can be achieved by anchor: (y: bottom), offset: (y: 0.5em) if the vertical offset is implemented (which is the 2nd and the last thing to do).

Andrew15-5 commented 11 months ago

The very last thing would be to discuss and make a decision on the naming scheme of the new boxed title features.

Pablo-Gonzalez-Calderon commented 11 months ago

Cool! Now everything is working. But we still need y: horizon to be in the center. We have 2 options:

  • make y: center as a 4th value or
  • replace horizon with `center.

I think the 2nd option is better, since center is more applicable than horizon and it is present in anchor(x). The current horizon behavior can be achieved by anchor: (y: bottom), offset: (y: 0.5em) if the vertical offset is implemented (which is the 2nd and the last thing to do).

Yes, we still have to discuss that. Since we already have started talking of that in issue #13, I'm going to close this and continue the talk there. Thank you!

Andrew15-5 commented 11 months ago

Oops, I thought it was already #13. My bad.