From b219d2f522a12d5a787a0eea38906c391c4fb532 Mon Sep 17 00:00:00 2001 From: Adel Atallah <2213999+atallahade@users.noreply.github.com> Date: Fri, 18 Aug 2023 09:22:19 +0200 Subject: [PATCH 01/18] Fix typo in the documentation --- docs/source/documentation/item-callbacks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/documentation/item-callbacks.rst b/docs/source/documentation/item-callbacks.rst index 47ca77426..80eb65f76 100644 --- a/docs/source/documentation/item-callbacks.rst +++ b/docs/source/documentation/item-callbacks.rst @@ -27,7 +27,7 @@ sender: or 0 if trigger by the application. app_data: - argument is used DPG to send information + argument is used by DPG to send information to the callback i.e. the current value of most basic widgets. .. code-block:: python From c53a4c53a2a5e550cf27e1dd3fa8f78dceb8331a Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Sun, 6 Aug 2023 01:23:34 +0500 Subject: [PATCH 02/18] fix (mvFileDialog): Need an INCREF on cancel_callback #2148 --- src/mvFileDialog.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mvFileDialog.cpp b/src/mvFileDialog.cpp index f8ea6f522..7eef5a3c1 100644 --- a/src/mvFileDialog.cpp +++ b/src/mvFileDialog.cpp @@ -187,7 +187,18 @@ void mvFileDialog::handleSpecificKeywordArgs(PyObject* dict) _max_size = { (float)max_size[0], (float)max_size[1] }; } - if (PyObject* item = PyDict_GetItemString(dict, "cancel_callback")) _cancelCallback = item; + if (PyObject* item = PyDict_GetItemString(dict, "cancel_callback")) + { + Py_XDECREF(_cancelCallback); + + if (item == Py_None) + _cancelCallback = nullptr; + else + { + Py_XINCREF(item); + _cancelCallback = item; + } + } } From 0c188e700c4d514ed67678ec933ddaa77ced4d78 Mon Sep 17 00:00:00 2001 From: Adel Atallah <2213999+atallahade@users.noreply.github.com> Date: Sat, 19 Aug 2023 20:33:01 +0100 Subject: [PATCH 03/18] Fix typo in the menu bar documentation --- docs/source/documentation/menus.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/documentation/menus.rst b/docs/source/documentation/menus.rst index cd0e905b6..4275280db 100644 --- a/docs/source/documentation/menus.rst +++ b/docs/source/documentation/menus.rst @@ -1,7 +1,7 @@ Menu Bar ======== -DPG contains to two types of Menu Bars +DPG contains two types of Menu Bars Viewport Menu Bar Attached to the viewport From 3ce32db5bdaa7c1b9f202ffdf7fe0e2505b7810f Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Wed, 12 Jul 2023 13:43:13 +0500 Subject: [PATCH 04/18] fix (mvMenu): ScopedID breaks menu hovering and should not be used (#2131) --- src/mvContainers.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mvContainers.cpp b/src/mvContainers.cpp index 5a8d0d571..edcd96a43 100644 --- a/src/mvContainers.cpp +++ b/src/mvContainers.cpp @@ -629,8 +629,6 @@ DearPyGui::draw_menu(ImDrawList* drawlist, mvAppItem& item, mvMenuConfig& config // draw //----------------------------------------------------------------------------- { - ScopedID id(item.uuid); - // create menu and see if its selected if (ImGui::BeginMenu(item.info.internalLabel.c_str(), item.config.enabled)) { From e8bab91020d02a997ce35a652375225ac1726e9e Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Thu, 6 Jul 2023 13:03:22 +0500 Subject: [PATCH 05/18] feat (mvSeparator): Ability to hide separators --- src/mvBasicWidgets.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mvBasicWidgets.cpp b/src/mvBasicWidgets.cpp index 2fb18c09f..9b120ae24 100644 --- a/src/mvBasicWidgets.cpp +++ b/src/mvBasicWidgets.cpp @@ -6302,6 +6302,8 @@ DearPyGui::draw_filter_set(ImDrawList* drawlist, mvAppItem& item, mvFilterSetCon void DearPyGui::draw_separator(ImDrawList* drawlist, mvAppItem& item) { + if (!item.config.show) + return; ImGui::Separator(); } From 1fe2f6c34037ed529c987b9fc4d13e2ac757508b Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Wed, 30 Aug 2023 06:21:59 +0500 Subject: [PATCH 06/18] feat (mvFont): added ImGui's PixelSnapH to font parameters --- dearpygui/dearpygui.py | 10 ++++++---- src/mvAppItem.cpp | 1 + src/mvFontItems.cpp | 13 ++++++++++++- src/mvFontItems.h | 2 ++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/dearpygui/dearpygui.py b/dearpygui/dearpygui.py index 0429e2d37..a04e0e049 100644 --- a/dearpygui/dearpygui.py +++ b/dearpygui/dearpygui.py @@ -1850,12 +1850,13 @@ def filter_set(*, label: str =None, user_data: Any =None, use_internal_label: bo internal_dpg.pop_container_stack() @contextmanager -def font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, **kwargs) -> Union[int, str]: +def font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, pixel_snapH: bool =False, **kwargs) -> Union[int, str]: """ Adds font to a font registry. Args: file (str): size (int): + pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). label (str, optional): Overrides 'name' as label. user_data (Any, optional): User data for callbacks use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). @@ -1875,7 +1876,7 @@ def font(file : str, size : int, *, label: str =None, user_data: Any =None, use_ if 'default_font' in kwargs.keys(): warnings.warn('default_font keyword removed', DeprecationWarning, 2) kwargs.pop('default_font', None) - widget = internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, **kwargs) + widget = internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, pixel_snapH=pixel_snapH, **kwargs) internal_dpg.push_container_stack(widget) yield widget finally: @@ -4308,12 +4309,13 @@ def add_float_vect_value(*, label: str =None, user_data: Any =None, use_internal return internal_dpg.add_float_vect_value(label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, source=source, default_value=default_value, parent=parent, **kwargs) -def add_font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, **kwargs) -> Union[int, str]: +def add_font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, pixel_snapH: bool =False, **kwargs) -> Union[int, str]: """ Adds font to a font registry. Args: file (str): size (int): + pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). label (str, optional): Overrides 'name' as label. user_data (Any, optional): User data for callbacks use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). @@ -4335,7 +4337,7 @@ def add_font(file : str, size : int, *, label: str =None, user_data: Any =None, kwargs.pop('default_font', None) - return internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, **kwargs) + return internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, pixel_snapH=pixel_snapH, **kwargs) def add_font_chars(chars : Union[List[int], Tuple[int, ...]], *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =0, **kwargs) -> Union[int, str]: """ Adds specific font characters to a font. diff --git a/src/mvAppItem.cpp b/src/mvAppItem.cpp index dc262c44a..180ed9f6c 100644 --- a/src/mvAppItem.cpp +++ b/src/mvAppItem.cpp @@ -4831,6 +4831,7 @@ DearPyGui::GetEntityParser(mvAppItemType type) args.push_back({ mvPyDataType::String, "file" }); args.push_back({ mvPyDataType::Integer, "size" }); + args.push_back({ mvPyDataType::Bool, "pixel_snapH", mvArgType::KEYWORD_ARG, "False", "Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring)." }); args.push_back({ mvPyDataType::UUID, "parent", mvArgType::KEYWORD_ARG, "internal_dpg.mvReservedUUID_0", "Parent to add this item to. (runtime adding)" }); args.push_back({ mvPyDataType::Bool, "default_font", mvArgType::DEPRECATED_REMOVE_KEYWORD_ARG }); diff --git a/src/mvFontItems.cpp b/src/mvFontItems.cpp index eb4c2875e..3b3a270c5 100644 --- a/src/mvFontItems.cpp +++ b/src/mvFontItems.cpp @@ -50,8 +50,10 @@ void mvFont::customAction(void* data) ImGuiIO& io = ImGui::GetIO(); + ImFontConfig cfg; + cfg.PixelSnapH = _pixel_snap_h; _fontPtr = io.Fonts->AddFontFromFileTTF(_file.c_str(), _size, - nullptr, _ranges.Data); + &cfg, _ranges.Data); if (_fontPtr == nullptr) { @@ -178,6 +180,14 @@ void mvFont::handleSpecificRequiredArgs(PyObject* dict) } +void mvFont::handleSpecificKeywordArgs(PyObject* dict) +{ + if (dict == nullptr) + return; + + if (PyObject* item = PyDict_GetItemString(dict, "pixel_snapH")) _pixel_snap_h = ToBool(item); +} + void mvFont::getSpecificConfiguration(PyObject* dict) { if (dict == nullptr) @@ -185,6 +195,7 @@ void mvFont::getSpecificConfiguration(PyObject* dict) PyDict_SetItemString(dict, "file", ToPyString(_file)); PyDict_SetItemString(dict, "size", ToPyFloat(_size)); + PyDict_SetItemString(dict, "pixel_snapH", ToPyBool(_pixel_snap_h)); } void mvFontChars::handleSpecificRequiredArgs(PyObject* dict) diff --git a/src/mvFontItems.h b/src/mvFontItems.h index 8cd6c5eae..30223a50a 100644 --- a/src/mvFontItems.h +++ b/src/mvFontItems.h @@ -51,6 +51,7 @@ class mvFont : public mvAppItem void draw(ImDrawList* drawlist, float x, float y) override; void customAction(void* data = nullptr) override; void handleSpecificRequiredArgs(PyObject* dict) override; + void handleSpecificKeywordArgs(PyObject* dict) override; void getSpecificConfiguration(PyObject* dict) override; ImFont* getFontPtr() { return _fontPtr; } @@ -60,6 +61,7 @@ class mvFont : public mvAppItem std::string _file; float _size = 13.0f; bool _default = false; + bool _pixel_snap_h = false; // finalized ImFont* _fontPtr = nullptr; From 31d844daceaa3f78c76a63b1cdd4572016de84cb Mon Sep 17 00:00:00 2001 From: Jonathan Hoffstadt Date: Tue, 12 Sep 2023 20:20:14 -0500 Subject: [PATCH 07/18] chore: up version to 1.10 --- dearpygui/_dearpygui.pyi | 6 +++--- dearpygui/_dearpygui_RTD.py | 8 ++++++++ dearpygui/dearpygui.py | 19 +++++++++---------- setup.py | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/dearpygui/_dearpygui.pyi b/dearpygui/_dearpygui.pyi index f10ed2de2..33ac513ba 100644 --- a/dearpygui/_dearpygui.pyi +++ b/dearpygui/_dearpygui.pyi @@ -46,7 +46,7 @@ def add_checkbox(*, label: str ='', user_data: Any ='', use_internal_label: bool """Adds a checkbox.""" ... -def add_child_window(*, label: str ='', user_data: Any ='', use_internal_label: bool ='', tag: Union[int, str] ='', width: int ='', height: int ='', indent: int ='', parent: Union[int, str] ='', before: Union[int, str] ='', payload_type: str ='', drop_callback: Callable ='', show: bool ='', pos: Union[List[int], Tuple[int, ...]] ='', filter_key: str ='', delay_search: bool ='', tracked: bool ='', track_offset: float ='', border: bool ='', autosize_x: bool ='', autosize_y: bool ='', no_scrollbar: bool ='', horizontal_scrollbar: bool ='', menubar: bool ='') -> Union[int, str]: +def add_child_window(*, label: str ='', user_data: Any ='', use_internal_label: bool ='', tag: Union[int, str] ='', width: int ='', height: int ='', indent: int ='', parent: Union[int, str] ='', before: Union[int, str] ='', payload_type: str ='', drop_callback: Callable ='', show: bool ='', pos: Union[List[int], Tuple[int, ...]] ='', filter_key: str ='', delay_search: bool ='', tracked: bool ='', track_offset: float ='', border: bool ='', autosize_x: bool ='', autosize_y: bool ='', no_scrollbar: bool ='', horizontal_scrollbar: bool ='', menubar: bool ='', no_scroll_with_mouse: bool ='') -> Union[int, str]: """Adds an embedded child window. Will show scrollbars when items do not fit.""" ... @@ -194,7 +194,7 @@ def add_float_vect_value(*, label: str ='', user_data: Any ='', use_internal_lab """Adds a float vect value.""" ... -def add_font(file : str, size : int, *, label: str ='', user_data: Any ='', use_internal_label: bool ='', tag: Union[int, str] ='', parent: Union[int, str] ='') -> Union[int, str]: +def add_font(file : str, size : int, *, label: str ='', user_data: Any ='', use_internal_label: bool ='', tag: Union[int, str] ='', pixel_snapH: bool ='', parent: Union[int, str] ='') -> Union[int, str]: """Adds font to a font registry.""" ... @@ -590,7 +590,7 @@ def add_time_picker(*, label: str ='', user_data: Any ='', use_internal_label: b """Adds a time picker.""" ... -def add_tooltip(parent : Union[int, str], *, label: str ='', user_data: Any ='', use_internal_label: bool ='', tag: Union[int, str] ='', show: bool ='') -> Union[int, str]: +def add_tooltip(parent : Union[int, str], *, label: str ='', user_data: Any ='', use_internal_label: bool ='', tag: Union[int, str] ='', show: bool ='', delay: float ='', hide_on_activity: bool ='') -> Union[int, str]: """Adds a tooltip window.""" ... diff --git a/dearpygui/_dearpygui_RTD.py b/dearpygui/_dearpygui_RTD.py index 89cd49afc..5205096b2 100644 --- a/dearpygui/_dearpygui_RTD.py +++ b/dearpygui/_dearpygui_RTD.py @@ -1512,6 +1512,7 @@ def child_window(**kwargs): no_scrollbar (bool, optional): Disable scrollbars (window can still scroll with mouse or programmatically). horizontal_scrollbar (bool, optional): Allow horizontal scrollbar to appear (off by default). menubar (bool, optional): Shows/Hides the menubar at the top. + no_scroll_with_mouse (bool, optional): Disable user vertically scrolling with mouse wheel. id (Union[int, str], optional): (deprecated) Yields: Union[int, str] @@ -1814,6 +1815,7 @@ def font(file, size, **kwargs): user_data (Any, optional): User data for callbacks use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). tag (Union[int, str], optional): Unique id used to programmatically refer to the item.If label is unused this will be the label. + pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). parent (Union[int, str], optional): Parent to add this item to. (runtime adding) id (Union[int, str], optional): (deprecated) default_font (bool, optional): (deprecated) @@ -2507,6 +2509,8 @@ def tooltip(parent, **kwargs): use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). tag (Union[int, str], optional): Unique id used to programmatically refer to the item.If label is unused this will be the label. show (bool, optional): Attempt to render widget. + delay (float, optional): Activation delay: time, in seconds, during which the mouse should stay still in order to display the tooltip. May be zero for instant activation. + hide_on_activity (bool, optional): Hide the tooltip if the user has moved the mouse. If False, the tooltip will follow mouse pointer. id (Union[int, str], optional): (deprecated) Yields: Union[int, str] @@ -2955,6 +2959,7 @@ def add_child_window(**kwargs): no_scrollbar (bool, optional): Disable scrollbars (window can still scroll with mouse or programmatically). horizontal_scrollbar (bool, optional): Allow horizontal scrollbar to appear (off by default). menubar (bool, optional): Shows/Hides the menubar at the top. + no_scroll_with_mouse (bool, optional): Disable user vertically scrolling with mouse wheel. id (Union[int, str], optional): (deprecated) Returns: Union[int, str] @@ -3949,6 +3954,7 @@ def add_font(file, size, **kwargs): user_data (Any, optional): User data for callbacks use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). tag (Union[int, str], optional): Unique id used to programmatically refer to the item.If label is unused this will be the label. + pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). parent (Union[int, str], optional): Parent to add this item to. (runtime adding) id (Union[int, str], optional): (deprecated) default_font (bool, optional): (deprecated) @@ -6462,6 +6468,8 @@ def add_tooltip(parent, **kwargs): use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). tag (Union[int, str], optional): Unique id used to programmatically refer to the item.If label is unused this will be the label. show (bool, optional): Attempt to render widget. + delay (float, optional): Activation delay: time, in seconds, during which the mouse should stay still in order to display the tooltip. May be zero for instant activation. + hide_on_activity (bool, optional): Hide the tooltip if the user has moved the mouse. If False, the tooltip will follow mouse pointer. id (Union[int, str], optional): (deprecated) Returns: Union[int, str] diff --git a/dearpygui/dearpygui.py b/dearpygui/dearpygui.py index a04e0e049..159aeec6b 100644 --- a/dearpygui/dearpygui.py +++ b/dearpygui/dearpygui.py @@ -1455,7 +1455,6 @@ def child(**kwargs): no_scrollbar (bool, optional): Disable scrollbars (window can still scroll with mouse or programmatically). horizontal_scrollbar (bool, optional): Allow horizontal scrollbar to appear (off by default). menubar (bool, optional): Shows/Hides the menubar at the top. - no_scroll_with_mouse (bool, optional): Disable user vertically scrolling with mouse wheel. Yields: Union[int, str] """ @@ -1486,7 +1485,7 @@ def set_start_callback(callback): @contextmanager -def child_window(*, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, width: int =0, height: int =0, indent: int =-1, parent: Union[int, str] =0, before: Union[int, str] =0, payload_type: str ='$$DPG_PAYLOAD', drop_callback: Callable =None, show: bool =True, pos: Union[List[int], Tuple[int, ...]] =[], filter_key: str ='', delay_search: bool =False, tracked: bool =False, track_offset: float =0.5, border: bool =True, autosize_x: bool =False, autosize_y: bool =False, no_scrollbar: bool =False, horizontal_scrollbar: bool =False, menubar: bool =False, no_scroll_with_mouse: bool=False, **kwargs) -> Union[int, str]: +def child_window(*, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, width: int =0, height: int =0, indent: int =-1, parent: Union[int, str] =0, before: Union[int, str] =0, payload_type: str ='$$DPG_PAYLOAD', drop_callback: Callable =None, show: bool =True, pos: Union[List[int], Tuple[int, ...]] =[], filter_key: str ='', delay_search: bool =False, tracked: bool =False, track_offset: float =0.5, border: bool =True, autosize_x: bool =False, autosize_y: bool =False, no_scrollbar: bool =False, horizontal_scrollbar: bool =False, menubar: bool =False, no_scroll_with_mouse: bool =False, **kwargs) -> Union[int, str]: """ Adds an embedded child window. Will show scrollbars when items do not fit. Args: @@ -1850,17 +1849,17 @@ def filter_set(*, label: str =None, user_data: Any =None, use_internal_label: bo internal_dpg.pop_container_stack() @contextmanager -def font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, pixel_snapH: bool =False, **kwargs) -> Union[int, str]: +def font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, pixel_snapH: bool =False, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, **kwargs) -> Union[int, str]: """ Adds font to a font registry. Args: file (str): size (int): - pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). label (str, optional): Overrides 'name' as label. user_data (Any, optional): User data for callbacks use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). tag (Union[int, str], optional): Unique id used to programmatically refer to the item.If label is unused this will be the label. + pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). parent (Union[int, str], optional): Parent to add this item to. (runtime adding) id (Union[int, str], optional): (deprecated) default_font (bool, optional): (deprecated) @@ -1876,7 +1875,7 @@ def font(file : str, size : int, *, label: str =None, user_data: Any =None, use_ if 'default_font' in kwargs.keys(): warnings.warn('default_font keyword removed', DeprecationWarning, 2) kwargs.pop('default_font', None) - widget = internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, pixel_snapH=pixel_snapH, **kwargs) + widget = internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, pixel_snapH=pixel_snapH, parent=parent, **kwargs) internal_dpg.push_container_stack(widget) yield widget finally: @@ -2829,7 +2828,7 @@ def window(*, label: str =None, user_data: Any =None, use_internal_label: bool = no_open_over_existing_popup (bool, optional): Don't open if there's already a popup no_scroll_with_mouse (bool, optional): Disable user vertically scrolling with mouse wheel. on_close (Callable, optional): Callback ran when window is closed. - id (Union[int, str], optional): (deprecated) + id (Union[int, str], optional): (deprecated) Yields: Union[int, str] """ @@ -3174,7 +3173,7 @@ def add_child_window(*, label: str =None, user_data: Any =None, use_internal_lab warnings.warn('id keyword renamed to tag', DeprecationWarning, 2) tag=kwargs['id'] - return internal_dpg.add_child_window(label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, width=width, height=height, indent=indent, parent=parent, before=before, payload_type=payload_type, drop_callback=drop_callback, show=show, pos=pos, filter_key=filter_key, delay_search=delay_search, tracked=tracked, track_offset=track_offset, border=border, autosize_x=autosize_x, autosize_y=autosize_y, no_scrollbar=no_scrollbar, horizontal_scrollbar=horizontal_scrollbar, menubar=menubar, **kwargs) + return internal_dpg.add_child_window(label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, width=width, height=height, indent=indent, parent=parent, before=before, payload_type=payload_type, drop_callback=drop_callback, show=show, pos=pos, filter_key=filter_key, delay_search=delay_search, tracked=tracked, track_offset=track_offset, border=border, autosize_x=autosize_x, autosize_y=autosize_y, no_scrollbar=no_scrollbar, horizontal_scrollbar=horizontal_scrollbar, menubar=menubar, no_scroll_with_mouse=no_scroll_with_mouse, **kwargs) def add_clipper(*, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, width: int =0, indent: int =-1, parent: Union[int, str] =0, before: Union[int, str] =0, show: bool =True, delay_search: bool =False, **kwargs) -> Union[int, str]: """ Helper to manually clip large list of items. Increases performance by not searching or drawing widgets outside of the clipped region. @@ -4309,17 +4308,17 @@ def add_float_vect_value(*, label: str =None, user_data: Any =None, use_internal return internal_dpg.add_float_vect_value(label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, source=source, default_value=default_value, parent=parent, **kwargs) -def add_font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, pixel_snapH: bool =False, **kwargs) -> Union[int, str]: +def add_font(file : str, size : int, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, pixel_snapH: bool =False, parent: Union[int, str] =internal_dpg.mvReservedUUID_0, **kwargs) -> Union[int, str]: """ Adds font to a font registry. Args: file (str): size (int): - pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). label (str, optional): Overrides 'name' as label. user_data (Any, optional): User data for callbacks use_internal_label (bool, optional): Use generated internal label instead of user specified (appends ### uuid). tag (Union[int, str], optional): Unique id used to programmatically refer to the item.If label is unused this will be the label. + pixel_snapH (bool, optional): Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font, or rendering text piece-by-piece (e.g. for coloring). parent (Union[int, str], optional): Parent to add this item to. (runtime adding) id (Union[int, str], optional): (deprecated) default_font (bool, optional): (deprecated) @@ -4337,7 +4336,7 @@ def add_font(file : str, size : int, *, label: str =None, user_data: Any =None, kwargs.pop('default_font', None) - return internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, pixel_snapH=pixel_snapH, **kwargs) + return internal_dpg.add_font(file, size, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, pixel_snapH=pixel_snapH, parent=parent, **kwargs) def add_font_chars(chars : Union[List[int], Tuple[int, ...]], *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =0, **kwargs) -> Union[int, str]: """ Adds specific font characters to a font. diff --git a/setup.py b/setup.py index 7d6385457..afc654b37 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ import shutil import subprocess -wip_version = "1.9.2" +wip_version = "1.10.0" def version_number(): """This function reads the version number which is populated by github actions""" From eb979321b639757a8289c835528b91f012dbb803 Mon Sep 17 00:00:00 2001 From: Jonathan Hoffstadt Date: Tue, 12 Sep 2023 22:06:12 -0500 Subject: [PATCH 08/18] chore: 1.10.1 WIP --- .github/workflows/Deployment.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Deployment.yml b/.github/workflows/Deployment.yml index 4e54f39ab..95fa4033f 100644 --- a/.github/workflows/Deployment.yml +++ b/.github/workflows/Deployment.yml @@ -17,7 +17,7 @@ on: version: description: 'Dear PyGui Version' required: false - default: '0.0.1' + default: '1.10.1' deploy: description: 'Deploy (true will deploy to pypi)' diff --git a/setup.py b/setup.py index afc654b37..b09f3d635 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ import shutil import subprocess -wip_version = "1.10.0" +wip_version = "1.10.1" def version_number(): """This function reads the version number which is populated by github actions""" From ecf672a34e34447c2b767a837a5ee81e29632821 Mon Sep 17 00:00:00 2001 From: Jonathan Hoffstadt Date: Mon, 9 Oct 2023 13:16:28 -0500 Subject: [PATCH 09/18] feat: add python 3.12 support --- .github/workflows/Deployment.yml | 12 ++++++------ setup.py | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/Deployment.yml b/.github/workflows/Deployment.yml index 95fa4033f..94c831e58 100644 --- a/.github/workflows/Deployment.yml +++ b/.github/workflows/Deployment.yml @@ -36,7 +36,7 @@ jobs: runs-on: windows-2019 strategy: matrix: - python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11" ] + python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11", "3.12" ] steps: @@ -64,7 +64,7 @@ jobs: shell: cmd run: | cd %GITHUB_WORKSPACE% - python -m pip install --upgrade pip twine wheel + python -m pip install --upgrade pip twine wheel setuptools python -m setup bdist_wheel --plat-name win_amd64 --dist-dir dist - name: Upload Windows ${{ matrix.python-version }} Wheel @@ -79,7 +79,7 @@ jobs: runs-on: macos-11 strategy: matrix: - python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11" ] + python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11", "3.12" ] steps: @@ -104,7 +104,7 @@ jobs: - name: Build Wheel run: | cd $GITHUB_WORKSPACE - python -m pip install --upgrade pip twine wheel + python -m pip install --upgrade pip twine wheel setuptools python -m setup bdist_wheel --plat-name macosx-10.6-x86_64 --dist-dir dist - name: Upload MacOS 10.15 ${{ matrix.python-version }} Wheel @@ -121,7 +121,7 @@ jobs: CXX: g++-9 strategy: matrix: - python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11" ] + python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11", "3.12" ] steps: @@ -148,7 +148,7 @@ jobs: - name: Build Wheel run: | cd $GITHUB_WORKSPACE - python -m pip install --upgrade pip twine wheel + python -m pip install --upgrade pip twine wheel setuptools python -m setup bdist_wheel --plat-name manylinux1_x86_64 --dist-dir dist - name: Upload Linux ${{ matrix.python-version }} Wheel diff --git a/setup.py b/setup.py index b09f3d635..f5f4ea404 100644 --- a/setup.py +++ b/setup.py @@ -185,6 +185,7 @@ def setup_package(): 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: 3 :: Only', 'Topic :: Software Development :: User Interfaces', From bdc02cb14b7dc60da0f7be2c6e851c09865b783c Mon Sep 17 00:00:00 2001 From: Jonathan Hoffstadt Date: Wed, 1 Nov 2023 19:31:19 -0500 Subject: [PATCH 10/18] docs: update minimum python version to 3.8 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 585edcad1..737bebd74 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ ## Installation -Ensure you have at least Python 3.7 64bit. +Ensure you have at least Python 3.8 64bit. ``` pip install dearpygui or From 49383185649020bb8d17bd7b30ad40f022a19f6f Mon Sep 17 00:00:00 2001 From: Raccoon <96011344+bandit-masked@users.noreply.github.com> Date: Thu, 30 Nov 2023 21:29:33 +0100 Subject: [PATCH 11/18] docs: Update README.md (#2228) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 737bebd74..5c4173b5c 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,8 @@ The built-in demo shows all of Dear PyGui's functionality. Use [this code](https - [Bug Tracker](https://github.com/hoffstadt/DearPyGui/issues?q=is%3Aissue+is%3Aopen+label%3A%22type%3A+bug%22) - [Useful code snippets demonstrating best practices](https://github.com/my1e5/dpg-examples) - [Showcase apps including source code](https://github.com/hoffstadt/DearPyGui/wiki/Dear-PyGui-Showcase) :star: +- [Showcase apps made with older versions of Dear PyGui](https://github.com/hoffstadt/DearPyGui/wiki/Showcase-apps-older-Dear-PyGui-versions) +- [Useful tools and widgets](https://github.com/hoffstadt/DearPyGui/wiki/Tools-and-Widgets) ## Support From 8b8d448f72c92884a254069a6b2d7340ad3d9a7e Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Tue, 19 Dec 2023 07:27:08 +0500 Subject: [PATCH 12/18] fix (mvDrawRect): Replaced four separate corner colors with a single parm that properly maps colors to corners #1996 (#2239) --- dearpygui/dearpygui.py | 12 ++++++------ src/mvAppItem.cpp | 1 + src/mvDrawings.cpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/dearpygui/dearpygui.py b/dearpygui/dearpygui.py index 159aeec6b..d8c0561d4 100644 --- a/dearpygui/dearpygui.py +++ b/dearpygui/dearpygui.py @@ -8026,7 +8026,7 @@ def draw_quad(p1 : Union[List[float], Tuple[float, ...]], p2 : Union[List[float] return internal_dpg.draw_quad(p1, p2, p3, p4, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, before=before, show=show, color=color, fill=fill, thickness=thickness, **kwargs) -def draw_rectangle(pmin : Union[List[float], Tuple[float, ...]], pmax : Union[List[float], Tuple[float, ...]], *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =0, before: Union[int, str] =0, show: bool =True, color: Union[List[int], Tuple[int, ...]] =(255, 255, 255, 255), color_upper_left: Union[List[int], Tuple[int, ...]] =(255, 255, 255, 255), color_upper_right: Union[List[int], Tuple[int, ...]] =(255, 255, 255, 255), color_bottom_right: Union[List[int], Tuple[int, ...]] =(255, 255, 255, 255), color_bottom_left: Union[List[int], Tuple[int, ...]] =(255, 255, 255, 255), fill: Union[List[int], Tuple[int, ...]] =(0, 0, 0, -255), multicolor: bool =False, rounding: float =0.0, thickness: float =1.0, **kwargs) -> Union[int, str]: +def draw_rectangle(pmin : Union[List[float], Tuple[float, ...]], pmax : Union[List[float], Tuple[float, ...]], *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =0, before: Union[int, str] =0, show: bool =True, color: Union[List[int], Tuple[int, ...]] =(255, 255, 255, 255), corner_colors: Union[List, Tuple, None] =None, fill: Union[List[int], Tuple[int, ...]] =(0, 0, 0, -255), multicolor: bool =False, rounding: float =0.0, thickness: float =1.0, **kwargs) -> Union[int, str]: """ Adds a rectangle. Args: @@ -8040,10 +8040,7 @@ def draw_rectangle(pmin : Union[List[float], Tuple[float, ...]], pmax : Union[Li before (Union[int, str], optional): This item will be displayed before the specified item in the parent. show (bool, optional): Attempt to render widget. color (Union[List[int], Tuple[int, ...]], optional): - color_upper_left (Union[List[int], Tuple[int, ...]], optional): 'multicolor' must be set to 'True' - color_upper_right (Union[List[int], Tuple[int, ...]], optional): 'multicolor' must be set to 'True' - color_bottom_right (Union[List[int], Tuple[int, ...]], optional): 'multicolor' must be set to 'True' - color_bottom_left (Union[List[int], Tuple[int, ...]], optional): 'multicolor' must be set to 'True' + corner_colors (Union[List, Tuple], optional): Corner colors in a list, starting with upper-left and going clockwise: (upper-left, upper-right, bottom-right, bottom-left). 'multicolor' must be set to 'True'. fill (Union[List[int], Tuple[int, ...]], optional): multicolor (bool, optional): rounding (float, optional): Number of pixels of the radius that will round the corners of the rectangle. Note: doesn't work with multicolor @@ -8057,7 +8054,10 @@ def draw_rectangle(pmin : Union[List[float], Tuple[float, ...]], pmax : Union[Li warnings.warn('id keyword renamed to tag', DeprecationWarning, 2) tag=kwargs['id'] - return internal_dpg.draw_rectangle(pmin, pmax, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, before=before, show=show, color=color, color_upper_left=color_upper_left, color_upper_right=color_upper_right, color_bottom_right=color_bottom_right, color_bottom_left=color_bottom_left, fill=fill, multicolor=multicolor, rounding=rounding, thickness=thickness, **kwargs) + if any(parm in kwargs.keys() for parm in ("color_upper_left", "color_upper_right", "color_bottom_left", "color_bottom_right")): + warnings.warn('Use corner_colors instead of color_x_y', DeprecationWarning, 2) + + return internal_dpg.draw_rectangle(pmin, pmax, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, parent=parent, before=before, show=show, color=color, corner_colors=corner_colors, fill=fill, multicolor=multicolor, rounding=rounding, thickness=thickness, **kwargs) def draw_text(pos : Union[List[float], Tuple[float, ...]], text : str, *, label: str =None, user_data: Any =None, use_internal_label: bool =True, tag: Union[int, str] =0, parent: Union[int, str] =0, before: Union[int, str] =0, show: bool =True, color: Union[List[int], Tuple[int, ...]] =(255, 255, 255, 255), size: float =10.0, **kwargs) -> Union[int, str]: """ Adds text (drawlist). diff --git a/src/mvAppItem.cpp b/src/mvAppItem.cpp index 180ed9f6c..0aab5f96e 100644 --- a/src/mvAppItem.cpp +++ b/src/mvAppItem.cpp @@ -3419,6 +3419,7 @@ DearPyGui::GetEntityParser(mvAppItemType type) args.push_back({ mvPyDataType::Bool, "multicolor", mvArgType::KEYWORD_ARG, "False" }); args.push_back({ mvPyDataType::Float, "rounding", mvArgType::KEYWORD_ARG, "0.0", "Number of pixels of the radius that will round the corners of the rectangle. Note: doesn't work with multicolor" }); args.push_back({ mvPyDataType::Float, "thickness", mvArgType::KEYWORD_ARG, "1.0" }); + args.push_back({ mvPyDataType::ListListInt, "corner_colors", mvArgType::KEYWORD_ARG, "[(255, 255, 255, 255), (255, 255, 255, 255), (255, 255, 255, 255), (255, 255, 255, 255)]", "Corner colors in a list, starting with upper-left and going clockwise: (upper-left, upper-right, bottom-right, bottom-left). 'multicolor' must be set to 'True'." }); setup.about = "Adds a rectangle."; setup.category = { "Drawlist", "Widgets" }; diff --git a/src/mvDrawings.cpp b/src/mvDrawings.cpp index 78fc413c1..135d751a3 100644 --- a/src/mvDrawings.cpp +++ b/src/mvDrawings.cpp @@ -1451,6 +1451,41 @@ void mvDrawRect::handleSpecificKeywordArgs(PyObject* dict) if (PyObject* item = PyDict_GetItemString(dict, "rounding")) _rounding = ToFloat(item); if (PyObject* item = PyDict_GetItemString(dict, "thickness")) _thickness = ToFloat(item); if (PyObject* item = PyDict_GetItemString(dict, "multicolor")) _multicolor = ToBool(item); + if (PyObject* item = PyDict_GetItemString(dict, "corner_colors")) + { + if (item != Py_None) + { + if (PyTuple_Check(item)) + { + if (PyTuple_Size(item) != 4) + mvThrowPythonError(mvErrorCode::mvNone, "The corner_colors parm on draw_rectangle must contain 4 colors."); + else + { + // Note: the variables are named incorrectly, e.g. _color_bottom_right + // actually controls upper-left corner. That's how old Python parms + // were named so we're keeping the names for a while until we drop the + // old parms altogether (if this ever happens). + // For now, we're just filling them in appropriate order. + _color_bottom_right = ToColor(PyTuple_GetItem(item, 0)); + _color_bottom_left = ToColor(PyTuple_GetItem(item, 1)); + _color_upper_left = ToColor(PyTuple_GetItem(item, 2)); + _color_upper_right = ToColor(PyTuple_GetItem(item, 3)); + } + } + else if (PyList_Check(item)) + { + if (PyList_Size(item) != 4) + mvThrowPythonError(mvErrorCode::mvNone, "The corner_colors parm on draw_rectangle must contain 4 colors."); + else + { + _color_bottom_right = ToColor(PyList_GetItem(item, 0)); + _color_bottom_left = ToColor(PyList_GetItem(item, 1)); + _color_upper_left = ToColor(PyList_GetItem(item, 2)); + _color_upper_right = ToColor(PyList_GetItem(item, 3)); + } + } + } + } if (_multicolor) _rounding = 0.0f; From ee71d74da68dbd0be4fcec0dd8f561966852da70 Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Wed, 23 Nov 2022 23:52:36 +0500 Subject: [PATCH 13/18] fix: adding/removing a child in the table doesn't reset row colors. fix: enabled themes on table rows (previously themes could be bound but didn't work). Column themes are not implemented yet. #1782 --- src/mvItemRegistry.cpp | 5 +++ src/mvTables.cpp | 71 ++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/mvItemRegistry.cpp b/src/mvItemRegistry.cpp index fa6f0ecf4..6c7b3246a 100644 --- a/src/mvItemRegistry.cpp +++ b/src/mvItemRegistry.cpp @@ -453,6 +453,7 @@ AddRuntimeChild(mvAppItem* rootitem, mvUUID parent, mvUUID before, std::shared_p std::vector> oldchildren = children; children.clear(); + int location = 0; for (auto& child : oldchildren) { if (!child) @@ -461,12 +462,16 @@ AddRuntimeChild(mvAppItem* rootitem, mvUUID parent, mvUUID before, std::shared_p if (child->uuid == before) { children.push_back(item); + item->info.location = location; DearPyGui::OnChildAdded(rootitem, item); + ++location; } children.push_back(child); + ++location; } + // TODO: maybe remove this call since location gets updated inside the loop UpdateChildLocations(rootitem->childslots, 4); return true; diff --git a/src/mvTables.cpp b/src/mvTables.cpp index 342bee7ac..b8e9c28de 100644 --- a/src/mvTables.cpp +++ b/src/mvTables.cpp @@ -146,10 +146,18 @@ void mvTable::draw(ImDrawList* drawlist, float x, float y) if (_columns == 0) return; - auto row_renderer = [&](mvAppItem* row) + auto row_renderer = [&](mvAppItem* row, mvAppItem* prev_visible_row=nullptr) { + //TableNextRow() ends the previous row, if any, and determines background color for it. + //We have to specify themes in a way that it captures the theme for the previous + //*visible* row, not for the current one. That's why we apply the theme *after* + //TableNextRow() and leave it active through the next TableNextRow() call. ImGui::TableNextRow(0, (float)row->config.height); + if (prev_visible_row) + cleanup_local_theming(prev_visible_row); + apply_local_theming(row); + row->state.lastFrameUpdate = GContext->frame; row->state.visible = true; @@ -279,6 +287,8 @@ void mvTable::draw(ImDrawList* drawlist, float x, float y) } } + std::shared_ptr prev_themed_row = nullptr; + if (_rows != 0) { @@ -310,7 +320,8 @@ void mvTable::draw(ImDrawList* drawlist, float x, float y) for (auto& row : childslots[1]) { if (row->config.show) - row_renderer(row.get()); + row_renderer(row.get(), prev_themed_row.get()); + prev_themed_row = row; } } } @@ -350,6 +361,9 @@ void mvTable::draw(ImDrawList* drawlist, float x, float y) _scrollMaxY = ImGui::GetScrollMaxY(); ImGui::EndTable(); + + if (prev_themed_row) + cleanup_local_theming(prev_themed_row.get()); } } @@ -389,11 +403,13 @@ void mvTable::onChildAdd(std::shared_ptr item) else if (item->type == mvAppItemType::mvTableRow) { _rows++; - _rowColors.push_back(ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f))); - _rowColorsSet.push_back(false); - _rowSelectionColors.push_back(ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f))); - _rowSelectionColorsSet.push_back(false); + int location = item->info.location; + _rowColors.insert(_rowColors.begin() + location, ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f))); + _rowColorsSet.insert(_rowColorsSet.begin() + location, false); + _rowSelectionColors.insert(_rowSelectionColors.begin() + location, ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f))); + _rowSelectionColorsSet.insert(_rowSelectionColorsSet.begin() + location, false); + // TODO: OMFG, this needs to be fixed, too. _cellColorsSet.push_back({}); _cellColors.push_back({}); for (int i = 0; i < _columns; i++) @@ -406,44 +422,23 @@ void mvTable::onChildAdd(std::shared_ptr item) void mvTable::onChildRemoved(std::shared_ptr item) { + int location = item->info.location; if (item->type == mvAppItemType::mvTableColumn) { - childslots[2][item->info.location] = nullptr; + childslots[2][location] = nullptr; _columns--; + _columnColors.erase(_columnColors.begin() + location); + _columnColorsSet.erase(_columnColorsSet.begin() + location); } else if (item->type == mvAppItemType::mvTableRow) - _rows--; - - - _columnColors.resize(_columns); - _columnColorsSet.resize(_columns); - _rowColors.resize(_rows); - _rowColorsSet.resize(_rows); - _rowSelectionColors.resize(_rows); - _rowSelectionColorsSet.resize(_rows); - - _cellColorsSet.resize(_rows); - _cellColors.resize(_rows); - for (int i = 0; i < _columns; i++) - { - _columnColors[i] = ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - _columnColorsSet[i] = false; - } - - for (int i = 0; i < _rows; i++) { - _rowColors[i] = ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - _rowColorsSet[i] = false; - _rowSelectionColors[i] = ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - _rowSelectionColorsSet[i] = false; - - _cellColorsSet[i].resize(_columns); - _cellColors[i].resize(_columns); - for (int j = 0; j < _columns; j++) - { - _cellColorsSet[i][j] = false; - _cellColors[i][j] = ImGui::ColorConvertFloat4ToU32(ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - } + _rows--; + _rowColors.erase(_rowColors.begin() + location); + _rowColorsSet.erase(_rowColorsSet.begin() + location); + _rowSelectionColors.erase(_rowSelectionColors.begin() + location); + _rowSelectionColorsSet.erase(_rowSelectionColorsSet.begin() + location); + _cellColorsSet.erase(_cellColorsSet.begin() + location); + _cellColors.erase(_cellColors.begin() + location); } } From f6e50b2386acea65157213a36474114de7954616 Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Thu, 24 Nov 2022 16:09:10 +0500 Subject: [PATCH 14/18] fix: enabled themes on table columns and cells #1782 --- src/mvTables.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mvTables.cpp b/src/mvTables.cpp index b8e9c28de..50aed94ec 100644 --- a/src/mvTables.cpp +++ b/src/mvTables.cpp @@ -197,7 +197,13 @@ void mvTable::draw(ImDrawList* drawlist, float x, float y) auto& columnItem = childslots[0][column_index]; if(columnItem->config.enabled) + { + apply_local_theming(columnItem.get()); + apply_local_theming(cell.get()); cell->draw(drawlist, ImGui::GetCursorPosX(), ImGui::GetCursorPosY()); + cleanup_local_theming(cell.get()); + cleanup_local_theming(columnItem.get()); + } } }; From 01f646e49bd7558d296582e239fbca573aa2039c Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Fri, 10 Nov 2023 15:09:48 +0500 Subject: [PATCH 15/18] fix (mvNodeEditor): Nodes created with show=False lead to segfault #2151 --- src/mvNodes.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mvNodes.cpp b/src/mvNodes.cpp index 1f0054855..daf122ee6 100644 --- a/src/mvNodes.cpp +++ b/src/mvNodes.cpp @@ -264,8 +264,14 @@ void mvNodeEditor::draw(ImDrawList* drawlist, float x, float y) child->state.lastFrameUpdate = GContext->frame; child->state.hovered = false; - ImVec2 size = ImNodes::GetNodeDimensions(static_cast(child.get())->getId()); - child->state.rectSize = { size.x, size.y }; + if (child->config.show) + { + // We can only refer to visible nodes here + ImVec2 size = ImNodes::GetNodeDimensions(static_cast(child.get())->getId()); + child->state.rectSize = { size.x, size.y }; + } + else + child->state.rectSize = { 0.0f, 0.0f }; if (anyNodeHovered && nodeHovered == static_cast(child.get())->getId()) child->state.hovered = true; From 7445213f1698fa9de4dc771b820e5300b0c9ec96 Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Sat, 23 Sep 2023 00:11:00 +0500 Subject: [PATCH 16/18] fix (handlers): Proper testing for handler applicability. --- src/mvItemHandlers.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mvItemHandlers.cpp b/src/mvItemHandlers.cpp index 7da421067..93e79a2ad 100644 --- a/src/mvItemHandlers.cpp +++ b/src/mvItemHandlers.cpp @@ -65,7 +65,7 @@ void mvItemHandlerRegistry::onBind(mvAppItem* item) case mvAppItemType::mvDeactivatedHandler: { - if (!(applicableState & ~MV_STATE_DEACTIVATED)) + if (!(applicableState & MV_STATE_DEACTIVATED)) mvThrowPythonError(mvErrorCode::mvNone, "bind_item_handler_registry", "Item Handler Registry includes inapplicable handler: mvDeactivatedHandler", item); break; @@ -73,7 +73,7 @@ void mvItemHandlerRegistry::onBind(mvAppItem* item) case mvAppItemType::mvEditedHandler: { - if (!(applicableState & ~MV_STATE_EDITED)) + if (!(applicableState & MV_STATE_EDITED)) mvThrowPythonError(mvErrorCode::mvNone, "bind_item_handler_registry", "Item Handler Registry includes inapplicable handler: mvEditedHandler", item); break; @@ -81,7 +81,7 @@ void mvItemHandlerRegistry::onBind(mvAppItem* item) case mvAppItemType::mvFocusHandler: { - if (!(applicableState & ~MV_STATE_FOCUSED)) + if (!(applicableState & MV_STATE_FOCUSED)) mvThrowPythonError(mvErrorCode::mvNone, "bind_item_handler_registry", "Item Handler Registry includes inapplicable handler: mvFocusHandler", item); break; @@ -89,7 +89,7 @@ void mvItemHandlerRegistry::onBind(mvAppItem* item) case mvAppItemType::mvHoverHandler: { - if (!(applicableState & ~MV_STATE_HOVER)) + if (!(applicableState & MV_STATE_HOVER)) mvThrowPythonError(mvErrorCode::mvNone, "bind_item_handler_registry", "Item Handler Registry includes inapplicable handler: mvHoverHandler", item); break; @@ -97,7 +97,7 @@ void mvItemHandlerRegistry::onBind(mvAppItem* item) case mvAppItemType::mvResizeHandler: { - if (!(applicableState & ~MV_STATE_RECT_SIZE)) + if (!(applicableState & MV_STATE_RECT_SIZE)) mvThrowPythonError(mvErrorCode::mvNone, "bind_item_handler_registry", "Item Handler Registry includes inapplicable handler: mvResizeHandler", item); break; @@ -105,7 +105,7 @@ void mvItemHandlerRegistry::onBind(mvAppItem* item) case mvAppItemType::mvToggledOpenHandler: { - if (!(applicableState & ~MV_STATE_TOGGLED_OPEN)) + if (!(applicableState & MV_STATE_TOGGLED_OPEN)) mvThrowPythonError(mvErrorCode::mvNone, "bind_item_handler_registry", "Item Handler Registry includes inapplicable handler: mvToggledOpenHandler", item); break; From 8b7e1909751475e36c88ad3e970e1bbf538a1c1e Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Fri, 6 Oct 2023 13:17:02 +0500 Subject: [PATCH 17/18] fix (mvNodeLink): Passing state to handlers instead of nullptr #2197 --- src/mvNodes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mvNodes.cpp b/src/mvNodes.cpp index daf122ee6..30c800b9d 100644 --- a/src/mvNodes.cpp +++ b/src/mvNodes.cpp @@ -696,7 +696,7 @@ void mvNodeLink::handleSpecificRequiredArgs(PyObject* dict) void mvNodeLink::customAction(void* data) { if (handlerRegistry) - handlerRegistry->checkEvents(data); + handlerRegistry->checkEvents(&state); } void mvNodeLink::draw(ImDrawList* drawlist, float x, float y) From 4eaf48ec5344c532da1a87c9b62dfc3d5338900f Mon Sep 17 00:00:00 2001 From: Vladimir Ein Date: Fri, 29 Dec 2023 21:26:22 +0500 Subject: [PATCH 18/18] fix (mvMenu): Resetting menu state if it's not open #2245 Also, restored indentation in draw_menu() - it's much easier to read now. --- src/mvContainers.cpp | 106 ++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/src/mvContainers.cpp b/src/mvContainers.cpp index edcd96a43..7e21130a8 100644 --- a/src/mvContainers.cpp +++ b/src/mvContainers.cpp @@ -588,13 +588,13 @@ DearPyGui::draw_menu(ImDrawList* drawlist, mvAppItem& item, mvMenuConfig& config // show/hide if (!item.config.show) - return; + return; // focusing if (item.info.focusNextFrame) { - ImGui::SetKeyboardFocusHere(); - item.info.focusNextFrame = false; + ImGui::SetKeyboardFocusHere(); + item.info.focusNextFrame = false; } // cache old cursor position @@ -602,24 +602,24 @@ DearPyGui::draw_menu(ImDrawList* drawlist, mvAppItem& item, mvMenuConfig& config // set cursor position if user set if (item.info.dirtyPos) - ImGui::SetCursorPos(item.state.pos); + ImGui::SetCursorPos(item.state.pos); // update widget's position state item.state.pos = { ImGui::GetCursorPosX(), ImGui::GetCursorPosY() }; // set item width if (item.config.width != 0) - ImGui::SetNextItemWidth((float)item.config.width); + ImGui::SetNextItemWidth((float)item.config.width); // set indent if (item.config.indent > 0.0f) - ImGui::Indent(item.config.indent); + ImGui::Indent(item.config.indent); // push font if a font object is attached if (item.font) { - ImFont* fontptr = static_cast(item.font.get())->getFontPtr(); - ImGui::PushFont(fontptr); + ImFont* fontptr = static_cast(item.font.get())->getFontPtr(); + ImGui::PushFont(fontptr); } // themes @@ -641,63 +641,77 @@ DearPyGui::draw_menu(ImDrawList* drawlist, mvAppItem& item, mvMenuConfig& config item.state.rectSize = { ImGui::GetWindowWidth(), ImGui::GetWindowHeight() }; item.state.contextRegionAvail = { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }; - // set other menus's value false on same level - for (auto& sibling : item.info.parentPtr->childslots[1]) - { - // ensure sibling - if (sibling->type == mvAppItemType::mvMenu) - *((mvMenu*)sibling.get())->configData.value = false; - } + // set other menus's value false on same level + for (auto& sibling : item.info.parentPtr->childslots[1]) + { + // ensure sibling + if (sibling->type == mvAppItemType::mvMenu) + *((mvMenu*)sibling.get())->configData.value = false; + } - // set current menu value true - *config.value = true; + // set current menu value true + *config.value = true; - for (auto& child : item.childslots[1]) - child->draw(drawlist, ImGui::GetCursorPosX(), ImGui::GetCursorPosY()); + for (auto& child : item.childslots[1]) + child->draw(drawlist, ImGui::GetCursorPosX(), ImGui::GetCursorPosY()); - if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) - { + if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) + { - // update mouse - ImVec2 mousePos = ImGui::GetMousePos(); - float x = mousePos.x - ImGui::GetWindowPos().x; - float y = mousePos.y - ImGui::GetWindowPos().y; - GContext->input.mousePos.x = (int)x; - GContext->input.mousePos.y = (int)y; + // update mouse + ImVec2 mousePos = ImGui::GetMousePos(); + float x = mousePos.x - ImGui::GetWindowPos().x; + float y = mousePos.y - ImGui::GetWindowPos().y; + GContext->input.mousePos.x = (int)x; + GContext->input.mousePos.y = (int)y; - if (GContext->itemRegistry->activeWindow != item.uuid) - GContext->itemRegistry->activeWindow = item.uuid; + if (GContext->itemRegistry->activeWindow != item.uuid) + GContext->itemRegistry->activeWindow = item.uuid; - } + } - ImGui::EndMenu(); + ImGui::EndMenu(); } + else + { + // even if menu popup is not open, we still need to update the state + item.state.lastFrameUpdate = GContext->frame; + item.state.active = ImGui::IsItemActive(); + item.state.activated = ImGui::IsItemActivated(); + item.state.deactivated = ImGui::IsItemDeactivated(); + item.state.prevFocused = item.state.focused; + item.state.focused = false; + item.state.prevHovered = item.state.hovered; + item.state.hovered = false; + item.state.rectSize = { 0.0f, 0.0f }; + item.state.contextRegionAvail = { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }; } + } - //----------------------------------------------------------------------------- - // post draw - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + // post draw + //----------------------------------------------------------------------------- - // set cursor position to cached position - if (item.info.dirtyPos) + // set cursor position to cached position + if (item.info.dirtyPos) ImGui::SetCursorPos(previousCursorPos); - if (item.config.indent > 0.0f) + if (item.config.indent > 0.0f) ImGui::Unindent(item.config.indent); - // pop font off stack - if (item.font) - ImGui::PopFont(); + // pop font off stack + if (item.font) + ImGui::PopFont(); - // handle popping themes - cleanup_local_theming(&item); + // handle popping themes + cleanup_local_theming(&item); - if (item.handlerRegistry) - item.handlerRegistry->checkEvents(&item.state); + if (item.handlerRegistry) + item.handlerRegistry->checkEvents(&item.state); - // handle drag & drop if used - apply_drag_drop(&item); + // handle drag & drop if used + apply_drag_drop(&item); } void