|
2 | 2 | -- screen. Not quite as nice as getting the data from DF directly, but better |
3 | 3 | -- than hand-rolling calculations for each "interesting" button. |
4 | 4 |
|
| 5 | +--[[ |
| 6 | +
|
| 7 | +DF bottom toolbars module |
| 8 | +------------------------- |
| 9 | +
|
| 10 | +This module provides a (black box) reproduction of how DF places its toolbar |
| 11 | +buttons at the bottom of the screen. Several DFHack overlay UI elements are |
| 12 | +placed with respect to (parts of) the toolbars that DF puts at the bottom of the |
| 13 | +screen. |
| 14 | +
|
| 15 | +The three primary toolbars are placed flush left, "centered", and flush right in |
| 16 | +the interface area (which varies based on configured interface percentage and |
| 17 | +the width (in UI tiles) of the DF window itself). |
| 18 | +
|
| 19 | +In narrow interfaces areas (114-130 UI columns) the center toolbar isn't exactly |
| 20 | +centered to avoid overlapping with the left toolbar. Furthermore the center |
| 21 | +toolbar has secondary toolbars that can be opened above it. These secondary |
| 22 | +toolbars are nominally opened directly above the button for the "tool" they |
| 23 | +belong to. If there is not room for a secondary toolbar placed above its |
| 24 | +"opening button", it will be pushed to the left to fit (even when most of the |
| 25 | +width of the toolbar is currently hidden because its advanced options are |
| 26 | +disabled). For example, the following secondary toolbars are "pushed left" when |
| 27 | +the interface area is narrow enough: |
| 28 | +
|
| 29 | +* dig: 114-175 UI columns |
| 30 | +* chop, gather: 114-120 UI columns |
| 31 | +* smooth, 114-151 UI columns |
| 32 | +* traffic, 114-195 UI columns |
| 33 | +
|
| 34 | +This nearly-centering and width-constrained placement can be derived manually |
| 35 | +for specific toolbars, but this often results in using the above-mentioned |
| 36 | +widths as "magic numbers". Instead of internalizing these values, this module |
| 37 | +implicitly derives them based on the static toolbar widths and dynamic interface |
| 38 | +sizes (combined with a few directly observable "padding" widths and a specific |
| 39 | +rounding method used for the center toolbar). |
| 40 | +
|
| 41 | +The module provides the following fields: |
| 42 | +
|
| 43 | +* ``MINIMUM_INTERFACE_RECT`` |
| 44 | +
|
| 45 | + The UI tile dimensions (from ``gui.mkdims_wh``) of the minimum-size DF window: |
| 46 | + 114x46 UI tiles. |
| 47 | +
|
| 48 | +* ``TOOLBAR_HEIGHT`` |
| 49 | +
|
| 50 | + The UI tile height of the primary toolbars at the bottom of the DF window. |
| 51 | +
|
| 52 | +* ``SECONDARY_TOOLBAR_HEIGHT`` |
| 53 | +
|
| 54 | + The UI tile height of the secondary toolbars that are sometimes placed above |
| 55 | + the primary toolbar. |
| 56 | +
|
| 57 | +* ``fort`` |
| 58 | +
|
| 59 | + The static "definitions" of the fortress mode toolbars. Each of |
| 60 | + ``fort.right``, ``fort.center``, and ``fort.left`` has the following fields: |
| 61 | +
|
| 62 | + * ``toolbar.width`` |
| 63 | +
|
| 64 | + The overall width of the DF toolbar. |
| 65 | +
|
| 66 | + * ``toolbar.buttons`` table that can be indexed by "button names" provided by |
| 67 | + this module: |
| 68 | +
|
| 69 | + * ``fort.left.buttons`` has ``citizens``, ``tasks``, ``places``, ``labor``, ``orders``, |
| 70 | + ``nobles``, ``objects``, and ``justice`` buttons |
| 71 | +
|
| 72 | + * ``fort.center.buttons`` has ``dig``, ``chop``, ``gather``, ``smooth``, ``erase``, |
| 73 | + ``build``, ``stockpile``, ``zone``, ``burrow``, ``cart``, ``traffic``, and |
| 74 | + ``mass_designation`` buttons |
| 75 | +
|
| 76 | + * ``fort.right.buttons`` has ``squads``, and ``world`` buttons |
| 77 | +
|
| 78 | + Each button (``toolbar.buttons[name]``) has two fields: |
| 79 | +
|
| 80 | + * ``button.offset`` |
| 81 | +
|
| 82 | + The offset of the button from the left-most column of the toolbar. |
| 83 | +
|
| 84 | + * ``button.width`` |
| 85 | +
|
| 86 | + The width of the button in UI tiles. |
| 87 | +
|
| 88 | + * ``toolbar:frame(interface_rect)`` method |
| 89 | +
|
| 90 | + The ``interface_rect`` parameter must have ``width`` and ``height`` fields, |
| 91 | + and should represent the size of an interface area (e.g., from the |
| 92 | + ``parent_rect`` parameter given to a non-fullscreen overlay's |
| 93 | + ``updateLayout`` method, or directly from ``gui.get_interface_rect()``). |
| 94 | +
|
| 95 | + Returns a Widget-style "frame" table that has fields for the offsets (``l``, |
| 96 | + ``r``, ``t``, ``b``) and size (``w``, ``h``) of the toolbar when it is |
| 97 | + displayed in an interface area of ``interface_rect`` size. |
| 98 | +
|
| 99 | + The interface area left-offset of a specific button can be found by adding a |
| 100 | + toolbar's frame's ``l`` field and the ``offset`` of one of its buttons:: |
| 101 | +
|
| 102 | + local tb = reqscript('internal/df-bottom-toolbars') |
| 103 | + ... |
| 104 | + local right = tb.fort.right |
| 105 | + local squads_offset = right:frame(interface_size) + right.buttons.squads.offset |
| 106 | +
|
| 107 | + The ``center`` definition has an additional field and method: |
| 108 | +
|
| 109 | + * ``fort.center.secondary_toolbars`` |
| 110 | +
|
| 111 | + Provides the definitions of secondary toolbar for several "tools": ``dig``, |
| 112 | + ``chop``, ``gather``, ``smooth``, ``erase``, ``stockpile``, |
| 113 | + ``stockpile_paint``, ``burrow_paint``, ``traffic``, and |
| 114 | + ``mass_designation``. See the complete list of secondary toolbar buttons in |
| 115 | + the module's code. |
| 116 | +
|
| 117 | + The definition of a secondary toolbar uses the same ``width`` & ``buttons`` |
| 118 | + fields as the primary toolbars. |
| 119 | +
|
| 120 | + * ``fort.center:secondary_toolbar_frame(interface_rect, secondary_name)`` |
| 121 | +
|
| 122 | + Provides the frame (like ``toolbar:frame()``) for the specified secondary |
| 123 | + toolbar when displayed in the specified interface size. |
| 124 | +
|
| 125 | + Again, a button's ``offset`` can be combined with its secondary toolbar's |
| 126 | + frame's ``l`` to find the location of a specific button:: |
| 127 | +
|
| 128 | + local tb = reqscript('internal/df-bottom-toolbars') |
| 129 | + ... |
| 130 | + local center = tb.fort.center |
| 131 | + local dig_advanced_offset = center:secondary_toolbar_frame(interface_size, 'dig') |
| 132 | + + center.secondary_toolbars.dig.advanced_toggle.offset |
| 133 | +
|
| 134 | +]] |
| 135 | + |
5 | 136 | --@module = true |
6 | 137 |
|
7 | 138 | TOOLBAR_HEIGHT = 3 |
|
0 commit comments