1macro_rules! folder_flags {
6 ($($variant:ident, $sdk:ident, $bits:literal, $title:literal, $description:literal;)+) => {
7 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
13 pub enum FolderFlag {
14 $(#[doc = $description] $variant,)+
15 Raw(u32),
17 }
18
19 impl FolderFlag {
20 pub const ALL: &'static [Self] = &[$(Self::$variant,)+];
22
23 pub const fn bits(self) -> u32 {
25 match self {
26 $(Self::$variant => $bits,)+
27 Self::Raw(bits) => bits,
28 }
29 }
30
31 pub const fn name(self) -> Option<&'static str> {
33 match self {
34 $(Self::$variant => Some(stringify!($sdk)),)+
35 Self::Raw(_) => None,
36 }
37 }
38
39 pub const fn title(self) -> Option<&'static str> {
41 match self {
42 $(Self::$variant => Some($title),)+
43 Self::Raw(_) => None,
44 }
45 }
46
47 pub const fn description(self) -> Option<&'static str> {
49 match self {
50 $(Self::$variant => Some($description),)+
51 Self::Raw(_) => None,
52 }
53 }
54 }
55
56 #[cfg(test)]
57 #[test]
58 fn folder_flag_catalog_matches_windows_sdk() {
59 $(assert_eq!(FolderFlag::$variant.bits(), windows::Win32::UI::Shell::$sdk.0 as u32);)+
60 }
61 };
62}
63
64folder_flags! {
65 None, FWF_NONE, 0x00000000, "None", "No special view options";
66 AutoArrange, FWF_AUTOARRANGE, 0x00000001, "Auto Arrange", "Automatically arrange the icons";
67 AbbreviatedNames, FWF_ABBREVIATEDNAMES, 0x00000002, "Abbreviated Names", "Not supported";
68 SnapToGrid, FWF_SNAPTOGRID, 0x00000004, "Snap to grid", "Snap icon positions to grid";
69 OwnerData, FWF_OWNERDATA, 0x00000008, "Owner Data", "Not supported";
70 BestFitWindow, FWF_BESTFITWINDOW, 0x00000010, "Best Fit Window", "Not supported";
71 Desktop, FWF_DESKTOP, 0x00000020, "Desktop", "Use desktop behavior; implies no client edge and no scroll bars";
72 SingleSelect, FWF_SINGLESEL, 0x00000040, "Single Select", "Prevents selection of multiple icons";
73 NoSubfolders, FWF_NOSUBFOLDERS, 0x00000080, "Hide Subfolders", "Don't show subfolders";
74 Transparent, FWF_TRANSPARENT, 0x00000100, "Transparent", "Draw transparently on the desktop";
75 NoClientEdge, FWF_NOCLIENTEDGE, 0x00000200, "No Client Edge", "Not supported";
76 NoScroll, FWF_NOSCROLL, 0x00000400, "No Scroll Bars", "Don't add scroll bars to the desktop view";
77 AlignLeft, FWF_ALIGNLEFT, 0x00000800, "Align Left", "Align the view to the left";
78 NoIcons, FWF_NOICONS, 0x00001000, "Hide Icons", "Don't show icons";
79 ShowSelectionAlways, FWF_SHOWSELALWAYS, 0x00002000, "Always Show Selection", "Deprecated since Windows XP; has no effect";
80 NoVisible, FWF_NOVISIBLE, 0x00004000, "Not Visible", "Not supported";
81 SingleClickActivate, FWF_SINGLECLICKACTIVATE, 0x00008000, "One Click Activate", "Icons open with one click";
82 NoWebView, FWF_NOWEBVIEW, 0x00010000, "No Web View", "Don't display the folder as a web view";
83 HideFileNames, FWF_HIDEFILENAMES, 0x00020000, "Hide Filenames", "Don't show filenames";
84 CheckSelect, FWF_CHECKSELECT, 0x00040000, "Checkbox Select #0", "Rudiment. Check for fun";
85 NoEnumRefresh, FWF_NOENUMREFRESH, 0x00080000, "No Enumeration Refresh", "Keep existing contents without re-enumerating on refresh";
86 NoGrouping, FWF_NOGROUPING, 0x00100000, "No Grouping", "Don't allow grouping in the view";
87 FullRowSelect, FWF_FULLROWSELECT, 0x00200000, "Full Row Select", "Highlight the item and all its sub-items when selected";
88 NoFilters, FWF_NOFILTERS, 0x00400000, "No Filters", "Don't display filters in the view";
89 NoColumnHeader, FWF_NOCOLUMNHEADER, 0x00800000, "No Column Header", "Don't display a column header in any view mode";
90 NoHeaderInAllViews, FWF_NOHEADERINALLVIEWS, 0x01000000, "Header in Details Only", "Show the column header only in details view";
91 ExtendedTiles, FWF_EXTENDEDTILES, 0x02000000, "Extended Tiles", "Extend each tile to the width of the view";
92 TriCheckSelect, FWF_TRICHECKSELECT, 0x04000000, "Checkbox Select #1", "Rudiment. Check for fun";
93 AutoCheckSelect, FWF_AUTOCHECKSELECT, 0x08000000, "Checkbox Select #2", "Rudiment. Check for fun";
94 NoBrowserViewState, FWF_NOBROWSERVIEWSTATE, 0x10000000, "Don't Save View State", "Don't save view state in the browser";
95 SubsetGroups, FWF_SUBSETGROUPS, 0x20000000, "Subset Groups", "Show the displayed item count in each group";
96 UseSearchFolder, FWF_USESEARCHFOLDER, 0x40000000, "Use Search Folder", "Use the search folder for stacking and searching";
97 AllowRtlReading, FWF_ALLOWRTLREADING, 0x80000000, "Allow Right-to-Left Reading", "Use right-to-left reading layout on right-to-left systems";
98}
99
100impl From<FolderFlag> for u32 {
101 fn from(flag: FolderFlag) -> Self {
102 flag.bits()
103 }
104}
105
106impl std::ops::BitOr for FolderFlag {
107 type Output = Self;
108
109 fn bitor(self, other: Self) -> Self {
110 Self::Raw(self.bits() | other.bits())
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::FolderFlag;
117
118 #[test]
119 fn folder_flag_catalog_is_complete_and_unique() {
120 let expected = std::iter::once(0).chain((0..32).map(|shift| 1u32 << shift));
121 assert_eq!(FolderFlag::ALL.len(), 33);
122 let mut names = std::collections::HashSet::new();
123 for (flag, bits) in FolderFlag::ALL.iter().zip(expected) {
124 assert_eq!(flag.bits(), bits);
125 assert!(names.insert(flag.name().unwrap()));
126 assert!(flag.name().unwrap().starts_with("FWF_"));
127 assert!(!flag.title().unwrap().is_empty());
128 assert!(!flag.description().unwrap().is_empty());
129 }
130 }
131
132 #[test]
133 fn folder_flag_raw_and_combined_masks_are_lossless() {
134 let combined =
135 FolderFlag::AutoArrange | FolderFlag::SnapToGrid | FolderFlag::Raw(0x80000000);
136 assert_eq!(u32::from(combined), 0x80000005);
137 assert_eq!(FolderFlag::Raw(u32::MAX).bits(), u32::MAX);
138 assert_eq!(FolderFlag::Raw(0).bits(), 0);
139 assert_eq!(combined.name(), None);
140 assert_eq!(combined.title(), None);
141 assert_eq!(combined.description(), None);
142 }
143}