Skip to content

Commit

Permalink
update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
dustpg committed Jun 27, 2020
1 parent f1915c4 commit 304979c
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 3 deletions.
Binary file added doc/blog/images/barbutton.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 35 additions & 3 deletions doc/blog/layout-size.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Size 种类

以width作为例子

类型 | 下限 | 建议 | 上限
Expand All @@ -24,10 +26,40 @@ case BKDR_MINHEIGHT:
break;
```

一个最简单的例子就是图像`<image>`,建议宽度就是使用图片的宽度,下限宽度可以考虑`0`或者`1`

复杂点的例子就是箱型布局`<box>`。LongUI中,使用对应滚动条(这里就是水平滚动条)的`<box>`下限宽度会调整到`0`,建议宽度依然是有效子控件建议宽度(以及边框什么的)累加。如果没有使用滚动条则两值相同。

一个最简单的例子就是图像`<image>`,建议宽度就是使用图片的宽度,下限宽度可以考虑`0`或者`1`。但是需要设置`flex`为有效值, 否则布局器依然会按照图片尺寸布局.

复杂点的例子就是箱型布局`<box>`。LongUI中,使用对应滚动条(这里就是水平滚动条)的`<box>`下限宽度会调整到`0`,建议宽度依然是有效子控件建议宽度(以及 `margin` 什么的,具体来说是 CSS 属性`box-sizing`控制的,XUL默认是`box-sizing: border-box`, LongUI中目前不支持动态切换`box-sizing`)累加.

而一旦使用CSS值,则以设置值为准。

正常控件大小应该介于建议值与最大值之间,特殊情况会处于最小值与建议值之间。而这种特殊情况`<box>`处理方式有点违背常理——`flex`越大的值反而最小,可以理解为以建议值作为起点,`flex`作为伸缩参数,越大的伸得越大,缩得也越大。
正常控件大小应该介于建议值与最大值之间,特殊情况会处于最小值与建议值之间。而这种特殊情况`<box>`处理方式有点违背常理——`flex`越大的值反而最小,可以理解为以建议值作为起点,`flex`作为伸缩参数,越大的伸得越大,缩得也越大。


# 布局算法

LongUI中`<box>`布局算法如下, 为了方便说明先定义一些东西:
- 有效布局子控件: `<box>`子控件中不是所有子控件都参与布局,最简单的,如果`visible``false` 或者是类似于滚动条之类的控件,是不参与布局的。而参与布局的子控件这里称为 有效布局子控件
- 最低滚动尺寸: 如果内容区大小小于这个尺寸就需要显示滚动条或者滚动按钮
- 建议尺寸: 这个上面以及说明了
- 有效内容区大小: 所有的控件应该将子控件放在内容区,而`box`可能有滚动条或者滚动按钮,如果显示这些控件,有效内容区需要减去这些。

具体算法,以`<hbox>`为栗子:
1. 确定有效内容区大小,自身建议宽度等预备数据
2. 先将有效布局子控件中`flex`(`f`)累加起来作为`F``F`自然最小为`0`
3. 有效内容区宽度 减去 建议宽度 作为`S`, 注意`S`可能为负数
4. 遍历每个有效布局子控件,将控件临时宽度设置为建议宽度
5.`U = S / F`. 当`F``0`时, 结束计算. (注: 如果`F`实现为浮点数时候注意浮点误差)
6. 遍历每个有效布局子控件
7. 将控件临时宽度 加上 `f * U`, 注意需要将宽度钳制到`min-width max-width`之间
8.`S`减去 实际变化量
9. `S`有变化,并且当宽度被钳制时, 让`F`减去`f`
10. 如果`F`没有变化,也结束计算,否则回到步骤5。


算法复杂度:
- 极大概率: O(N)
- 理论最差: O(N^2)

最后确定的临时宽度就是控件的最终宽度,而控件的另一维度,即高度,对齐方式由其他属性控制,与主维度宽度相比就简单多了,不再赘述。
85 changes: 85 additions & 0 deletions doc/xul/stacks-and-decks.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
There may be need to display elements as a set of overlapping cards. The stack and deck elements can be used for this purpose.

# Containers

Each XUL box is a container that can contain any other element. There are a number of elements that are specialized types of boxes, such as [toolbars](./toolbars.md) and [tabbed panels](./tabboxes.en.md). The [box](./box.md) tag creates the simplest box with no special properties. However, the specialized types of boxes work just like regular boxes in the way they `orient` the elements inside them, but they have additional features.

In fact, many components can contain other elements. We've already seen that buttons may contain other things besides the default. A scroll bar is just a special type of box that creates its own elements if you don't provide them. It also handles the moving of the scroll bar thumb.

In the next few sections, we'll introduce some elements that are designed for holding other elements. They are all special types of boxes and allow all of the attributes of boxes on them.


# Stacks

The [stack](./stack.md) element is a simple box. It works like any other box but has the special property that its children are laid out all on top of each other. The first child of the stack is drawn underneath, the second child is drawn next, followed by the third and so on. Any number of elements may be stacked up in a stack.

The `orient` property has little meaning on a stack as children are laid out above each other rather than from side to side. The size of the stack is determined by its largest child, but you can use the CSS properties `width`, `height`, `min-width` and other related properties on both the stack and its children.

The [stack](./stack.md) element might be used for cases where a status indicator needs to be added over an existing element. For example, a progress bar might be created using a bar and a label overlaid on top of it.


## Shadowing with stacks

One convenient use of the [stack](./stack.md) element however is that you could emulate a number of CSS properties with it. For example, you could create an effect similar to the text-shadow property with the following:

- Example 1
- [Source](./source/ex_stacks_1.xul)

![ex_stacks_1](./images/ex_stacks_1.png)

```xml
<stack>
<label value="Shadowed" style="padding-left: 1px; padding-top: 1px; font-size: 15px"/>
<label value="Shadowed" style="color: red; font-size: 15px;"/>
</stack>
```

Both [label](.label.md) elements create text with a size of 15 pixels. The first, however is offset one pixel to the right and down by adding a padding to its left and top sides. This has the result of drawing the same text 'Shadowed' again but slightly offset from the other. The second `label` element is drawn in red so the effect is more visible.

This method has advantages over using `text-shadow` because you could completely style the shadow apart from the main text. It could have its own font, underline or size. (You could even make the shadow blink). It is also useful as Mozilla doesn't currently support CSS text shadowing. A disadvantage is that the area taken up by the shadow makes the size of the stack larger. Shadowing is very useful for creating the disabled appearance of buttons:

- Example 2
- [Source](./source/ex_stacks_2.xul)

![ex_stacks_2](./images/ex_stacks_2.png)

```xml
<stack style="background-color: #C0C0C0">
<label value="Disabled" style="color: white; padding-left: 1px; padding-top: 1px;"/>
<label value="Disabled" style="color: grey;"/>
</stack>
```

This arrangement of text and shadow colors creates the disabled look under some platforms.

Note that events such as mouse clicks and keypresses are passed to the element on the top of the stack, that is, the last element in the stack. That means that buttons will only work properly as the last element of the stack.

# Decks

A [deck](./deck.md) element also lays out its children on top of each other much like the [stack](./stack.md) element, however decks only display one of their children at a time. This would be useful for a wizard interface where a series of similar panels are displayed in sequence. Rather than create separate windows and add navigation buttons to each of them, you would create one window and use a deck where the content changes.

Like stacks, the direct children of the [deck](./deck.md) element form the pages of the deck. If there are three children of the `deck` element, the deck will have three children. The displayed page of the deck can be changed by setting an `selectedIndex` attribute on the deck element. The index is a number that identifies which page to display. Pages are numbered starting from zero. So, the first child of the deck is page 0, the second is page 1 and so on.

- Example 3
- [Source](./source/ex_stacks_3.xul)

![ex_stacks_3](./images/ex_stacks_3.png)

```xml
<deck selectedIndex="2">
<label value="This is the first page"/>
<button label="This is the second page"/>
<box>
<label value="This is the third page"/>
<button label="This is also the third page"/>
</box>
</deck>
```

Three pages exist here, the default being the third one. The third page is a box with two elements inside it. Both the box and the elements inside it make up the page. The deck will be as large as the largest child, which here should be the third page.

You can switch pages by using a script to modify the `selectedIndex` attribute. More on this in the section on events and the DOM.

# REF

- [XUL-Stacks_and_Decks](https://developer.mozilla.org/en-US/docs/Archive/Mozilla/XUL/Tutorial/Stacks_and_Decks)
85 changes: 85 additions & 0 deletions doc/xul/stacks-and-decks.jp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
要素を重なった一組のカードのように扱えると便利なときがあります。 スタック (`stack`) 要素と、デッキ (`deck`) 要素がこのために用意されています。

# コンテナ

XUL のボックスは、それぞれが任意の要素を含むことのできるコンテナとして位置づけられます。[ ツールバー](./toolbars.md)[タブ付きパネル](./tabboxes.jp.md)のようないくつかの要素も、特定の用途のために特化したボックスの一種という位置づけになります。 [box](./box.md) タグは、特別な性質のない最も単純なボックスを作ります。 特化型のボックスは、内部に要素を配置するという点においては、通常のボックスと同じように動作しますが、それ以外の機能も追加されています。

実際のところ、多くのコンポーネントが、他の要素を含むことができます。 これは「ボタンにラベル以外の要素も含めることができる」といった、 ここまでのセクションで説明した例の中でも既に見ています。 極端な話、スクロールバーも、明示的に子要素を作成しない限り、自動で子要素を作成する機能を持った、特化型のボックスの 1 つにすぎません。 スクロールバーのもう 1 つの特殊な機能は、子要素のサムの移動を自動で処理することです。

ここからの数セクションにわたって、他の要素を保持するために設計された要素をいくつか紹介することにします。 これらは特化型のボックスで、ボックスの属性をすべて使うことができます。

# スタック

[stack](./stack.md) 要素は、単純なボックスです。 この要素は他のボックスと同じように動作しますが、子要素を重なり合うようにレイアウトできるという特質を持っています。 スタック上の最初の子要素が一番下に描かれ、次に 2 番目の子要素がその上に描かれます。 3 番目以降についても同様に続いていきます。 スタックに積み重ねることができる子要素の数に制限はありません。

スタック要素では、`orient` プロパティはあまり意味がありません。 スタックでは、子要素は並んでレイアウトされるのではなく、重なり合ってレイアウトされるからです。 スタック要素のサイズは、最も大きな子要素によって決められます。 または、スタック要素とその子要素のどちらに対しても、CSS プロパティの `width``height``min-width` 及びその他の関連するプロパティを使って明示的にサイズを指定することも可能です。

スタック要素は、既にある要素に重ねてステータス表示を追加する必要があるといった場合に使うことができます。 例えば、プログレスバーで、バーの上にラベルを表示さたいといった場合です。

## スタックで影つき文字を表現する

また、[stack](./stack.md) 要素の便利な用法のひとつとして、 CSS プロパティの多くをエミュレートできるというものがあります。 例えば、以下のようにして、`text-shadow` プロパティに似た効果を作ることができます。

- 例 1
- [ソース](./source/ex_stacks_1.xul)

![ex_stacks_1](./images/ex_stacks_1.png)

```xml
<stack>
<label value="Shadowed" style="padding-left: 1px; padding-top: 1px; font-size: 15px"/>
<label value="Shadowed" style="color: red; font-size: 15px;"/>
</stack>
```

2 つの [label](.label.md) 要素は、両方とも 15 ピクセルのサイズのテキストを作ります。 ただし、最初の要素は、その左端と上端にパディングを加えることによって、右下に 1 ピクセルずらされています。 この結果、2 番目めの要素も、同じ「Shadowed」というテキストを描画しますが、最初のものから少しずれた位置になっています。2 番目の [label](.label.md) 要素は、効果がよくわかるように、赤で描画されています。

この方法は、影の部分のスタイルを、本体とは完全に独立して設定できるため、 `text-shadow` にはない利点を持っています。 具体的には、影に、独自のフォント、下線、サイズを持つことができます (影を点滅させることさえ可能です)。 また、現バージョンの Mozilla では、CSS のテキストの影付きスタイルをサポートしていないのため、この方法のみが使用できます。 この方法の欠点としては、影のために取られた領域がスタックサイズを大きくしてしまうことがあります。 影付けは、無効状態のボタンの外観を作る場合に、非常に役立ちます。

- 例 2
- [ソース](./source/ex_stacks_2.xul)

![ex_stacks_2](./images/ex_stacks_2.png)

```xml
<stack style="background-color: #C0C0C0">
<label value="Disabled" style="color: white; padding-left: 1px; padding-top: 1px;"/>
<label value="Disabled" style="color: grey;"/>
</stack>
```

いくつかのプラットフォームでは、このテキスト配置と影の配色によって、無効の外観が作り出されています。

マウスクリックやキー入力といったイベントは、スタックの一番上にある要素、つまり、スタックに最後に入れられた要素に渡されるということに注意して下さい。 これは、ボタンをスタックに入れる場合、最後に置かれた場合のみ、正しく動作するということを意味しています。

# デッキ

デッキ ([deck](./deck.md)) 要素も、[stack](./stack.md) 要素と同様に、子要素を順に重ねてレイアウトしますが、デッキでは一度に 1 つの子要素しか表示されない点が異なります。 これは、一連の類似したパネルを順番に表示していく、ウィザード型のインターフェイスに使うことができます。 パネルごとに別々のウィンドウを作成し、それぞれにナビゲーションボタンを加えたりする代わりに、 内容が変わる部分にデッキを使用することによって、ウィンドウを 1 つ作るだけで済ますことができます。

スタックと同様に、デッキ内のページは [deck](./deck.md) 要素の直接の子要素から構成されます。 `deck` 要素の中に子要素が 3 つあるとすると、デッキは 3 つの ページをもつことになります。 表示するデッキのページは、`deck` 要素の `selectedIndex` 属性を設定することによって、変更することができます。 このインデックスは、どのページを表示するかを指定する数値で、 ページの番号は、0 から始まります。 そのため、デッキの最初の子要素はページ 0 で、 2 番目はページ 1 といった具合に続いていきます。

以下は、デッキの例です。

- 例 3
- [ソース](./source/ex_stacks_3.xul)

![ex_stacks_3](./images/ex_stacks_3.png)

```xml
<deck selectedIndex="2">
<label value="This is the first page"/>
<button label="This is the second page"/>
<box>
<label value="This is the third page"/>
<button label="This is also the third page"/>
</box>
</deck>
```

この例では、ページが 3 つあり、デフォルトは、3 番目のページです。 3 番目のページは、内部に 2 つの要素をもつボックスです。 そのボックスと内部の要素がページを構成しています。 デッキは最大の子要素と同じ大きさになりますので、ここでは、3 番目のページと同じ大きさになるはずです。

スクリプトを使って `selectedIndex` 属性を変更することにより、ページを切り替えることができます。 これについては、イベントと DOM に関するセクションでもっと詳しく説明します。

# REF

- [XUL-Stacks_and_Decks](https://developer.mozilla.org/en-US/docs/Archive/Mozilla/XUL/Tutorial/Stacks_and_Decks)
Loading

0 comments on commit 304979c

Please sign in to comment.