{"id":13730245,"url":"https://github.com/sudara/melatonin_inspector","last_synced_at":"2025-04-05T01:03:08.192Z","repository":{"id":63729875,"uuid":"358944094","full_name":"sudara/melatonin_inspector","owner":"sudara","description":"A JUCE module that gives you the ability to inspect and visually edit (non-destructively) components in your UI.","archived":false,"fork":false,"pushed_at":"2025-02-19T22:43:09.000Z","size":561,"stargazers_count":176,"open_issues_count":33,"forks_count":22,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-29T00:03:55.099Z","etag":null,"topics":["cplusplus","juce-framework","juce-modules"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sudara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"sudara"}},"created_at":"2021-04-17T17:41:10.000Z","updated_at":"2025-03-27T07:01:13.000Z","dependencies_parsed_at":"2024-01-06T13:08:21.542Z","dependency_job_id":"c35c6a33-f98e-40cb-839b-e1ebe64d47e4","html_url":"https://github.com/sudara/melatonin_inspector","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_inspector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_inspector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_inspector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_inspector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sudara","download_url":"https://codeload.github.com/sudara/melatonin_inspector/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247271514,"owners_count":20911587,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cplusplus","juce-framework","juce-modules"],"created_at":"2024-08-03T02:01:12.146Z","updated_at":"2025-04-05T01:03:08.185Z","avatar_url":"https://github.com/sudara.png","language":"C++","funding_links":["https://github.com/sponsors/sudara"],"categories":["Tooling \u0026 Debugging"],"sub_categories":[],"readme":"![](https://github.com/sudara/melatonin_inspector/actions/workflows/ci.yml/badge.svg)\n\n## Melatonin Component Inspector\n\nA JUCE module that gives you the ability to inspect and visually edit (non-destructively) components in your UI.\n\nIt's inspired by [Figma](https://figma.com) (where I prefer to design UI), web browser web inspectors and Jim Credland's [Component Debugger](https://github.com/jcredland/juce-toys/blob/master/jcf_debug/source/component_debugger.cpp) [juce-toys](https://github.com/jcredland/juce-toys). \n\nA big hearty thanks to [Dmytro Kiro](https://github.com/dikadk) and [Roland Rabien (aka FigBug)](https://github.com/figbug) for contributing some great features!\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213710642-389d4313-5b5a-4656-859e-ea014c859021.jpg\" width=\"500\"/\u003e\n\u003c/p\u003e\n\n\n\u003cp align=\"center\"\u003e\n✨\u003cbr/\u003e\n✨✨\u003cbr/\u003e\n✨✨✨\u003cbr/\u003e\n\u003cb\u003e\u003ci\u003e...the features...\u003c/i\u003e\u003c/b\u003e\u003cbr/\u003e\n✨✨✨\u003cbr/\u003e\n✨✨\u003cbr/\u003e\n✨\u003cbr/\u003e\n\u003c/p\u003e\n\n## Browse and select components visually\n\nPoint n' click to inspect a component, see its size and distance to parent.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213708404-90948d45-6440-455d-bac0-662acf5a1d70.gif\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n\n## Explore the component hierarchy\n\nImmediately gain clarity over parent/child relationships and see what components are currently visible.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213709528-b0f4d3dc-61bb-4e72-aae5-7c414ee5e798.gif\" width=\"400\"/\u003e\n\u003c/p\u003e\n\nFilter components by name. Names are derived from stock components, label/button text, or demangled class names.\n\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213702600-2e479677-8a6e-459b-ba38-1db93be689e3.gif\" width=\"400\"/\u003e\n\u003c/p\u003e\n\n\n## Preview Component\n\nSee what exactly is drawing on a per-component basis, even when the component is hidden. A fixed transparency grid helps you understand which components and images have transparency.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sudara/melatonin_inspector/assets/472/429e4ce6-cc6c-4ca0-ba7c-201272234c6b\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n## Edit component position and spacing\n\nThere's like...4 different ways to do this, visually and numerically...\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213701508-eaf1dfc6-4465-4581-915e-7d788d47e08c.gif\" width=\"600\"/\u003e\n\u003c/p\u003e\n\nWe also display component *padding* if you follow the convention of storing them as the component properties  `paddingLeft`, `paddingTop`, `paddingRight`, `paddingBottom`. See my `PaddedComponent` [base class as an example](https://gist.github.com/sudara/eed6b8bb3b960b4c2156a0883913ea15).\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213940575-0f9fa289-6b00-4899-b07e-9c9ae9e500c9.gif\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n## Inspect and modify component flags and properties\n\nSee the most important component properties at a glance, including look and feels, fonts for labels, etc. Where applicable, flags are editable! \n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213707219-dc8619c1-8800-4267-b3f3-0c9911817a63.jpg\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n\nAny custom properties you've added the component will also show up here and be editable. \n\n![AudioPluginHost - 2023-08-14 01](https://github.com/sudara/melatonin_inspector/assets/472/3c69c652-5468-409b-9e3c-134868f4db9c)\n\n## Nudge components around \n\nVerify new values, get things pixel perfect.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213701074-a48414e8-a86c-4881-a911-392710078ce7.gif\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n## View spacing relative to siblings/neighbors\n\nHold \"alt\" while component is selected. A Figma inspired feature.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://user-images.githubusercontent.com/472/213705531-d9887c7b-15a7-4b78-bab4-6868765d45a5.gif\" width=\"450\"/\u003e\n\u003c/p\u003e\n\n## Display and modify JUCE widget colors\n\nNo, it's not a christmas miracle, but we do [magically](https://github.com/sudara/melatonin_inspector/blob/main/update_juce_colours.rb) display JUCE's friendly `enum ColourIds` names from the stock widgets. \n\nSee what that Slider's `trackColourId` is set to, and hey, go ahead and try out a new theme in real time.\n\n(Just to be clear: The color changes are temporary, no code is edited!)\n\n\n![AudioPluginHost - 2023-08-14 38](https://github.com/sudara/melatonin_inspector/assets/472/09e0fdd7-1e31-4956-8808-781920c64a66)\n\n## Color picker\n\nAccurately pinpoint colors. Click to pick and store one. Toggle between RGBA and HEX values.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sudara/melatonin_inspector/assets/472/9d9d1fe8-b34a-4e1f-a71c-26f0a0ef5169\" width=\"450\"/\u003e\n\u003c/p\u003e\n\n\n## FPS meter\n\nOverlay an FPS meter on your Editor to get an intuitive understanding of your painting performance. Please see the [FAQ](https://github.com/sudara/melatonin_inspector#my-fps-seems-low-is-it-accurate) for details on usage.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sudara/melatonin_inspector/assets/472/06ee7e30-a536-4dc3-a54e-13aba3a2b0c0\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n\n## Display component performance in real time\n\nA life saving feature. \n\nSee time spent exclusively in a component's `paint` method as well as conveniently provide you with a sum with all children.\n\nKeep track of the max. Double click to `repaint` and get fresh timings. See [setup paint timing](#7-optional-setup-component-timing).\n\n![AudioPluginHost - 2023-08-16 57](https://github.com/sudara/melatonin_inspector/assets/472/7b08ea30-ebd1-4900-bb67-02bb8393211b)\n\n## Undo Manager Inspection \n\nSet it up with\n\n```cpp\ninspector-\u003esetUndoManager (\u0026myUndoManager);\n```\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/user-attachments/assets/c8ffd81d-885d-4a31-88d7-0f3cd5ca7a75\"\nwidth=\"400\"/\u003e\n\u003c/p\u003e\n\n## Installing with CMake\n\n### CMake option #1: `FetchContent`\n\nPlace this chunk o love somewhere before your call to `juce_add_plugin` or `juce_add_gui_app`:\n\n```cmake\nInclude (FetchContent)\nFetchContent_Declare (melatonin_inspector\n  GIT_REPOSITORY https://github.com/sudara/melatonin_inspector.git\n  GIT_TAG origin/main\n  SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/melatonin_inspector)\nFetchContent_MakeAvailable (melatonin_inspector)\n```\n\n### CMake option #2 git submodules\n\nIf you are a git submodule aficionado, life is great! Add this submodule to your project:\n```sh\ngit submodule add -b main https://github.com/sudara/melatonin_inspector.git modules/melatonin_inspector\n```\nand then simply call `add_subdirectory` in your CMakeLists.txt. Remember, modules go *before* your main call to `juce_add_plugin` or `juce_add_gui_app` ([this makes life easier in IDEs](https://github.com/juce-framework/JUCE/blob/master/docs/CMake%20API.md#juce_enable_module_source_groups)):\n\n```cmake\nadd_subdirectory (modules/melatonin_inspector)\n```\n\nTo update melatonin_inspector down the road (gasp! maintained dependencies!?):\n```git\ngit submodule update --remote --merge modules/melatonin_inspector\n```\n\n### CMake Step 2: Tell JUCE about the module\n\nWait wait, not so fast! You couldn't get away that easily. \n\n*After* your `juce_add_plugin` call you will need to link your plugin to the module's target, for example:\n\n```\ntarget_link_libraries(\"YourProject\" PRIVATE melatonin_inspector)\n```\n\nNote: you don't have to call `juce_add_module`. That's handled by our CMake.\n\nIf you use Projucer, add the module manually.\n \n## Installing with Projucer\n\nIf you're rolling old school, or just prefer Projucer life, you'll be happy to note that though JUCE doesn't make it easy we've bent over backwards to make sure our icons, etc are included in the module.\n\n### Download the module \n\nYou can still use git to add it as a submodule if you'd like stay up to date with any changes:\n\n```\ngit submodule add -b main https://github.com/sudara/melatonin_inspector.git modules/melatonin_inspector\n```\n\nOr just download it and stick it somewhere.\n\n### Add it to the projucer\n\nJust \"Add a module from a specified folder\" and you're done!\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/sudara/melatonin_inspector/assets/472/010d9bf3-f8dc-4fc1-9039-69ba42ff856c\" width=\"500\"/\u003e\n\u003c/p\u003e\n\n## 2. Add an include to your Plugin Editor\n\nInclude the module header:\n\n```cpp\n#include \"melatonin_inspector/melatonin_inspector.h\"\n```\n\n## 3. Add the inspector as a private member to your Editor\n\nThe easiest way to get started is to pass a reference to the root component of your UI (typically the Editor itself like in this example, but you could also inspect anything that derives from `juce::Component`).\n\n```cpp\nmelatonin::Inspector inspector { *this };\n```\n\nIf you prefer the inspector open in the disabled state by default, you can pass false as the second argument.\n\n```cpp\nmelatonin::Inspector inspector { *this, false };\n```\n\n## 4. Set it visible\n\nWhen the inspector as an editor member, you can use `cmd/ctrl i` to toggle whether the inspector is enabled.\n\n`setVisible` on the member will also pop the window open.\n\nWhat I do is have a GUI toggle that pops open the window and enables inspection:\n\n```cpp\n// open the inspector window\ninspector.setVisible(true); \n\n// enable the inspector\ninspector.toggle(true);\n```\n\n## 5. Optional: Make it smarter \n\nSetting up as above means that the inspector will always be constructed with your editor. Clicking close on the inspector's `DocumentWindow` will just hide it while disabling inspection. \n\nIf you wrap the inspector with `#if DEBUG` this might be fine for you.\n\nHowever, if you'd plan to ship a product that includes the inspector, or otherwise want to lazily construct it to be more efficient, use a `unique_ptr` instead and set the `onClose` callback to reset the pointer.\n\n```c++\n// PluginEditor.h\nstd::unique_ptr\u003cmelatonin::Inspector\u003e inspector;\n\n// in some button on-click logic\n// replace `this` with a reference to your editor if necessary\nif (!inspector)\n{\n    inspector = std::make_unique\u003cmelatonin::Inspector\u003e (*this);\n    inspector-\u003eonClose = [this]() { inspector.reset(); };\n}\n\ninspector-\u003esetVisible (true);\n```\nThanks to @FigBug for this feature.\n\n## 6. Optional: Setup component timing\n\nJust `#include modules/melatonin_inspector/melatonin/helpers/timing.h` and then call the RAII helper ***at the top*** of a component's paint method:\n\n```c++\nvoid paint (juce::Graphics\u0026 g) override\n{\n    melatonin::ComponentTimer timer { this };\n\n    // do all your expensive painting...\n ```\n\nThis simply times the method and stores it in the component's own properties. It will store up to 3 values named `timing1`, `timing2`, `timing3`.\n\nWant automatic timings for every JUCE component, including stock widgets? [Upvote this FR](https://forum.juce.com/t/fr-callback-or-other-mechanism-for-exposing-component-debugging-timing/54481/1).\n\nWant timings for your custom components ***right now***? Do what I do and derive all your components from a `juce::Component` subclass which wraps the `paint` call and adds the helper before `paint` is called. \n\nCheck out [the forum post for detail](https://forum.juce.com/t/fr-callback-or-other-mechanism-for-exposing-component-debugging-timing/54481/11?u=sudara). Or, if you run a JUCE fork, you might prefer [Roland's solution](https://forum.juce.com/t/fr-callback-or-other-mechanism-for-exposing-component-debugging-timing/54481/6?u=sudara).\n\n## FAQ\n\n### Can I use this in a GUI app/standalone?\n\nYup! See the tests folder for an example.\n\n### Can I save my component resizes or edits?\n\nNope! \n\nFor that, one would need a component system relying on data for placement and size vs. code. See [Daniel's Foley GUI Magic](https://github.com/ffAudio/foleys_gui_magic).\n\n### How is the component hierarchy created?\n\nIt traverses components from the root, building a `TreeView`. \n\nIn the special case of `TabbedComponent`, each tab is added as a child. \n\n### My FPS seems low, is it accurate?\n\nIt's a smoothed running average.\n\nIf you see low FPS rates, check the following:\n\n* Are you running *just* your plugin? Make sure other plugin UIs are closed.\n* I optimize the inspector for Debug usage, but it can be tough for complex UIs to hit 60fps in Debug, especially on macOS (see note below). See what happens in Release.\n* You might have legitimately expensive paint calls (esp. in Debug). You can verify this out via [Perfetto](https://github.com/sudara/melatonin_perfetto).\n\nOn recent macOS, a `repaint()` on even small sections of a window (ie, what the FPS meter does) will cause the OS to paint the entire plugin window. You can use `Flash Screen Updates` in Quartz Debug to verify this.  Because of this macOS behavior, the FPS meter will actually trigger full repaints of your UI, so anything expensive (especially in Debug) will slow down what the FPS meter reports.\n\nIf you are using the JUCE flag `JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS`, JUCE will internally manage the rectangles that need to be repainted, with the aim of being more precise/hygenic with what actually gets painted. This might be a good choice if your plugin already frequently repainting parts of the UI. But please don't switch over to that flag just to appease the FPS meter! It needs to be a choice you make depending on your internal testing (without the FPS meter in play).\n\n\nFeel free to ask for other ideas in the [forum thread](https://forum.juce.com/t/melatonin-inspector-a-web-inspector-ish-module-for-juce-components/45672).\n\n### I have a problem / feature request\n\nPlease do submit an Issue or PR on the repository! Or visit the [official thread on the JUCE forum](https://forum.juce.com/t/melatonin-inspector-a-web-inspector-ish-module-for-juce-components/45672).\n\n\n## Contributing\n\nContributions are always welcome! \n\nThe inspector wouldn't be half as awesome without the help of the community.\n\nIf you'd like to contribute, look out for the issues tagged with \"[Good First Issue](https://github.com/sudara/melatonin_inspector/issues?q=is:issue+is:open+label:%22good+first+issue%22)\"\n\nNote that CI tests for compilation and treats errors on both macOS and Windows as errors. \n\n### Assets\n\nAll assets are PNG exported at 2x. \n\nPlease see the CMakelists.txt file for details on how to add icons in a Projucer friendly way. There's a script for it!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudara%2Fmelatonin_inspector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsudara%2Fmelatonin_inspector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudara%2Fmelatonin_inspector/lists"}