OLD | NEW |
---|---|
(Empty) | |
1 # Views Platform Styling | |
2 | |
3 ## Overview | |
4 | |
5 Views controls may have different appearances on different platforms, so that | |
6 Views UIs can fit better into the platform's native styling. This document | |
7 describes how to build Views UIs that will look good on all platforms with a | |
8 minimum of manual intervention. | |
9 | |
10 UIs looking good happens at two levels: first, the individual controls must look | |
11 and act appropriately for their platform, and second, the overall layout of the | |
12 controls in a dialog or UI surface must match what users of the platform would | |
13 expect. There are differences at both of these layers between desktop platforms, | |
14 and mobile platforms have still more differences. | |
15 | |
16 ## Controls | |
17 | |
18 Individual controls have different looks and behaviors on different platforms. | |
19 If you're adding a new control or a subclass of an existing control, there are | |
20 some best practices you should follow in designing it so that it works well | |
21 everywhere: | |
22 | |
23 ### Use PlatformStyle for stylistic elements | |
24 | |
25 PlatformStyle exposes factory functions that produce different subclasses of | |
26 Border, Background, and so on that are appropriate to the current platform. If | |
27 your class needs a special kind of border or another stylistic element, creating | |
28 it through a factory function in PlatformStyle will make per-platform styling | |
29 for it easier, and will make which parts of the appearance are platform-specific | |
30 more apparent. For example, if you were adding a Foo control that had a special | |
31 FooBackground background, you might add a function to PlatformStyle: | |
32 | |
33 unique_ptr<FooBackground> CreateFooBackground(); | |
34 | |
35 and a default implementation in PlatformStyle. This way, in future a | |
36 platform-specific implementation can go in PlatformStyleBar and change the | |
37 background of that control on platform Bar without changing the implementation | |
38 of the Foo control at all. | |
39 | |
40 ### Use PlatformStyle to add simple behavior switches | |
41 | |
42 When adding platform-specific behavior for an existing control, if possible, it | |
43 is useful to implement the switch using a const boolean exported from | |
44 PlatformStyle, instead of ifdefs inside the control's implementation. For | |
45 example, instead of: | |
46 | |
47 #if defined(OS_BAR) | |
48 void Foo::DoThing() { ... } | |
49 #else | |
50 void Foo::DoThing() { ... } | |
51 #endif | |
52 | |
53 It's better to do this: | |
54 | |
55 Foo::Foo() : does_thing_that_way_(PlatformStyle::kFooDoesThingThatWay) | |
56 | |
57 void Foo::DoThing() { | |
58 if (does_thing_that_way_) | |
59 ... | |
60 else | |
61 ... | |
62 } | |
63 | |
64 This pattern makes it possible to unit-test all the different platform behaviors | |
65 on one platform. | |
66 | |
67 ### Use subclassing to add complex behavior switches | |
sky
2016/05/05 23:27:43
Do you have an example of this? I could see this f
Elly Fong-Jones
2016/05/06 19:23:29
Done.
| |
68 | |
69 If a lot of the behavior of Foo needs to change per-platform, creating | |
70 platform-specific subclasses of Foo and a factory method on Foo that creates the | |
71 appropriate subclass for the platform is easier to read and understand than | |
72 having ifdefs or lots of control flow inside Foo to implement per-platform | |
73 behavior. | |
74 | |
75 ## UI Layout / Controls | |
76 | |
77 TODO(ellyjones): This section needs a bit more thought. | |
78 | |
79 Some platforms have conventions about the ordering of buttons in dialogs, or the | |
80 presence or absence of certain common controls. For example, on Mac, dialogs are | |
81 expected to have their "default" button at the bottom right, and expected not to | |
82 have a "close" button in their top corner if they have a "Cancel"/"Dismiss" | |
83 button in the dialog body. If you can design a layout that follows all | |
84 platforms' conventions simultaneously, that is the lowest-effort route to | |
85 follow, but if not, there are static booleans in PlatformStyle that hold the | |
86 appropriate values for these decisions on the current platform, like: | |
87 | |
88 static const bool PlatformStyle::kDialogsShouldHaveCloseButton; | |
89 | |
90 You can then condition your dialog creation code like this: | |
91 | |
92 if (PlatformStyle::kDialogsShouldHaveCloseButton) | |
93 views::Button* close_button = ...; | |
94 | |
95 TODO(ellyjones): Actually add these variables to PlatformStyle | |
OLD | NEW |