>:NDEBUG>")
47 | endfunction()
48 |
49 | # Flutter library and tool build rules.
50 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
51 | add_subdirectory(${FLUTTER_MANAGED_DIR})
52 |
53 | # System-level dependencies.
54 | find_package(PkgConfig REQUIRED)
55 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
56 |
57 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
58 |
59 | # Define the application target. To change its name, change BINARY_NAME above,
60 | # not the value here, or `flutter run` will no longer work.
61 | #
62 | # Any new source files that you add to the application should be added here.
63 | add_executable(${BINARY_NAME}
64 | "main.cc"
65 | "my_application.cc"
66 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
67 | )
68 |
69 | # Apply the standard set of build settings. This can be removed for applications
70 | # that need different build settings.
71 | apply_standard_settings(${BINARY_NAME})
72 |
73 | # Add dependency libraries. Add any application-specific dependencies here.
74 | target_link_libraries(${BINARY_NAME} PRIVATE flutter)
75 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
76 |
77 | # Run the Flutter tool portions of the build. This must not be removed.
78 | add_dependencies(${BINARY_NAME} flutter_assemble)
79 |
80 | # Only the install-generated bundle's copy of the executable will launch
81 | # correctly, since the resources must in the right relative locations. To avoid
82 | # people trying to run the unbundled copy, put it in a subdirectory instead of
83 | # the default top-level location.
84 | set_target_properties(${BINARY_NAME}
85 | PROPERTIES
86 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
87 | )
88 |
89 |
90 | # Generated plugin build rules, which manage building the plugins and adding
91 | # them to the application.
92 | include(flutter/generated_plugins.cmake)
93 |
94 |
95 | # === Installation ===
96 | # By default, "installing" just makes a relocatable bundle in the build
97 | # directory.
98 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
99 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
100 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
101 | endif()
102 |
103 | # Start with a clean build bundle directory every time.
104 | install(CODE "
105 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
106 | " COMPONENT Runtime)
107 |
108 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
109 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
110 |
111 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
112 | COMPONENT Runtime)
113 |
114 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
115 | COMPONENT Runtime)
116 |
117 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
118 | COMPONENT Runtime)
119 |
120 | foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
121 | install(FILES "${bundled_library}"
122 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
123 | COMPONENT Runtime)
124 | endforeach(bundled_library)
125 |
126 | # Fully re-copy the assets directory on each build to avoid having stale files
127 | # from a previous install.
128 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
129 | install(CODE "
130 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
131 | " COMPONENT Runtime)
132 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
133 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
134 |
135 | # Install the AOT library on non-Debug builds only.
136 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
137 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
138 | COMPONENT Runtime)
139 | endif()
140 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |
FlutterFolio 📱
5 | Flutter Widget Catalog App for Hacktoberfest
6 |
7 |
8 |
9 |
10 | 
11 | 
12 | 
13 | 
14 | 
15 | 
16 | 
17 | 
18 | 
19 |
20 |
21 |
22 | ---
23 |
24 | ## 🎇 Welcome to FlutterFolio!
25 |
26 | Welcome to FlutterFolio, your go-to catalog app for exploring Flutter widgets. Whether you're a beginner or an experienced Flutter developer, this repository offers a valuable resource to discover and learn about various Flutter widgets. Join our community and embark on your Flutter journey today! 🚀
27 |
28 | ## Key Features
29 |
30 | - **Homepage with Widget Buttons** 📱 - The app's landing page showcases a list of elevated buttons, each representing a different Flutter widget. These buttons make it easy for users to find and select a widget to explore.
31 |
32 | - **Dedicated Widget Detail Pages** 📝 - Each widget has its own dedicated page that displays comprehensive information about the selected widget. The widget detail page provides a clear and concise description of the widget's purpose and usage.
33 |
34 | - **Sample Code Snippets** 💻 - For each widget, the detail page includes sample code snippets that demonstrate how to use the widget in a Flutter app. These code snippets help users understand the practical implementation of the widget.
35 |
36 | - **Intuitive Navigation** 🚶♂️ - The app offers a user-friendly navigation system that allows users to seamlessly transition between the homepage and widget detail pages. Users can return to the homepage from any detail page.
37 |
38 | - **Responsive Design** 📱 - The app is designed to be responsive, ensuring a consistent and pleasant user experience on different screen sizes and orientations.
39 |
40 | ## 📦 Project Structure
41 |
42 | This repository follows a structured approach to building the FlutterFolio app. To contribute, please adhere to this structure:
43 |
44 | ```
45 | - lib/
46 | - screens/
47 | - home_screen.dart
48 | - widget_detail_screen.dart
49 | - models/
50 | - widget_models.dart
51 | - main.dart
52 | - assets/
53 | - images/
54 | - flutter_logo.png
55 | - data/
56 | - widgets_data.dart
57 | - theme
58 | - app_theme.dart
59 | - README.md
60 |
61 | ```
62 |
63 | ## 🧮 How to Contribute
64 |
65 | Contributing to FlutterFolio is easy! Here are the steps to guide you:
66 |
67 | 1. **Fork** the repository.
68 | 2. **Clone** your forked repository to your local machine.
69 | 3. Choose an issue from the [Issues](https://github.com/dscpesu/FlutterFolio/issues) section or create a new one.
70 | 4. Work on the issue, make your changes, and commit them.
71 | 5. Push your changes to your forked repository.
72 | 6. Create a **Pull Request (PR)** in GitHub.
73 |
74 | ## 🤔 New to Open Source?
75 |
76 | If you're new to open source, here are some resources to help you get started:
77 |
78 | - [Watch this video to get started with open source](https://youtu.be/SYtPC9tHYyQ)
79 | - [How to Fork a Repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo)
80 | - [How to Clone a Repo](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request)
81 | - [How to Create a Pull Request](https://opensource.com/article/19/7/create-pull-request-github)
82 | - [Getting Started with Git and GitHub](https://towardsdatascience.com/getting-started-with-git-and-github-6fcd0f2d4ac6)
83 |
84 | ## Project Admin 👨💼
85 |
86 |
94 | ## ✨ Top Contributors
95 |
96 | Thanks to all our wonderful contributors! Contributions of any kind are welcome! 🚀
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | ## ⭐ Give this Project a Star
112 |
113 | If you find this project helpful or learn something from it, consider giving it a star. Your support means a lot to us! :star:
114 |
115 | [](https://github.com/dscpesu/)
116 |
117 | ## 📬 Connect with Us
118 |
119 | If you have any questions or need support, feel free to reach out to us at **dsc@pes.edu**.
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
Happy Contributing! 🚀
130 |
131 |
132 |
133 | (Back to top)
134 |
135 |
136 |
--------------------------------------------------------------------------------
/windows/runner/win32_window.cpp:
--------------------------------------------------------------------------------
1 | #include "win32_window.h"
2 |
3 | #include
4 | #include
5 |
6 | #include "resource.h"
7 |
8 | namespace {
9 |
10 | /// Window attribute that enables dark mode window decorations.
11 | ///
12 | /// Redefined in case the developer's machine has a Windows SDK older than
13 | /// version 10.0.22000.0.
14 | /// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
15 | #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
16 | #define DWMWA_USE_IMMERSIVE_DARK_MODE 20
17 | #endif
18 |
19 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
20 |
21 | /// Registry key for app theme preference.
22 | ///
23 | /// A value of 0 indicates apps should use dark mode. A non-zero or missing
24 | /// value indicates apps should use light mode.
25 | constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
26 | L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
27 | constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
28 |
29 | // The number of Win32Window objects that currently exist.
30 | static int g_active_window_count = 0;
31 |
32 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
33 |
34 | // Scale helper to convert logical scaler values to physical using passed in
35 | // scale factor
36 | int Scale(int source, double scale_factor) {
37 | return static_cast(source * scale_factor);
38 | }
39 |
40 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
41 | // This API is only needed for PerMonitor V1 awareness mode.
42 | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
43 | HMODULE user32_module = LoadLibraryA("User32.dll");
44 | if (!user32_module) {
45 | return;
46 | }
47 | auto enable_non_client_dpi_scaling =
48 | reinterpret_cast(
49 | GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
50 | if (enable_non_client_dpi_scaling != nullptr) {
51 | enable_non_client_dpi_scaling(hwnd);
52 | }
53 | FreeLibrary(user32_module);
54 | }
55 |
56 | } // namespace
57 |
58 | // Manages the Win32Window's window class registration.
59 | class WindowClassRegistrar {
60 | public:
61 | ~WindowClassRegistrar() = default;
62 |
63 | // Returns the singleton registrar instance.
64 | static WindowClassRegistrar* GetInstance() {
65 | if (!instance_) {
66 | instance_ = new WindowClassRegistrar();
67 | }
68 | return instance_;
69 | }
70 |
71 | // Returns the name of the window class, registering the class if it hasn't
72 | // previously been registered.
73 | const wchar_t* GetWindowClass();
74 |
75 | // Unregisters the window class. Should only be called if there are no
76 | // instances of the window.
77 | void UnregisterWindowClass();
78 |
79 | private:
80 | WindowClassRegistrar() = default;
81 |
82 | static WindowClassRegistrar* instance_;
83 |
84 | bool class_registered_ = false;
85 | };
86 |
87 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
88 |
89 | const wchar_t* WindowClassRegistrar::GetWindowClass() {
90 | if (!class_registered_) {
91 | WNDCLASS window_class{};
92 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
93 | window_class.lpszClassName = kWindowClassName;
94 | window_class.style = CS_HREDRAW | CS_VREDRAW;
95 | window_class.cbClsExtra = 0;
96 | window_class.cbWndExtra = 0;
97 | window_class.hInstance = GetModuleHandle(nullptr);
98 | window_class.hIcon =
99 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
100 | window_class.hbrBackground = 0;
101 | window_class.lpszMenuName = nullptr;
102 | window_class.lpfnWndProc = Win32Window::WndProc;
103 | RegisterClass(&window_class);
104 | class_registered_ = true;
105 | }
106 | return kWindowClassName;
107 | }
108 |
109 | void WindowClassRegistrar::UnregisterWindowClass() {
110 | UnregisterClass(kWindowClassName, nullptr);
111 | class_registered_ = false;
112 | }
113 |
114 | Win32Window::Win32Window() {
115 | ++g_active_window_count;
116 | }
117 |
118 | Win32Window::~Win32Window() {
119 | --g_active_window_count;
120 | Destroy();
121 | }
122 |
123 | bool Win32Window::Create(const std::wstring& title,
124 | const Point& origin,
125 | const Size& size) {
126 | Destroy();
127 |
128 | const wchar_t* window_class =
129 | WindowClassRegistrar::GetInstance()->GetWindowClass();
130 |
131 | const POINT target_point = {static_cast(origin.x),
132 | static_cast(origin.y)};
133 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
134 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
135 | double scale_factor = dpi / 96.0;
136 |
137 | HWND window = CreateWindow(
138 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
139 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
140 | Scale(size.width, scale_factor), Scale(size.height, scale_factor),
141 | nullptr, nullptr, GetModuleHandle(nullptr), this);
142 |
143 | if (!window) {
144 | return false;
145 | }
146 |
147 | UpdateTheme(window);
148 |
149 | return OnCreate();
150 | }
151 |
152 | bool Win32Window::Show() {
153 | return ShowWindow(window_handle_, SW_SHOWNORMAL);
154 | }
155 |
156 | // static
157 | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
158 | UINT const message,
159 | WPARAM const wparam,
160 | LPARAM const lparam) noexcept {
161 | if (message == WM_NCCREATE) {
162 | auto window_struct = reinterpret_cast(lparam);
163 | SetWindowLongPtr(window, GWLP_USERDATA,
164 | reinterpret_cast(window_struct->lpCreateParams));
165 |
166 | auto that = static_cast(window_struct->lpCreateParams);
167 | EnableFullDpiSupportIfAvailable(window);
168 | that->window_handle_ = window;
169 | } else if (Win32Window* that = GetThisFromHandle(window)) {
170 | return that->MessageHandler(window, message, wparam, lparam);
171 | }
172 |
173 | return DefWindowProc(window, message, wparam, lparam);
174 | }
175 |
176 | LRESULT
177 | Win32Window::MessageHandler(HWND hwnd,
178 | UINT const message,
179 | WPARAM const wparam,
180 | LPARAM const lparam) noexcept {
181 | switch (message) {
182 | case WM_DESTROY:
183 | window_handle_ = nullptr;
184 | Destroy();
185 | if (quit_on_close_) {
186 | PostQuitMessage(0);
187 | }
188 | return 0;
189 |
190 | case WM_DPICHANGED: {
191 | auto newRectSize = reinterpret_cast(lparam);
192 | LONG newWidth = newRectSize->right - newRectSize->left;
193 | LONG newHeight = newRectSize->bottom - newRectSize->top;
194 |
195 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
196 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
197 |
198 | return 0;
199 | }
200 | case WM_SIZE: {
201 | RECT rect = GetClientArea();
202 | if (child_content_ != nullptr) {
203 | // Size and position the child window.
204 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
205 | rect.bottom - rect.top, TRUE);
206 | }
207 | return 0;
208 | }
209 |
210 | case WM_ACTIVATE:
211 | if (child_content_ != nullptr) {
212 | SetFocus(child_content_);
213 | }
214 | return 0;
215 |
216 | case WM_DWMCOLORIZATIONCOLORCHANGED:
217 | UpdateTheme(hwnd);
218 | return 0;
219 | }
220 |
221 | return DefWindowProc(window_handle_, message, wparam, lparam);
222 | }
223 |
224 | void Win32Window::Destroy() {
225 | OnDestroy();
226 |
227 | if (window_handle_) {
228 | DestroyWindow(window_handle_);
229 | window_handle_ = nullptr;
230 | }
231 | if (g_active_window_count == 0) {
232 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
233 | }
234 | }
235 |
236 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
237 | return reinterpret_cast(
238 | GetWindowLongPtr(window, GWLP_USERDATA));
239 | }
240 |
241 | void Win32Window::SetChildContent(HWND content) {
242 | child_content_ = content;
243 | SetParent(content, window_handle_);
244 | RECT frame = GetClientArea();
245 |
246 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
247 | frame.bottom - frame.top, true);
248 |
249 | SetFocus(child_content_);
250 | }
251 |
252 | RECT Win32Window::GetClientArea() {
253 | RECT frame;
254 | GetClientRect(window_handle_, &frame);
255 | return frame;
256 | }
257 |
258 | HWND Win32Window::GetHandle() {
259 | return window_handle_;
260 | }
261 |
262 | void Win32Window::SetQuitOnClose(bool quit_on_close) {
263 | quit_on_close_ = quit_on_close;
264 | }
265 |
266 | bool Win32Window::OnCreate() {
267 | // No-op; provided for subclasses.
268 | return true;
269 | }
270 |
271 | void Win32Window::OnDestroy() {
272 | // No-op; provided for subclasses.
273 | }
274 |
275 | void Win32Window::UpdateTheme(HWND const window) {
276 | DWORD light_mode;
277 | DWORD light_mode_size = sizeof(light_mode);
278 | LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
279 | kGetPreferredBrightnessRegValue,
280 | RRF_RT_REG_DWORD, nullptr, &light_mode,
281 | &light_mode_size);
282 |
283 | if (result == ERROR_SUCCESS) {
284 | BOOL enable_dark_mode = light_mode == 0;
285 | DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
286 | &enable_dark_mode, sizeof(enable_dark_mode));
287 | }
288 | }
289 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.11.0"
12 | boolean_selector:
13 | dependency: transitive
14 | description:
15 | name: boolean_selector
16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.1.1"
20 | characters:
21 | dependency: transitive
22 | description:
23 | name: characters
24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "1.3.0"
28 | clock:
29 | dependency: transitive
30 | description:
31 | name: clock
32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.1.1"
36 | collection:
37 | dependency: transitive
38 | description:
39 | name: collection
40 | sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.17.2"
44 | crypto:
45 | dependency: transitive
46 | description:
47 | name: crypto
48 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "3.0.3"
52 | cupertino_icons:
53 | dependency: "direct main"
54 | description:
55 | name: cupertino_icons
56 | sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.0.6"
60 | fake_async:
61 | dependency: transitive
62 | description:
63 | name: fake_async
64 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
65 | url: "https://pub.dev"
66 | source: hosted
67 | version: "1.3.1"
68 | ffi:
69 | dependency: transitive
70 | description:
71 | name: ffi
72 | sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
73 | url: "https://pub.dev"
74 | source: hosted
75 | version: "2.1.0"
76 | flutter:
77 | dependency: "direct main"
78 | description: flutter
79 | source: sdk
80 | version: "0.0.0"
81 | flutter_highlight:
82 | dependency: "direct main"
83 | description:
84 | name: flutter_highlight
85 | sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c"
86 | url: "https://pub.dev"
87 | source: hosted
88 | version: "0.7.0"
89 | flutter_lints:
90 | dependency: "direct dev"
91 | description:
92 | name: flutter_lints
93 | sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
94 | url: "https://pub.dev"
95 | source: hosted
96 | version: "2.0.3"
97 | flutter_test:
98 | dependency: "direct dev"
99 | description: flutter
100 | source: sdk
101 | version: "0.0.0"
102 | google_fonts:
103 | dependency: "direct main"
104 | description:
105 | name: google_fonts
106 | sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "6.1.0"
110 | highlight:
111 | dependency: transitive
112 | description:
113 | name: highlight
114 | sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "0.7.0"
118 | http:
119 | dependency: transitive
120 | description:
121 | name: http
122 | sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "1.1.0"
126 | http_parser:
127 | dependency: transitive
128 | description:
129 | name: http_parser
130 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
131 | url: "https://pub.dev"
132 | source: hosted
133 | version: "4.0.2"
134 | lints:
135 | dependency: transitive
136 | description:
137 | name: lints
138 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
139 | url: "https://pub.dev"
140 | source: hosted
141 | version: "2.1.1"
142 | matcher:
143 | dependency: transitive
144 | description:
145 | name: matcher
146 | sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
147 | url: "https://pub.dev"
148 | source: hosted
149 | version: "0.12.16"
150 | material_color_utilities:
151 | dependency: transitive
152 | description:
153 | name: material_color_utilities
154 | sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
155 | url: "https://pub.dev"
156 | source: hosted
157 | version: "0.5.0"
158 | meta:
159 | dependency: transitive
160 | description:
161 | name: meta
162 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
163 | url: "https://pub.dev"
164 | source: hosted
165 | version: "1.9.1"
166 | path:
167 | dependency: transitive
168 | description:
169 | name: path
170 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
171 | url: "https://pub.dev"
172 | source: hosted
173 | version: "1.8.3"
174 | path_provider:
175 | dependency: transitive
176 | description:
177 | name: path_provider
178 | sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
179 | url: "https://pub.dev"
180 | source: hosted
181 | version: "2.1.1"
182 | path_provider_android:
183 | dependency: transitive
184 | description:
185 | name: path_provider_android
186 | sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
187 | url: "https://pub.dev"
188 | source: hosted
189 | version: "2.2.1"
190 | path_provider_foundation:
191 | dependency: transitive
192 | description:
193 | name: path_provider_foundation
194 | sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
195 | url: "https://pub.dev"
196 | source: hosted
197 | version: "2.3.1"
198 | path_provider_linux:
199 | dependency: transitive
200 | description:
201 | name: path_provider_linux
202 | sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
203 | url: "https://pub.dev"
204 | source: hosted
205 | version: "2.2.1"
206 | path_provider_platform_interface:
207 | dependency: transitive
208 | description:
209 | name: path_provider_platform_interface
210 | sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
211 | url: "https://pub.dev"
212 | source: hosted
213 | version: "2.1.1"
214 | path_provider_windows:
215 | dependency: transitive
216 | description:
217 | name: path_provider_windows
218 | sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
219 | url: "https://pub.dev"
220 | source: hosted
221 | version: "2.2.1"
222 | platform:
223 | dependency: transitive
224 | description:
225 | name: platform
226 | sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
227 | url: "https://pub.dev"
228 | source: hosted
229 | version: "3.1.3"
230 | plugin_platform_interface:
231 | dependency: transitive
232 | description:
233 | name: plugin_platform_interface
234 | sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
235 | url: "https://pub.dev"
236 | source: hosted
237 | version: "2.1.6"
238 | sky_engine:
239 | dependency: transitive
240 | description: flutter
241 | source: sdk
242 | version: "0.0.99"
243 | source_span:
244 | dependency: transitive
245 | description:
246 | name: source_span
247 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
248 | url: "https://pub.dev"
249 | source: hosted
250 | version: "1.10.0"
251 | stack_trace:
252 | dependency: transitive
253 | description:
254 | name: stack_trace
255 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
256 | url: "https://pub.dev"
257 | source: hosted
258 | version: "1.11.0"
259 | stream_channel:
260 | dependency: transitive
261 | description:
262 | name: stream_channel
263 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
264 | url: "https://pub.dev"
265 | source: hosted
266 | version: "2.1.1"
267 | string_scanner:
268 | dependency: transitive
269 | description:
270 | name: string_scanner
271 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
272 | url: "https://pub.dev"
273 | source: hosted
274 | version: "1.2.0"
275 | term_glyph:
276 | dependency: transitive
277 | description:
278 | name: term_glyph
279 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
280 | url: "https://pub.dev"
281 | source: hosted
282 | version: "1.2.1"
283 | test_api:
284 | dependency: transitive
285 | description:
286 | name: test_api
287 | sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
288 | url: "https://pub.dev"
289 | source: hosted
290 | version: "0.6.0"
291 | typed_data:
292 | dependency: transitive
293 | description:
294 | name: typed_data
295 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
296 | url: "https://pub.dev"
297 | source: hosted
298 | version: "1.3.2"
299 | vector_math:
300 | dependency: transitive
301 | description:
302 | name: vector_math
303 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
304 | url: "https://pub.dev"
305 | source: hosted
306 | version: "2.1.4"
307 | web:
308 | dependency: transitive
309 | description:
310 | name: web
311 | sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
312 | url: "https://pub.dev"
313 | source: hosted
314 | version: "0.1.4-beta"
315 | win32:
316 | dependency: transitive
317 | description:
318 | name: win32
319 | sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
320 | url: "https://pub.dev"
321 | source: hosted
322 | version: "5.0.9"
323 | xdg_directories:
324 | dependency: transitive
325 | description:
326 | name: xdg_directories
327 | sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
328 | url: "https://pub.dev"
329 | source: hosted
330 | version: "1.0.3"
331 | sdks:
332 | dart: ">=3.1.3 <4.0.0"
333 | flutter: ">=3.7.0"
334 |
--------------------------------------------------------------------------------
/lib/data/widget_data.dart:
--------------------------------------------------------------------------------
1 | // widget_data.dart
2 | import 'package:flutter_folio/models/widget_model.dart';
3 |
4 | List widgetData = [
5 | WidgetModel(
6 | name: 'Row',
7 | description: '''
8 | • A widget that displays its children in a horizontal array.
9 | • To cause a child to expand to fill the available horizontal space, wrap the child in an Expanded widget.
10 | • The Row widget does not scroll.
11 | • If you have a line of widgets and want them to be able to scroll if there is insufficient room, consider using a ListView.
12 | ''',
13 | imagePath: 'assets/images/row/row.png',
14 | outputImage: 'assets/images/row/row_op.png',
15 | codeSnippet: '''
16 | const Row(
17 | children: [
18 | Expanded(
19 | child: Text('Deliver features faster', textAlign: TextAlign.center),
20 | ),
21 | Expanded(
22 | child: Text('Craft beautiful UIs', textAlign: TextAlign.center),
23 | ),
24 | Expanded(
25 | child: FittedBox(
26 | child: FlutterLogo(),
27 | ),
28 | ),
29 | ],
30 | )
31 | ''',
32 | ),
33 | WidgetModel(
34 | name: 'Text',
35 | description: '''The Text widget displays a string of text with single style. The string might break across multiple lines or might all be displayed on the same line depending on the layout constraints.
36 | Here are the attributes of the Text widget :
37 | 1. data or text: The text content to be displayed.
38 | 2. style: Defines text style properties (e.g., fontSize, color).
39 | 3. textAlign: Sets text alignment (e.g., TextAlign.center).
40 | 4. softWrap: Allows text to wrap to the next line.
41 | 5. overflow: Handles overflowing text (e.g., TextOverflow.ellipsis).
42 | ''',
43 | imagePath: 'assets/images/text/text.png',
44 | outputImage: 'assets/images/text/text_op.png',
45 | codeSnippet: '''
46 | class MyHomePage extends StatelessWidget {
47 | @override
48 | Widget build(BuildContext context) {
49 | return Scaffold(
50 | body: Center(
51 | child: Text(
52 | "Helo World",
53 | style: TextStyle(
54 | fontSize: 49,
55 | color: Colors.blue,
56 | fontWeight: FontWeight.bold,
57 | decoration: TextDecoration.underline,
58 | ),
59 | ),
60 | ),
61 | );
62 | }
63 | }
64 | ''',
65 | ),
66 | WidgetModel(
67 | name: 'Image',
68 | description:
69 | 'The Image widget in Flutter is a fundamental component used to display images within an application. It provides a seamless way to incorporate visual content, such as icons, photographs, or graphics, into the user interface.',
70 | imagePath: 'assets/images/image/image.png',
71 | outputImage: 'assets/images/image/image_op.png',
72 | codeSnippet: '''import 'package:flutter/material.dart';
73 | class HomePage extends StatelessWidget {
74 | @override
75 | Widget build(BuildContext context) {
76 | return Scaffold(
77 | body: Center(
78 | child: ClipRRect(
79 | borderRadius: BorderRadius.circular(20),
80 | child: Container(
81 | height: 300,
82 | width: 300,
83 | color: Colors.blue,
84 | child: Image.asset(
85 | 'lib/images/playstation.jpg',
86 | fit: BoxFit.fill,),
87 | ),
88 | ),
89 | ),
90 | );
91 | }
92 | }
93 | '''
94 | ),
95 | WidgetModel(
96 | name: 'AppBar',
97 | description:
98 | 'The AppBar displays the toolbar widgets, leading, title, and actions, above the bottom (if any). The bottom is usually used for a TabBar. If a flexibleSpace widget is specified then it is stacked behind the toolbar and the bottom widget.',
99 | imagePath: 'assets/images/app_bar/app_bar.png',
100 | outputImage: 'assets/images/app_bar/app_bar_op.png',
101 | codeSnippet: '''import 'package:flutter/material.dart';
102 | /// Flutter code sample for [AppBar].
103 | void main() => runApp(const AppBarApp());
104 |
105 | class AppBarApp extends StatelessWidget {
106 | const AppBarApp({super.key});
107 | @override
108 | Widget build(BuildContext context) {
109 | return const MaterialApp(
110 | home: AppBarExample(),
111 | );
112 | }
113 | }
114 |
115 | class AppBarExample extends StatelessWidget {
116 | const AppBarExample({super.key});
117 |
118 | @override
119 | Widget build(BuildContext context) {
120 | return Scaffold(
121 | appBar: AppBar(
122 | title: const Text('AppBar Demo'),
123 | actions: [
124 | IconButton(
125 | icon: const Icon(Icons.add_alert),
126 | tooltip: 'Show Snackbar',
127 | onPressed: () {
128 | ScaffoldMessenger.of(context).showSnackBar(
129 | const SnackBar(content: Text('This is a snackbar')));
130 | },
131 | ),
132 | IconButton(
133 | icon: const Icon(Icons.navigate_next),
134 | tooltip: 'Go to the next page',
135 | onPressed: () {
136 | Navigator.push(context, MaterialPageRoute(
137 | builder: (BuildContext context) {
138 | return Scaffold(
139 | appBar: AppBar(
140 | title: const Text('Next page'),
141 | ),
142 | body: const Center(
143 | child: Text(
144 | 'This is the next page',
145 | style: TextStyle(fontSize: 24),
146 | ),
147 | ),
148 | );
149 | },
150 | ));
151 | },
152 | ),
153 | ],
154 | ),
155 | body: const Center(
156 | child: Text(
157 | 'This is the home page',
158 | style: TextStyle(fontSize: 24),
159 | ),
160 | ),
161 | );
162 | }
163 | }
164 | '''
165 | ),
166 | WidgetModel(
167 | name: 'Scaffold',
168 | description:
169 | 'In Flutter, the Scaffold widget offers a basic layout structure for visual apps. It helps position key elements like the app bar, floating action buttons, and snack bars. Essentially, it streamlines the creation of material design-based applications.',
170 | imagePath: 'assets/images/scaffold/scaffold.png',
171 | outputImage: 'assets/images/scaffold/scaffold_op.png',
172 | codeSnippet: '''import 'package:flutter/material.dart';
173 |
174 | /// Flutter code sample for [Scaffold].
175 |
176 | void main() => runApp(const ScaffoldExampleApp());
177 |
178 | class ScaffoldExampleApp extends StatelessWidget {
179 | const ScaffoldExampleApp({super.key});
180 |
181 | @override
182 | Widget build(BuildContext context) {
183 | return const MaterialApp(
184 | home: ScaffoldExample(),
185 | );
186 | }
187 | }
188 |
189 | class ScaffoldExample extends StatefulWidget {
190 | const ScaffoldExample({super.key});
191 |
192 | @override
193 | State createState() => _ScaffoldExampleState();
194 | }
195 |
196 | class _ScaffoldExampleState extends State {
197 | int _count = 0;
198 |
199 | @override
200 | Widget build(BuildContext context) {
201 | return Scaffold(
202 | appBar: AppBar(
203 | title: const Text('Sample Code'),
204 | ),
205 | body: Center(child: Text('You have pressed the button _count times.')),
206 | floatingActionButton: FloatingActionButton(
207 | onPressed: () => setState(() => _count++),
208 | tooltip: 'Increment Counter',
209 | child: const Icon(Icons.add),
210 | ),
211 | );
212 | }
213 | }
214 | '''
215 | ),
216 | WidgetModel(
217 | name: 'Container',
218 | description:
219 | 'A convenience widget that combines common painting, positioning, and sizing widgets. A container first surrounds the child with padding (inflated by any borders present in the decoration) and then applies additional constraints to the padded extent (incorporating the width and height as constraints, if either is non-null). The container is then surrounded by additional empty space described from the margin.',
220 | imagePath: 'assets/images/container/container.png',
221 | outputImage: 'assets/images/container/container_op.png',
222 | codeSnippet: '''
223 | Center(
224 | child: Container(
225 | margin: const EdgeInsets.all(10.0),
226 | color: Colors.amber[600],
227 | width: 48.0,
228 | height: 48.0,
229 | ),
230 | )'''
231 | ),
232 | WidgetModel(
233 | name: 'ElevatedButton',
234 | description:
235 | 'Use elevated buttons to add dimension to otherwise mostly flat layouts, e.g. in long busy lists of content, or in wide spaces. Avoid using elevated buttons on already-elevated content such as dialogs or cards.',
236 | imagePath: 'assets/images/elevatedButton/elevatedButton.png',
237 | outputImage: 'assets/images/elevatedButton/elevatedButton_op.png',
238 | codeSnippet: '''
239 | import 'package:flutter/material.dart';
240 |
241 | /// Flutter code sample for [ElevatedButton].
242 |
243 | void main() => runApp(const ElevatedButtonExampleApp());
244 |
245 | class ElevatedButtonExampleApp extends StatelessWidget {
246 | const ElevatedButtonExampleApp({super.key});
247 |
248 | @override
249 | Widget build(BuildContext context) {
250 | return MaterialApp(
251 | home: Scaffold(
252 | appBar: AppBar(title: const Text('ElevatedButton Sample')),
253 | body: const ElevatedButtonExample(),
254 | ),
255 | );
256 | }
257 | }
258 |
259 | class ElevatedButtonExample extends StatefulWidget {
260 | const ElevatedButtonExample({super.key});
261 |
262 | @override
263 | State createState() => _ElevatedButtonExampleState();
264 | }
265 |
266 | class _ElevatedButtonExampleState extends State {
267 | @override
268 | Widget build(BuildContext context) {
269 | final ButtonStyle style =
270 | ElevatedButton.styleFrom(textStyle: const TextStyle(fontSize: 20));
271 |
272 | return Center(
273 | child: Column(
274 | mainAxisSize: MainAxisSize.min,
275 | children: [
276 | ElevatedButton(
277 | style: style,
278 | onPressed: null,
279 | child: const Text('Disabled'),
280 | ),
281 | const SizedBox(height: 30),
282 | ElevatedButton(
283 | style: style,
284 | onPressed: () {},
285 | child: const Text('Enabled'),
286 | ),
287 | ],
288 | ),
289 | );
290 | }
291 | }
292 | '''
293 | ),
294 | WidgetModel(
295 | name: 'Icon',
296 | description: '''
297 | The Icon widget in Flutter is used to display a variety of pre-designed icons, making it easy to add visual elements such as arrows, buttons, and symbols to your app's user interface. It offers customization options for size, color, and more.
298 | ''',
299 | imagePath: 'assets/images/icon/icon.jpeg',
300 | outputImage: 'assets/images/icon/icon_op.png',
301 | codeSnippet: '''
302 | const Row(
303 | mainAxisAlignment: MainAxisAlignment.spaceAround,
304 | children: [
305 | Icon(
306 | Icons.favorite,
307 | color: Colors.pink,
308 | size: 24.0,
309 | semanticLabel: 'Text to announce in accessibility modes',
310 | ),
311 | Icon(
312 | Icons.audiotrack,
313 | color: Colors.green,
314 | size: 30.0,
315 | ),
316 | Icon(
317 | Icons.beach_access,
318 | color: Colors.blue,
319 | size: 36.0,
320 | ),
321 | ],
322 | )
323 | ''',
324 | ),
325 | WidgetModel(
326 | name: 'Column',
327 | description:
328 | 'The Column widget does not scroll (and in general it is considered an error to have more children in a Column than will fit in the available room). If you have a line of widgets and want them to be able to scroll if there is insufficient room, consider using a ListView.',
329 | imagePath: 'assets/images/column/column.png',
330 | outputImage: 'assets/images/column/column_op.png',
331 | codeSnippet: '''
332 | const Column(
333 | children: [
334 | Text('Deliver features faster'),
335 | Text('Craft beautiful UIs'),
336 | Expanded(
337 | child: FittedBox(
338 | child: FlutterLogo(),
339 | ),
340 | ),
341 | ],
342 | )'''
343 | ),
344 | WidgetModel(
345 | name: 'InkWell',
346 | description:
347 | 'A rectangular area of a Material that responds to touch. The InkWell widget must have a Material widget as an ancestor. The Material widget is where the ink reactions are actually painted. This matches the Material Design premise wherein the Material is what is actually reacting to touches by spreading ink.',
348 | imagePath: 'assets/images/InkWell/Inkwell.png',
349 | outputImage: 'assets/images/InkWell/Inkwell_output.png',
350 | codeSnippet: '''
351 | class InkWellExampleApp extends StatelessWidget {
352 | const InkWellExampleApp({super.key});
353 |
354 | @override
355 | Widget build(BuildContext context) {
356 | return MaterialApp(
357 | home: Scaffold(
358 | appBar: AppBar(title: const Text('InkWell Sample')),
359 | body: const Center(
360 | child: InkWellExample(),
361 | ),
362 | ),
363 | );
364 | }
365 | }
366 |
367 | class InkWellExample extends StatefulWidget {
368 | const InkWellExample({super.key});
369 |
370 | @override
371 | State createState() => _InkWellExampleState();
372 | }
373 |
374 | class _InkWellExampleState extends State {
375 | double sideLength = 50;
376 |
377 | @override
378 | Widget build(BuildContext context) {
379 | return AnimatedContainer(
380 | height: sideLength,
381 | width: sideLength,
382 | duration: const Duration(seconds: 2),
383 | curve: Curves.easeIn,
384 | child: Material(
385 | color: Colors.yellow,
386 | child: InkWell(
387 | onTap: () {
388 | setState(() {
389 | sideLength == 50 ? sideLength = 100 : sideLength = 50;
390 | });
391 | },
392 | ),
393 | ),
394 | );
395 | }
396 | }
397 | '''
398 | ),
399 |
400 | // Add more widgets here
401 | ];
402 |
--------------------------------------------------------------------------------
/macos/Runner/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
--------------------------------------------------------------------------------