From 56433308db5715fec88e595601222bb49bf41c76 Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Wed, 3 Oct 2018 20:23:31 -0700 Subject: [PATCH 01/18] Add some RAII wrappers for ImGui calls --- extract_raii.rb | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ imgui_raii.h | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 extract_raii.rb create mode 100644 imgui_raii.h diff --git a/extract_raii.rb b/extract_raii.rb new file mode 100644 index 000000000000..d3a705724a06 --- /dev/null +++ b/extract_raii.rb @@ -0,0 +1,106 @@ +#!/usr/bin/env ruby + +$VERBOSE = 2 + +INDENT = ' ' * 4 + +puts <[\w\s]+\w)\s+(?\w*)\((?[^)]+)\)(?[^;]*);(?.*)$/) do |m| + next unless m[:name].match(/^(Begin|Push|Open|Tree|Column)/) + next unless m[:name].match(/^TreeNode|PushID|Begin$/) + + argnames = m[:args].split(/,\s*/).map do |arg| + arg = arg.split(/\s*=\s*/, 2).first + arg.split(/[ \*]/).last + end + + # Check for obsolete + if m[:name] == 'Begin' && + (argnames == %w{name p_open size_on_first_use bg_alpha_override flags} || + argnames == %w{items_count items_height}) + next + end + + $stderr.puts m.inspect if $-d + + fail "Return value #{m[:type]} is not bool or void" unless %w{bool void}.include?(m[:type]) + + if !$current_match || $current_match[:name] != m[:name] + if $current_match + close_class + puts + end + + $current_match = m + $class_name = case m[:name] + when 'Begin' then 'ImWindow' + else "Im#{m[:name]}" + end + + puts < Date: Wed, 3 Oct 2018 23:34:00 -0700 Subject: [PATCH 02/18] Put RAII header into a more appropriate location --- extract_raii.rb => misc/raii/extract_raii.rb | 0 imgui_raii.h => misc/raii/imgui_raii.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename extract_raii.rb => misc/raii/extract_raii.rb (100%) rename imgui_raii.h => misc/raii/imgui_raii.h (100%) diff --git a/extract_raii.rb b/misc/raii/extract_raii.rb similarity index 100% rename from extract_raii.rb rename to misc/raii/extract_raii.rb diff --git a/imgui_raii.h b/misc/raii/imgui_raii.h similarity index 100% rename from imgui_raii.h rename to misc/raii/imgui_raii.h From fb339a2425ac613e59d8bd24638d2842128d5cbd Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Thu, 4 Oct 2018 21:00:38 -0700 Subject: [PATCH 03/18] ImGui::End() must always be called after Begin() --- misc/raii/extract_raii.rb | 92 ++++++++++++++++++++++----------------- misc/raii/imgui_raii.h | 8 ++-- 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/misc/raii/extract_raii.rb b/misc/raii/extract_raii.rb index d3a705724a06..e4f64d93c826 100644 --- a/misc/raii/extract_raii.rb +++ b/misc/raii/extract_raii.rb @@ -11,29 +11,55 @@ EOT -$current_match = nil -$class_name = nil -$pop_body = nil - -def close_class - pop_body = case $current_match[:name] - when 'Begin' then 'if (IsOpen) ImGui::End();' - when /^Tree/ then 'if (IsOpen) ImGui::TreePop();' - when /^PushID$/ then 'ImGui::PopID();' - else fail "Don't know what pop body to use" - end - - puts "#{INDENT}~#{$class_name}() { #{pop_body} }" - - if $current_match[:type] == 'bool' - puts - puts "#{INDENT}operator bool() { return IsOpen; }" +class WrapperClass + attr_reader :name, :class_name, :state_var + + def initialize(m) + @name = m[:name] + + @state_var = nil + case m[:name] + when 'Begin' + @class_name = 'ImWindow' + @state_var = 'IsExpanded' + else + @class_name = "Im#{m[:name]}" + @state_var = 'IsOpen' if m[:type] == 'bool' + end + + puts <[\w\s]+\w)\s+(?\w*)\((?[^)]+)\)(?[^;]*);(?.*)$/) do |m| next unless m[:name].match(/^(Begin|Push|Open|Tree|Column)/) @@ -55,34 +81,20 @@ def close_class fail "Return value #{m[:type]} is not bool or void" unless %w{bool void}.include?(m[:type]) - if !$current_match || $current_match[:name] != m[:name] - if $current_match - close_class + if !current_class || current_class.name != m[:name] + if current_class + current_class.close puts end - $current_match = m - $class_name = case m[:name] - when 'Begin' then 'ImWindow' - else "Im#{m[:name]}" - end - - puts < Date: Wed, 3 Oct 2018 20:23:31 -0700 Subject: [PATCH 04/18] Add some RAII wrappers for ImGui calls --- extract_raii.rb | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ imgui_raii.h | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 extract_raii.rb create mode 100644 imgui_raii.h diff --git a/extract_raii.rb b/extract_raii.rb new file mode 100644 index 000000000000..d3a705724a06 --- /dev/null +++ b/extract_raii.rb @@ -0,0 +1,106 @@ +#!/usr/bin/env ruby + +$VERBOSE = 2 + +INDENT = ' ' * 4 + +puts <[\w\s]+\w)\s+(?\w*)\((?[^)]+)\)(?[^;]*);(?.*)$/) do |m| + next unless m[:name].match(/^(Begin|Push|Open|Tree|Column)/) + next unless m[:name].match(/^TreeNode|PushID|Begin$/) + + argnames = m[:args].split(/,\s*/).map do |arg| + arg = arg.split(/\s*=\s*/, 2).first + arg.split(/[ \*]/).last + end + + # Check for obsolete + if m[:name] == 'Begin' && + (argnames == %w{name p_open size_on_first_use bg_alpha_override flags} || + argnames == %w{items_count items_height}) + next + end + + $stderr.puts m.inspect if $-d + + fail "Return value #{m[:type]} is not bool or void" unless %w{bool void}.include?(m[:type]) + + if !$current_match || $current_match[:name] != m[:name] + if $current_match + close_class + puts + end + + $current_match = m + $class_name = case m[:name] + when 'Begin' then 'ImWindow' + else "Im#{m[:name]}" + end + + puts < Date: Wed, 3 Oct 2018 23:34:00 -0700 Subject: [PATCH 05/18] Put RAII header into a more appropriate location --- extract_raii.rb => misc/raii/extract_raii.rb | 0 imgui_raii.h => misc/raii/imgui_raii.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename extract_raii.rb => misc/raii/extract_raii.rb (100%) rename imgui_raii.h => misc/raii/imgui_raii.h (100%) diff --git a/extract_raii.rb b/misc/raii/extract_raii.rb similarity index 100% rename from extract_raii.rb rename to misc/raii/extract_raii.rb diff --git a/imgui_raii.h b/misc/raii/imgui_raii.h similarity index 100% rename from imgui_raii.h rename to misc/raii/imgui_raii.h From 4cad3757307853a813605f5dc0aef257af20bd67 Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Thu, 4 Oct 2018 21:00:38 -0700 Subject: [PATCH 06/18] ImGui::End() must always be called after Begin() --- misc/raii/extract_raii.rb | 92 ++++++++++++++++++++++----------------- misc/raii/imgui_raii.h | 8 ++-- 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/misc/raii/extract_raii.rb b/misc/raii/extract_raii.rb index d3a705724a06..e4f64d93c826 100644 --- a/misc/raii/extract_raii.rb +++ b/misc/raii/extract_raii.rb @@ -11,29 +11,55 @@ EOT -$current_match = nil -$class_name = nil -$pop_body = nil - -def close_class - pop_body = case $current_match[:name] - when 'Begin' then 'if (IsOpen) ImGui::End();' - when /^Tree/ then 'if (IsOpen) ImGui::TreePop();' - when /^PushID$/ then 'ImGui::PopID();' - else fail "Don't know what pop body to use" - end - - puts "#{INDENT}~#{$class_name}() { #{pop_body} }" - - if $current_match[:type] == 'bool' - puts - puts "#{INDENT}operator bool() { return IsOpen; }" +class WrapperClass + attr_reader :name, :class_name, :state_var + + def initialize(m) + @name = m[:name] + + @state_var = nil + case m[:name] + when 'Begin' + @class_name = 'ImWindow' + @state_var = 'IsExpanded' + else + @class_name = "Im#{m[:name]}" + @state_var = 'IsOpen' if m[:type] == 'bool' + end + + puts <[\w\s]+\w)\s+(?\w*)\((?[^)]+)\)(?[^;]*);(?.*)$/) do |m| next unless m[:name].match(/^(Begin|Push|Open|Tree|Column)/) @@ -55,34 +81,20 @@ def close_class fail "Return value #{m[:type]} is not bool or void" unless %w{bool void}.include?(m[:type]) - if !$current_match || $current_match[:name] != m[:name] - if $current_match - close_class + if !current_class || current_class.name != m[:name] + if current_class + current_class.close puts end - $current_match = m - $class_name = case m[:name] - when 'Begin' then 'ImWindow' - else "Im#{m[:name]}" - end - - puts < Date: Thu, 18 Oct 2018 14:51:40 -0700 Subject: [PATCH 07/18] Move RAII header into misc/cpp --- misc/{raii => cpp}/extract_raii.rb | 0 misc/{raii => cpp}/imgui_raii.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename misc/{raii => cpp}/extract_raii.rb (100%) rename misc/{raii => cpp}/imgui_raii.h (100%) diff --git a/misc/raii/extract_raii.rb b/misc/cpp/extract_raii.rb similarity index 100% rename from misc/raii/extract_raii.rb rename to misc/cpp/extract_raii.rb diff --git a/misc/raii/imgui_raii.h b/misc/cpp/imgui_raii.h similarity index 100% rename from misc/raii/imgui_raii.h rename to misc/cpp/imgui_raii.h From 3583d6444db6985fb3facb306583356a48df9778 Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Tue, 23 Oct 2018 18:45:59 -0700 Subject: [PATCH 08/18] Use struct over class; all members are public --- misc/cpp/extract_raii.rb | 3 +-- misc/cpp/imgui_raii.h | 18 ++++++------------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_raii.rb index e4f64d93c826..b66cca817c4a 100644 --- a/misc/cpp/extract_raii.rb +++ b/misc/cpp/extract_raii.rb @@ -28,9 +28,8 @@ def initialize(m) end puts < Date: Tue, 23 Oct 2018 18:46:48 -0700 Subject: [PATCH 09/18] Delete the move and copy operators --- misc/cpp/extract_raii.rb | 7 ++++++- misc/cpp/imgui_raii.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_raii.rb index b66cca817c4a..43941132b494 100644 --- a/misc/cpp/extract_raii.rb +++ b/misc/cpp/extract_raii.rb @@ -52,7 +52,12 @@ def close puts "#{INDENT}operator bool() { return #{@state_var}; }" end - puts "};" + puts + puts "#{INDENT}#{@class_name}(#{@class_name} &&) = delete;" + puts "#{INDENT}#{@class_name} &operator=(#{@class_name} &&) = delete;" + puts "#{INDENT}#{@class_name}(const #{@class_name} &) = delete;" + puts "#{INDENT}#{@class_name} &operator=(#{@class_name} &) = delete;" + puts '};' end end diff --git a/misc/cpp/imgui_raii.h b/misc/cpp/imgui_raii.h index 21c8d33345d8..22059fd75d91 100644 --- a/misc/cpp/imgui_raii.h +++ b/misc/cpp/imgui_raii.h @@ -10,6 +10,11 @@ struct ImWindow ~ImWindow() { ImGui::End(); } operator bool() { return IsExpanded; } + + ImWindow(ImWindow &&) = delete; + ImWindow &operator=(ImWindow &&) = delete; + ImWindow(const ImWindow &) = delete; + ImWindow &operator=(ImWindow &) = delete; }; struct ImPushID @@ -19,6 +24,11 @@ struct ImPushID ImPushID(const void* ptr_id) { ImGui::PushID(ptr_id); } ImPushID(int int_id) { ImGui::PushID(int_id); } ~ImPushID() { ImGui::PopID(); } + + ImPushID(ImPushID &&) = delete; + ImPushID &operator=(ImPushID &&) = delete; + ImPushID(const ImPushID &) = delete; + ImPushID &operator=(ImPushID &) = delete; }; struct ImTreeNode @@ -31,6 +41,11 @@ struct ImTreeNode ~ImTreeNode() { if (IsOpen) ImGui::TreePop(); } operator bool() { return IsOpen; } + + ImTreeNode(ImTreeNode &&) = delete; + ImTreeNode &operator=(ImTreeNode &&) = delete; + ImTreeNode(const ImTreeNode &) = delete; + ImTreeNode &operator=(ImTreeNode &) = delete; }; struct ImTreeNodeV @@ -42,6 +57,11 @@ struct ImTreeNodeV ~ImTreeNodeV() { if (IsOpen) ImGui::TreePop(); } operator bool() { return IsOpen; } + + ImTreeNodeV(ImTreeNodeV &&) = delete; + ImTreeNodeV &operator=(ImTreeNodeV &&) = delete; + ImTreeNodeV(const ImTreeNodeV &) = delete; + ImTreeNodeV &operator=(ImTreeNodeV &) = delete; }; struct ImTreeNodeEx @@ -54,6 +74,11 @@ struct ImTreeNodeEx ~ImTreeNodeEx() { if (IsOpen) ImGui::TreePop(); } operator bool() { return IsOpen; } + + ImTreeNodeEx(ImTreeNodeEx &&) = delete; + ImTreeNodeEx &operator=(ImTreeNodeEx &&) = delete; + ImTreeNodeEx(const ImTreeNodeEx &) = delete; + ImTreeNodeEx &operator=(ImTreeNodeEx &) = delete; }; struct ImTreeNodeExV @@ -65,4 +90,9 @@ struct ImTreeNodeExV ~ImTreeNodeExV() { if (IsOpen) ImGui::TreePop(); } operator bool() { return IsOpen; } + + ImTreeNodeExV(ImTreeNodeExV &&) = delete; + ImTreeNodeExV &operator=(ImTreeNodeExV &&) = delete; + ImTreeNodeExV(const ImTreeNodeExV &) = delete; + ImTreeNodeExV &operator=(ImTreeNodeExV &) = delete; }; From 79e1aebfceb50f380a98c63271fd58111433a0f0 Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Thu, 8 Nov 2018 16:26:39 -0800 Subject: [PATCH 10/18] Get rid of duplicate renamed files --- misc/raii/extract_raii.rb | 118 -------------------------------------- misc/raii/imgui_raii.h | 74 ------------------------ 2 files changed, 192 deletions(-) delete mode 100644 misc/raii/extract_raii.rb delete mode 100644 misc/raii/imgui_raii.h diff --git a/misc/raii/extract_raii.rb b/misc/raii/extract_raii.rb deleted file mode 100644 index e4f64d93c826..000000000000 --- a/misc/raii/extract_raii.rb +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env ruby - -$VERBOSE = 2 - -INDENT = ' ' * 4 - -puts <[\w\s]+\w)\s+(?\w*)\((?[^)]+)\)(?[^;]*);(?.*)$/) do |m| - next unless m[:name].match(/^(Begin|Push|Open|Tree|Column)/) - next unless m[:name].match(/^TreeNode|PushID|Begin$/) - - argnames = m[:args].split(/,\s*/).map do |arg| - arg = arg.split(/\s*=\s*/, 2).first - arg.split(/[ \*]/).last - end - - # Check for obsolete - if m[:name] == 'Begin' && - (argnames == %w{name p_open size_on_first_use bg_alpha_override flags} || - argnames == %w{items_count items_height}) - next - end - - $stderr.puts m.inspect if $-d - - fail "Return value #{m[:type]} is not bool or void" unless %w{bool void}.include?(m[:type]) - - if !current_class || current_class.name != m[:name] - if current_class - current_class.close - puts - end - - current_class = WrapperClass.new(m) - end - - attrs = m[:attrs].gsub(/IM_FMT(ARGS|LIST)\(\d+\)/) do |a| - a.sub(/\d+/) { |index| (index.to_i + 1).to_s } - end - - print "#{INDENT}#{current_class.class_name}(#{m[:args]})#{attrs} { " - - use_varargs = false - if argnames.last == '...' - argnames[-1] = 'ap' - use_varargs = true - print "va_list ap; va_start(ap, fmt); " - end - - print "#{current_class.state_var} = " if current_class.state_var - - print "ImGui::#{m[:name]}" - print 'V' if use_varargs - print "(#{argnames.join(', ')}); " - print 'va_end(ap); ' if use_varargs - - puts '}' - end -end - -current_class.close if current_class - diff --git a/misc/raii/imgui_raii.h b/misc/raii/imgui_raii.h deleted file mode 100644 index 55cdb672d663..000000000000 --- a/misc/raii/imgui_raii.h +++ /dev/null @@ -1,74 +0,0 @@ -#include "imgui.h" - -#pragma once - -class ImWindow -{ -public: - bool IsExpanded; - - ImWindow(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0) { IsExpanded = ImGui::Begin(name, p_open, flags); } - ~ImWindow() { ImGui::End(); } - - operator bool() { return IsExpanded; } -}; - -class ImPushID -{ -public: - ImPushID(const char* str_id) { ImGui::PushID(str_id); } - ImPushID(const char* str_id_begin, const char* str_id_end) { ImGui::PushID(str_id_begin, str_id_end); } - ImPushID(const void* ptr_id) { ImGui::PushID(ptr_id); } - ImPushID(int int_id) { ImGui::PushID(int_id); } - ~ImPushID() { ImGui::PopID(); } -}; - -class ImTreeNode -{ -public: - bool IsOpen; - - ImTreeNode(const char* label) { IsOpen = ImGui::TreeNode(label); } - ImTreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(3) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeV(str_id, fmt, ap); va_end(ap); } - ImTreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(3) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeV(ptr_id, fmt, ap); va_end(ap); } - ~ImTreeNode() { if (IsOpen) ImGui::TreePop(); } - - operator bool() { return IsOpen; } -}; - -class ImTreeNodeV -{ -public: - bool IsOpen; - - ImTreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(3) { IsOpen = ImGui::TreeNodeV(str_id, fmt, args); } - ImTreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(3) { IsOpen = ImGui::TreeNodeV(ptr_id, fmt, args); } - ~ImTreeNodeV() { if (IsOpen) ImGui::TreePop(); } - - operator bool() { return IsOpen; } -}; - -class ImTreeNodeEx -{ -public: - bool IsOpen; - - ImTreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0) { IsOpen = ImGui::TreeNodeEx(label, flags); } - ImTreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(4) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeExV(str_id, flags, fmt, ap); va_end(ap); } - ImTreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(4) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, ap); va_end(ap); } - ~ImTreeNodeEx() { if (IsOpen) ImGui::TreePop(); } - - operator bool() { return IsOpen; } -}; - -class ImTreeNodeExV -{ -public: - bool IsOpen; - - ImTreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(4) { IsOpen = ImGui::TreeNodeExV(str_id, flags, fmt, args); } - ImTreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(4) { IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, args); } - ~ImTreeNodeExV() { if (IsOpen) ImGui::TreePop(); } - - operator bool() { return IsOpen; } -}; From f42f3e6310d02ac85bfdc1c70949a2b204041d23 Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Thu, 8 Nov 2018 16:45:47 -0800 Subject: [PATCH 11/18] Wrap RAII helpers in namespace ImScoped --- misc/cpp/extract_raii.rb | 38 ++++---- misc/cpp/imgui_raii.h | 192 ++++++++++++++++++++------------------- 2 files changed, 120 insertions(+), 110 deletions(-) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_raii.rb index 43941132b494..3ec8f0d23caa 100644 --- a/misc/cpp/extract_raii.rb +++ b/misc/cpp/extract_raii.rb @@ -5,10 +5,12 @@ INDENT = ' ' * 4 puts < Date: Thu, 8 Nov 2018 19:10:02 -0800 Subject: [PATCH 12/18] Generate wrappers for remaining Begin/Push/Tree methods --- misc/cpp/extract_raii.rb | 42 ++++-- misc/cpp/imgui_raii.h | 273 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 291 insertions(+), 24 deletions(-) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_raii.rb index 3ec8f0d23caa..13ac982c670b 100644 --- a/misc/cpp/extract_raii.rb +++ b/misc/cpp/extract_raii.rb @@ -19,15 +19,23 @@ class WrapperClass def initialize(m) @name = m[:name] - @state_var = nil - case m[:name] - when 'Begin' - @class_name = 'Window' - @state_var = 'IsContentVisible' - else - @class_name = m[:name] - @state_var = 'IsOpen' if m[:type] == 'bool' - end + @class_name = case @name + when 'Begin' + 'Window' + when /^Begin(.*)$/ + $1 + when /^Push(.*)$/ + $1 + else + m[:name] + end + + @state_var = case @name + when 'Begin', 'BeginChild' + 'IsContentVisible' + else + 'IsOpen' if m[:type] == 'bool' + end puts <[\w\s]+\w)\s+(?\w*)\((?[^)]+)\)(?[^;]*);(?.*)$/) do |m| - next unless m[:name].match(/^(Begin|Push|Open|Tree|Column)/) - next unless m[:name].match(/^TreeNode|PushID|Begin$/) + next unless m[:name].match(/^(Begin|Push|Tree)/) argnames = m[:args].split(/,\s*/).map do |arg| arg = arg.split(/\s*=\s*/, 2).first diff --git a/misc/cpp/imgui_raii.h b/misc/cpp/imgui_raii.h index 207f74563dd3..bfb6c17d9ed1 100644 --- a/misc/cpp/imgui_raii.h +++ b/misc/cpp/imgui_raii.h @@ -19,18 +19,128 @@ namespace ImScoped Window &operator=(Window &) = delete; }; - struct PushID + struct Child { - PushID(const char* str_id) { ImGui::PushID(str_id); } - PushID(const char* str_id_begin, const char* str_id_end) { ImGui::PushID(str_id_begin, str_id_end); } - PushID(const void* ptr_id) { ImGui::PushID(ptr_id); } - PushID(int int_id) { ImGui::PushID(int_id); } - ~PushID() { ImGui::PopID(); } + bool IsContentVisible; + + Child(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(str_id, size, 0); } + Child(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(id, size, 0); } + ~Child() { ImGui::EndChild(); } + + operator bool() { return IsContentVisible; } + + Child(Child &&) = delete; + Child &operator=(Child &&) = delete; + Child(const Child &) = delete; + Child &operator=(Child &) = delete; + }; + + struct Font + { + Font(ImFont* font) { ImGui::PushFont(font); } + ~Font() { ImGui::PopFont(); } + + Font(Font &&) = delete; + Font &operator=(Font &&) = delete; + Font(const Font &) = delete; + Font &operator=(Font &) = delete; + }; + + struct StyleColor + { + StyleColor(ImGuiCol idx, ImU32 col) { ImGui::PushStyleColor(idx, col); } + StyleColor(ImGuiCol idx, const ImVec4& col) { ImGui::PushStyleColor(idx, col); } + ~StyleColor() { ImGui::PopStyleColor(); } + + StyleColor(StyleColor &&) = delete; + StyleColor &operator=(StyleColor &&) = delete; + StyleColor(const StyleColor &) = delete; + StyleColor &operator=(StyleColor &) = delete; + }; + + struct StyleVar + { + StyleVar(ImGuiStyleVar idx, float val) { ImGui::PushStyleVar(idx, val); } + StyleVar(ImGuiStyleVar idx, const ImVec2& val) { ImGui::PushStyleVar(idx, val); } + ~StyleVar() { ImGui::PopStyleVar(); } + + StyleVar(StyleVar &&) = delete; + StyleVar &operator=(StyleVar &&) = delete; + StyleVar(const StyleVar &) = delete; + StyleVar &operator=(StyleVar &) = delete; + }; + + struct ItemWidth + { + ItemWidth(float item_width) { ImGui::PushItemWidth(item_width); } + ~ItemWidth() { ImGui::PopItemWidth(); } + + ItemWidth(ItemWidth &&) = delete; + ItemWidth &operator=(ItemWidth &&) = delete; + ItemWidth(const ItemWidth &) = delete; + ItemWidth &operator=(ItemWidth &) = delete; + }; + + struct TextWrapPos + { + TextWrapPos(float wrap_pos_x = 0.0f) { ImGui::PushTextWrapPos(wrap_pos_x); } + ~TextWrapPos() { ImGui::PopTextWrapPos(); } + + TextWrapPos(TextWrapPos &&) = delete; + TextWrapPos &operator=(TextWrapPos &&) = delete; + TextWrapPos(const TextWrapPos &) = delete; + TextWrapPos &operator=(TextWrapPos &) = delete; + }; + + struct AllowKeyboardFocus + { + AllowKeyboardFocus(bool allow_keyboard_focus) { ImGui::PushAllowKeyboardFocus(allow_keyboard_focus); } + ~AllowKeyboardFocus() { ImGui::PopAllowKeyboardFocus(); } + + AllowKeyboardFocus(AllowKeyboardFocus &&) = delete; + AllowKeyboardFocus &operator=(AllowKeyboardFocus &&) = delete; + AllowKeyboardFocus(const AllowKeyboardFocus &) = delete; + AllowKeyboardFocus &operator=(AllowKeyboardFocus &) = delete; + }; + + struct ButtonRepeat + { + ButtonRepeat(bool repeat) { ImGui::PushButtonRepeat(repeat); } + ~ButtonRepeat() { ImGui::PopButtonRepeat(); } + + ButtonRepeat(ButtonRepeat &&) = delete; + ButtonRepeat &operator=(ButtonRepeat &&) = delete; + ButtonRepeat(const ButtonRepeat &) = delete; + ButtonRepeat &operator=(ButtonRepeat &) = delete; + }; + + struct ID + { + ID(const char* str_id) { ImGui::PushID(str_id); } + ID(const char* str_id_begin, const char* str_id_end) { ImGui::PushID(str_id_begin, str_id_end); } + ID(const void* ptr_id) { ImGui::PushID(ptr_id); } + ID(int int_id) { ImGui::PushID(int_id); } + ~ID() { ImGui::PopID(); } + + ID(ID &&) = delete; + ID &operator=(ID &&) = delete; + ID(const ID &) = delete; + ID &operator=(ID &) = delete; + }; + + struct Combo + { + bool IsOpen; + + Combo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0) { IsOpen = ImGui::BeginCombo(label, preview_value, flags); } + ~Combo() { if (IsOpen) ImGui::EndCombo(); } + + operator bool() { return IsOpen; } - PushID(PushID &&) = delete; - PushID &operator=(PushID &&) = delete; - PushID(const PushID &) = delete; - PushID &operator=(PushID &) = delete; + Combo(Combo &&) = delete; + Combo &operator=(Combo &&) = delete; + Combo(const Combo &) = delete; + Combo &operator=(Combo &) = delete; }; struct TreeNode @@ -99,4 +209,147 @@ namespace ImScoped TreeNodeExV &operator=(TreeNodeExV &) = delete; }; + struct TreePush + { + TreePush(const char* str_id) { ImGui::TreePush(str_id); } + TreePush(const void* ptr_id = NULL) { ImGui::TreePush(ptr_id); } + ~TreePush() { ImGui::TreePop(); } + + TreePush(TreePush &&) = delete; + TreePush &operator=(TreePush &&) = delete; + TreePush(const TreePush &) = delete; + TreePush &operator=(TreePush &) = delete; + }; + + struct Menu + { + bool IsOpen; + + Menu(const char* label, bool enabled = true) { IsOpen = ImGui::BeginMenu(label, enabled); } + ~Menu() { if (IsOpen) ImGui::EndMenu(); } + + operator bool() { return IsOpen; } + + Menu(Menu &&) = delete; + Menu &operator=(Menu &&) = delete; + Menu(const Menu &) = delete; + Menu &operator=(Menu &) = delete; + }; + + struct Popup + { + bool IsOpen; + + Popup(const char* str_id, ImGuiWindowFlags flags = 0) { IsOpen = ImGui::BeginPopup(str_id, flags); } + ~Popup() { if (IsOpen) ImGui::EndPopup(); } + + operator bool() { return IsOpen; } + + Popup(Popup &&) = delete; + Popup &operator=(Popup &&) = delete; + Popup(const Popup &) = delete; + Popup &operator=(Popup &) = delete; + }; + + struct PopupContextItem + { + bool IsOpen; + + PopupContextItem(const char* str_id = NULL, int mouse_button = 1) { IsOpen = ImGui::BeginPopupContextItem(str_id, mouse_button); } + ~PopupContextItem() { if (IsOpen) ImGui::EndPopup(); } + + operator bool() { return IsOpen; } + + PopupContextItem(PopupContextItem &&) = delete; + PopupContextItem &operator=(PopupContextItem &&) = delete; + PopupContextItem(const PopupContextItem &) = delete; + PopupContextItem &operator=(PopupContextItem &) = delete; + }; + + struct PopupContextWindow + { + bool IsOpen; + + PopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true) { IsOpen = ImGui::BeginPopupContextWindow(str_id, mouse_button, also_over_items); } + ~PopupContextWindow() { if (IsOpen) ImGui::EndPopup(); } + + operator bool() { return IsOpen; } + + PopupContextWindow(PopupContextWindow &&) = delete; + PopupContextWindow &operator=(PopupContextWindow &&) = delete; + PopupContextWindow(const PopupContextWindow &) = delete; + PopupContextWindow &operator=(PopupContextWindow &) = delete; + }; + + struct PopupContextVoid + { + bool IsOpen; + + PopupContextVoid(const char* str_id = NULL, int mouse_button = 1) { IsOpen = ImGui::BeginPopupContextVoid(str_id, mouse_button); } + ~PopupContextVoid() { if (IsOpen) ImGui::EndPopup(); } + + operator bool() { return IsOpen; } + + PopupContextVoid(PopupContextVoid &&) = delete; + PopupContextVoid &operator=(PopupContextVoid &&) = delete; + PopupContextVoid(const PopupContextVoid &) = delete; + PopupContextVoid &operator=(PopupContextVoid &) = delete; + }; + + struct PopupModal + { + bool IsOpen; + + PopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0) { IsOpen = ImGui::BeginPopupModal(name, p_open, flags); } + ~PopupModal() { if (IsOpen) ImGui::EndPopup(); } + + operator bool() { return IsOpen; } + + PopupModal(PopupModal &&) = delete; + PopupModal &operator=(PopupModal &&) = delete; + PopupModal(const PopupModal &) = delete; + PopupModal &operator=(PopupModal &) = delete; + }; + + struct DragDropSource + { + bool IsOpen; + + DragDropSource(ImGuiDragDropFlags flags = 0) { IsOpen = ImGui::BeginDragDropSource(flags); } + ~DragDropSource() { if (IsOpen) ImGui::EndDragDropSource(); } + + operator bool() { return IsOpen; } + + DragDropSource(DragDropSource &&) = delete; + DragDropSource &operator=(DragDropSource &&) = delete; + DragDropSource(const DragDropSource &) = delete; + DragDropSource &operator=(DragDropSource &) = delete; + }; + + struct ClipRect + { + ClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { ImGui::PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); } + ~ClipRect() { ImGui::PopClipRect(); } + + ClipRect(ClipRect &&) = delete; + ClipRect &operator=(ClipRect &&) = delete; + ClipRect(const ClipRect &) = delete; + ClipRect &operator=(ClipRect &) = delete; + }; + + struct ChildFrame + { + bool IsOpen; + + ChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0) { IsOpen = ImGui::BeginChildFrame(id, size, flags); } + ~ChildFrame() { ImGui::EndChildFrame(); } + + operator bool() { return IsOpen; } + + ChildFrame(ChildFrame &&) = delete; + ChildFrame &operator=(ChildFrame &&) = delete; + ChildFrame(const ChildFrame &) = delete; + ChildFrame &operator=(ChildFrame &) = delete; + }; + } // namespace ImScoped From f7a2c93fcaf6cf4d35bb53afa0073a8dee36a76e Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Tue, 13 Nov 2018 21:58:16 -0800 Subject: [PATCH 13/18] Use macro to delete copy/move constructors/operators --- misc/cpp/extract_raii.rb | 13 ++-- misc/cpp/imgui_raii.h | 133 ++++++++++----------------------------- 2 files changed, 42 insertions(+), 104 deletions(-) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_raii.rb index 13ac982c670b..431c4c88e6ea 100644 --- a/misc/cpp/extract_raii.rb +++ b/misc/cpp/extract_raii.rb @@ -11,6 +11,12 @@ namespace ImScoped { +#{INDENT}#define IMGUI_DELETE_MOVE_COPY(Base)#{INDENT} \\ +#{INDENT}#{INDENT}Base(Base&&) = delete; /* Move not allowed */ \\ +#{INDENT}#{INDENT}Base &operator=(Base&&) = delete; /* "" */ \\ +#{INDENT}#{INDENT}Base(const Base&) = delete; /* Copy not allowed */ \\ +#{INDENT}#{INDENT}Base& operator=(const Base&) = delete /* "" */ + EOT class WrapperClass @@ -68,10 +74,7 @@ def close end puts - puts "#{INDENT * 2}#{@class_name}(#{@class_name} &&) = delete;" - puts "#{INDENT * 2}#{@class_name} &operator=(#{@class_name} &&) = delete;" - puts "#{INDENT * 2}#{@class_name}(const #{@class_name} &) = delete;" - puts "#{INDENT * 2}#{@class_name} &operator=(#{@class_name} &) = delete;" + puts "#{INDENT * 2}IMGUI_DELETE_MOVE_COPY(#{@class_name});" puts "#{INDENT}};" end end @@ -138,5 +141,7 @@ def close puts < Date: Tue, 13 Nov 2018 21:58:45 -0800 Subject: [PATCH 14/18] Make operator bool() explicit --- misc/cpp/extract_raii.rb | 2 +- misc/cpp/imgui_raii.h | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_raii.rb index 431c4c88e6ea..666f1b070de0 100644 --- a/misc/cpp/extract_raii.rb +++ b/misc/cpp/extract_raii.rb @@ -70,7 +70,7 @@ def close if @state_var puts - puts "#{INDENT * 2}operator bool() { return #{@state_var}; }" + puts "#{INDENT * 2}explicit operator bool() const { return #{@state_var}; }" end puts diff --git a/misc/cpp/imgui_raii.h b/misc/cpp/imgui_raii.h index 89d57bfef19b..42caf63a9803 100644 --- a/misc/cpp/imgui_raii.h +++ b/misc/cpp/imgui_raii.h @@ -17,7 +17,7 @@ namespace ImScoped Window(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::Begin(name, p_open, flags); } ~Window() { ImGui::End(); } - operator bool() { return IsContentVisible; } + explicit operator bool() const { return IsContentVisible; } IMGUI_DELETE_MOVE_COPY(Window); }; @@ -30,7 +30,7 @@ namespace ImScoped Child(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(id, size, 0); } ~Child() { ImGui::EndChild(); } - operator bool() { return IsContentVisible; } + explicit operator bool() const { return IsContentVisible; } IMGUI_DELETE_MOVE_COPY(Child); }; @@ -111,7 +111,7 @@ namespace ImScoped Combo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0) { IsOpen = ImGui::BeginCombo(label, preview_value, flags); } ~Combo() { if (IsOpen) ImGui::EndCombo(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(Combo); }; @@ -125,7 +125,7 @@ namespace ImScoped TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(3) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeV(ptr_id, fmt, ap); va_end(ap); } ~TreeNode() { if (IsOpen) ImGui::TreePop(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(TreeNode); }; @@ -138,7 +138,7 @@ namespace ImScoped TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(3) { IsOpen = ImGui::TreeNodeV(ptr_id, fmt, args); } ~TreeNodeV() { if (IsOpen) ImGui::TreePop(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(TreeNodeV); }; @@ -152,7 +152,7 @@ namespace ImScoped TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(4) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, ap); va_end(ap); } ~TreeNodeEx() { if (IsOpen) ImGui::TreePop(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(TreeNodeEx); }; @@ -165,7 +165,7 @@ namespace ImScoped TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(4) { IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, args); } ~TreeNodeExV() { if (IsOpen) ImGui::TreePop(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(TreeNodeExV); }; @@ -186,7 +186,7 @@ namespace ImScoped Menu(const char* label, bool enabled = true) { IsOpen = ImGui::BeginMenu(label, enabled); } ~Menu() { if (IsOpen) ImGui::EndMenu(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(Menu); }; @@ -198,7 +198,7 @@ namespace ImScoped Popup(const char* str_id, ImGuiWindowFlags flags = 0) { IsOpen = ImGui::BeginPopup(str_id, flags); } ~Popup() { if (IsOpen) ImGui::EndPopup(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(Popup); }; @@ -210,7 +210,7 @@ namespace ImScoped PopupContextItem(const char* str_id = NULL, int mouse_button = 1) { IsOpen = ImGui::BeginPopupContextItem(str_id, mouse_button); } ~PopupContextItem() { if (IsOpen) ImGui::EndPopup(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(PopupContextItem); }; @@ -222,7 +222,7 @@ namespace ImScoped PopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true) { IsOpen = ImGui::BeginPopupContextWindow(str_id, mouse_button, also_over_items); } ~PopupContextWindow() { if (IsOpen) ImGui::EndPopup(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(PopupContextWindow); }; @@ -234,7 +234,7 @@ namespace ImScoped PopupContextVoid(const char* str_id = NULL, int mouse_button = 1) { IsOpen = ImGui::BeginPopupContextVoid(str_id, mouse_button); } ~PopupContextVoid() { if (IsOpen) ImGui::EndPopup(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(PopupContextVoid); }; @@ -246,7 +246,7 @@ namespace ImScoped PopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0) { IsOpen = ImGui::BeginPopupModal(name, p_open, flags); } ~PopupModal() { if (IsOpen) ImGui::EndPopup(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(PopupModal); }; @@ -258,7 +258,7 @@ namespace ImScoped DragDropSource(ImGuiDragDropFlags flags = 0) { IsOpen = ImGui::BeginDragDropSource(flags); } ~DragDropSource() { if (IsOpen) ImGui::EndDragDropSource(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(DragDropSource); }; @@ -278,7 +278,7 @@ namespace ImScoped ChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0) { IsOpen = ImGui::BeginChildFrame(id, size, flags); } ~ChildFrame() { ImGui::EndChildFrame(); } - operator bool() { return IsOpen; } + explicit operator bool() const { return IsOpen; } IMGUI_DELETE_MOVE_COPY(ChildFrame); }; From f61b72728e27ab3821511d8cc1aaa5de927ab5bd Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Wed, 14 Nov 2018 01:51:12 -0800 Subject: [PATCH 15/18] More thoroughly parse arguments and defaults --- misc/cpp/extract_raii.rb | 173 ++++++++++++++++++++++++++++++--------- misc/cpp/imgui_raii.h | 57 +++++++++++-- 2 files changed, 184 insertions(+), 46 deletions(-) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_raii.rb index 666f1b070de0..48a7277c708c 100644 --- a/misc/cpp/extract_raii.rb +++ b/misc/cpp/extract_raii.rb @@ -40,7 +40,7 @@ def initialize(m) when 'Begin', 'BeginChild' 'IsContentVisible' else - 'IsOpen' if m[:type] == 'bool' + 'IsOpen' if m[:type] == %w{bool} end puts <[\w\s]+\w)\s+(?\w*)\((?[^)]+)\)(?[^;]*);(?.*)$/) do |m| - next unless m[:name].match(/^(Begin|Push|Tree)/) + m = parse_method(line) + next unless m - argnames = m[:args].split(/,\s*/).map do |arg| - arg = arg.split(/\s*=\s*/, 2).first - arg.split(/[ \*]/).last - end - - # Check for obsolete - if m[:name] == 'Begin' && - (argnames == %w{name p_open size_on_first_use bg_alpha_override flags} || - argnames == %w{items_count items_height}) - next - end + next unless m[:name].match(/^(Begin|Push|Tree)/) - $stderr.puts m.inspect if $-d + $stderr.puts m.inspect if $-d - fail "Return value #{m[:type]} is not bool or void" unless %w{bool void}.include?(m[:type]) + # Check for obsolete + if m[:name] == 'Begin' && + (m[:argnames] == %w{name p_open size_on_first_use bg_alpha_override flags} || + m[:argnames] == %w{items_count items_height}) + next + end - if !current_class || current_class.name != m[:name] - if current_class - current_class.close - puts - end + fail "Return value #{m[:type]} is not bool or void" unless [%w{bool}, %w{void}].include?(m[:type]) - current_class = WrapperClass.new(m) + if !current_class || current_class.name != m[:name] + if current_class + current_class.close + puts end - attrs = m[:attrs].gsub(/IM_FMT(ARGS|LIST)\(\d+\)/) do |a| - a.sub(/\d+/) { |index| (index.to_i + 1).to_s } + current_class = WrapperClass.new(m) + end + + shift_index = false + attrs = m[:attrs].map do |attr| + case attr + when /^IM_FMT(ARGS|LIST)$/ + shift_index = true + when /^\d+/ + if shift_index + attr = (attr.to_i + 1).to_s + shift_index = false + end end + attr + end.join('') - print "#{INDENT * 2}#{current_class.class_name}(#{m[:args]})#{attrs} { " + args = m[:args].map { |argparts| argparts.join('') }.join(',') + print "#{INDENT * 2}#{current_class.class_name}(#{args})#{attrs} { " - use_varargs = false - if argnames.last == '...' - argnames[-1] = 'ap' - use_varargs = true - print "va_list ap; va_start(ap, fmt); " - end + use_varargs = false + if m[:argnames].last == '...' + m[:argnames][-1] = 'ap' + use_varargs = true + print "va_list ap; va_start(ap, fmt); " + end - print "#{current_class.state_var} = " if current_class.state_var + print "#{current_class.state_var} = " if current_class.state_var - print "ImGui::#{m[:name]}" - print 'V' if use_varargs - print "(#{argnames.join(', ')}); " - print 'va_end(ap); ' if use_varargs + print "ImGui::#{m[:name]}" + print 'V' if use_varargs + print "(#{m[:argnames].join(', ')}); " + print 'va_end(ap); ' if use_varargs - puts '}' - end + puts '}' end current_class.close if current_class diff --git a/misc/cpp/imgui_raii.h b/misc/cpp/imgui_raii.h index 42caf63a9803..4e7eb6ceabbe 100644 --- a/misc/cpp/imgui_raii.h +++ b/misc/cpp/imgui_raii.h @@ -26,8 +26,8 @@ namespace ImScoped { bool IsContentVisible; - Child(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(str_id, size, 0); } - Child(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(id, size, 0); } + Child(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(str_id, size, border, flags); } + Child(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0) { IsContentVisible = ImGui::BeginChild(id, size, border, flags); } ~Child() { ImGui::EndChild(); } explicit operator bool() const { return IsContentVisible; } @@ -93,6 +93,14 @@ namespace ImScoped IMGUI_DELETE_MOVE_COPY(ButtonRepeat); }; + struct Group + { + Group() { ImGui::BeginGroup(); } + ~Group() { if () ImGui::EndGroup(); } + + IMGUI_DELETE_MOVE_COPY(Group); + }; + struct ID { ID(const char* str_id) { ImGui::PushID(str_id); } @@ -170,13 +178,28 @@ namespace ImScoped IMGUI_DELETE_MOVE_COPY(TreeNodeExV); }; - struct TreePush + struct MainMenuBar + { + bool IsOpen; + + MainMenuBar() { IsOpen = ImGui::BeginMainMenuBar(); } + ~MainMenuBar() { if (IsOpen) ImGui::EndMainMenuBar(); } + + explicit operator bool() const { return IsOpen; } + + IMGUI_DELETE_MOVE_COPY(MainMenuBar); + }; + + struct MenuBar { - TreePush(const char* str_id) { ImGui::TreePush(str_id); } - TreePush(const void* ptr_id = NULL) { ImGui::TreePush(ptr_id); } - ~TreePush() { ImGui::TreePop(); } + bool IsOpen; + + MenuBar() { IsOpen = ImGui::BeginMenuBar(); } + ~MenuBar() { if (IsOpen) ImGui::EndMenuBar(); } - IMGUI_DELETE_MOVE_COPY(TreePush); + explicit operator bool() const { return IsOpen; } + + IMGUI_DELETE_MOVE_COPY(MenuBar); }; struct Menu @@ -191,6 +214,14 @@ namespace ImScoped IMGUI_DELETE_MOVE_COPY(Menu); }; + struct Tooltip + { + Tooltip() { ImGui::BeginTooltip(); } + ~Tooltip() { if () ImGui::EndTooltip(); } + + IMGUI_DELETE_MOVE_COPY(Tooltip); + }; + struct Popup { bool IsOpen; @@ -263,6 +294,18 @@ namespace ImScoped IMGUI_DELETE_MOVE_COPY(DragDropSource); }; + struct DragDropTarget + { + bool IsOpen; + + DragDropTarget() { IsOpen = ImGui::BeginDragDropTarget(); } + ~DragDropTarget() { if (IsOpen) ImGui::EndDragDropTarget(); } + + explicit operator bool() const { return IsOpen; } + + IMGUI_DELETE_MOVE_COPY(DragDropTarget); + }; + struct ClipRect { ClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { ImGui::PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); } From e6ff68a3b0b807add9dda5fcd29d503603ec7353 Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Wed, 14 Nov 2018 01:52:23 -0800 Subject: [PATCH 16/18] Rename imgui_raii -> imgui_scoped to match namespace --- misc/cpp/{extract_raii.rb => extract_scoped.rb} | 0 misc/cpp/{imgui_raii.h => imgui_scoped.h} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename misc/cpp/{extract_raii.rb => extract_scoped.rb} (100%) rename misc/cpp/{imgui_raii.h => imgui_scoped.h} (100%) diff --git a/misc/cpp/extract_raii.rb b/misc/cpp/extract_scoped.rb similarity index 100% rename from misc/cpp/extract_raii.rb rename to misc/cpp/extract_scoped.rb diff --git a/misc/cpp/imgui_raii.h b/misc/cpp/imgui_scoped.h similarity index 100% rename from misc/cpp/imgui_raii.h rename to misc/cpp/imgui_scoped.h From 027861074c3e73aaeaec231e38fd3b03eb1dc50c Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Wed, 14 Nov 2018 01:57:55 -0800 Subject: [PATCH 17/18] BeginGroup() and Tooltip don't have return values --- misc/cpp/extract_scoped.rb | 5 ++++- misc/cpp/imgui_scoped.h | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/misc/cpp/extract_scoped.rb b/misc/cpp/extract_scoped.rb index 48a7277c708c..5422036b0218 100644 --- a/misc/cpp/extract_scoped.rb +++ b/misc/cpp/extract_scoped.rb @@ -60,7 +60,10 @@ def close when 'BeginChild' then 'ImGui::EndChild();' when 'BeginChildFrame' then 'ImGui::EndChildFrame();' when /^BeginPopup/ then "if (#{@state_var}) ImGui::EndPopup();" - when /^Begin(.*)/ then "if (#{@state_var}) ImGui::End#{$1}();" + when /^Begin(.*)/ + body = "ImGui::End#{$1}();" + body = "if (#{@state_var}) " + body if @state_var + body when /^TreeNode/ then "if (#{@state_var}) ImGui::TreePop();" when 'TreePush' then 'ImGui::TreePop();' when /^Push(.*)/ then "ImGui::Pop#{$1}();" diff --git a/misc/cpp/imgui_scoped.h b/misc/cpp/imgui_scoped.h index 4e7eb6ceabbe..163fb301d13c 100644 --- a/misc/cpp/imgui_scoped.h +++ b/misc/cpp/imgui_scoped.h @@ -96,7 +96,7 @@ namespace ImScoped struct Group { Group() { ImGui::BeginGroup(); } - ~Group() { if () ImGui::EndGroup(); } + ~Group() { ImGui::EndGroup(); } IMGUI_DELETE_MOVE_COPY(Group); }; @@ -217,7 +217,7 @@ namespace ImScoped struct Tooltip { Tooltip() { ImGui::BeginTooltip(); } - ~Tooltip() { if () ImGui::EndTooltip(); } + ~Tooltip() { ImGui::EndTooltip(); } IMGUI_DELETE_MOVE_COPY(Tooltip); }; From 0a25a49e946c1557b05456c02366773b34996a1d Mon Sep 17 00:00:00 2001 From: Seth Kingsley Date: Sun, 18 Nov 2018 06:36:36 -0800 Subject: [PATCH 18/18] Assert that ImScoped::TreeNodeEx() is called without ImGuyTreeNodeFlags_NoTreePushOnOpen --- misc/cpp/extract_scoped.rb | 12 ++++++++---- misc/cpp/imgui_scoped.h | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/misc/cpp/extract_scoped.rb b/misc/cpp/extract_scoped.rb index 5422036b0218..faea36c58eee 100644 --- a/misc/cpp/extract_scoped.rb +++ b/misc/cpp/extract_scoped.rb @@ -216,18 +216,22 @@ def parse_method(line) end.join('') args = m[:args].map { |argparts| argparts.join('') }.join(',') - print "#{INDENT * 2}#{current_class.class_name}(#{args})#{attrs} { " + print "#{INDENT * 2}#{current_class.class_name}(#{args})#{attrs} {" use_varargs = false if m[:argnames].last == '...' m[:argnames][-1] = 'ap' use_varargs = true - print "va_list ap; va_start(ap, fmt); " + print " va_list ap; va_start(ap, fmt);" end - print "#{current_class.state_var} = " if current_class.state_var + if m[:name] =~ /^TreeNodeEx/ && m[:argnames].include?('flags') + print " IM_ASSERT(!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen));" + end + + print " #{current_class.state_var} =" if current_class.state_var - print "ImGui::#{m[:name]}" + print " ImGui::#{m[:name]}" print 'V' if use_varargs print "(#{m[:argnames].join(', ')}); " print 'va_end(ap); ' if use_varargs diff --git a/misc/cpp/imgui_scoped.h b/misc/cpp/imgui_scoped.h index 163fb301d13c..cd872b187a90 100644 --- a/misc/cpp/imgui_scoped.h +++ b/misc/cpp/imgui_scoped.h @@ -155,9 +155,9 @@ namespace ImScoped { bool IsOpen; - TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0) { IsOpen = ImGui::TreeNodeEx(label, flags); } - TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(4) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeExV(str_id, flags, fmt, ap); va_end(ap); } - TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(4) { va_list ap; va_start(ap, fmt); IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, ap); va_end(ap); } + TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0) { IM_ASSERT(!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)); IsOpen = ImGui::TreeNodeEx(label, flags); } + TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(4) { va_list ap; va_start(ap, fmt); IM_ASSERT(!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)); IsOpen = ImGui::TreeNodeExV(str_id, flags, fmt, ap); va_end(ap); } + TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(4) { va_list ap; va_start(ap, fmt); IM_ASSERT(!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)); IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, ap); va_end(ap); } ~TreeNodeEx() { if (IsOpen) ImGui::TreePop(); } explicit operator bool() const { return IsOpen; } @@ -169,8 +169,8 @@ namespace ImScoped { bool IsOpen; - TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(4) { IsOpen = ImGui::TreeNodeExV(str_id, flags, fmt, args); } - TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(4) { IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, args); } + TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(4) { IM_ASSERT(!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)); IsOpen = ImGui::TreeNodeExV(str_id, flags, fmt, args); } + TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(4) { IM_ASSERT(!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)); IsOpen = ImGui::TreeNodeExV(ptr_id, flags, fmt, args); } ~TreeNodeExV() { if (IsOpen) ImGui::TreePop(); } explicit operator bool() const { return IsOpen; }