MoleditPy-linux 4.6.0__tar.gz → 4.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/PKG-INFO +1 -1
  2. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/pyproject.toml +1 -1
  3. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/MoleditPy_linux.egg-info/PKG-INFO +1 -1
  4. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/atom_item.py +16 -3
  5. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/bond_item.py +18 -4
  6. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/molecular_scene_handler.py +18 -2
  7. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/molecule_scene.py +2 -2
  8. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/settings_tabs/settings_2d_tab.py +4 -1
  9. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/LICENSE +0 -0
  10. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/README.md +0 -0
  11. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/setup.cfg +0 -0
  12. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/MoleditPy_linux.egg-info/SOURCES.txt +0 -0
  13. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/MoleditPy_linux.egg-info/dependency_links.txt +0 -0
  14. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/MoleditPy_linux.egg-info/entry_points.txt +0 -0
  15. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/MoleditPy_linux.egg-info/requires.txt +0 -0
  16. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/MoleditPy_linux.egg-info/top_level.txt +0 -0
  17. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/__init__.py +0 -0
  18. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/__main__.py +0 -0
  19. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/assets/file_icon.ico +0 -0
  20. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/assets/icon.icns +0 -0
  21. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/assets/icon.ico +0 -0
  22. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/assets/icon.png +0 -0
  23. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/core/__init__.py +0 -0
  24. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/core/mol_geometry.py +0 -0
  25. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/core/molecular_data.py +0 -0
  26. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/main.py +0 -0
  27. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/plugins/__init__.py +0 -0
  28. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/plugins/plugin_interface.py +0 -0
  29. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/plugins/plugin_manager.py +0 -0
  30. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/plugins/plugin_manager_window.py +0 -0
  31. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/__init__.py +0 -0
  32. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/about_dialog.py +0 -0
  33. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/align_plane_dialog.py +0 -0
  34. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/alignment_dialog.py +0 -0
  35. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/analysis_window.py +0 -0
  36. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/angle_dialog.py +0 -0
  37. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/app_state.py +0 -0
  38. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/atom_picking.py +0 -0
  39. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/base_picking_dialog.py +0 -0
  40. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/bond_length_dialog.py +0 -0
  41. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/calculation_worker.py +0 -0
  42. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/chain_mixin.py +0 -0
  43. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/color_settings_dialog.py +0 -0
  44. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/compute_logic.py +0 -0
  45. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/constrained_optimization_dialog.py +0 -0
  46. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/custom_interactor_style.py +0 -0
  47. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/custom_qt_interactor.py +0 -0
  48. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/dialog_3d_picking_mixin.py +0 -0
  49. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/dialog_logic.py +0 -0
  50. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/dihedral_dialog.py +0 -0
  51. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/edit_3d_logic.py +0 -0
  52. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/edit_actions_logic.py +0 -0
  53. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/export_logic.py +0 -0
  54. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/geometry_base_dialog.py +0 -0
  55. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/io_logic.py +0 -0
  56. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/main_window.py +0 -0
  57. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/main_window_init.py +0 -0
  58. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/mirror_dialog.py +0 -0
  59. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/move_group_dialog.py +0 -0
  60. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/move_selected_atoms_dialog.py +0 -0
  61. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/periodic_table_dialog.py +0 -0
  62. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/planarize_dialog.py +0 -0
  63. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/plugin_menu_manager.py +0 -0
  64. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/settings_dialog.py +0 -0
  65. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/settings_tabs/__init__.py +0 -0
  66. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/settings_tabs/settings_3d_tabs.py +0 -0
  67. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/settings_tabs/settings_other_tab.py +0 -0
  68. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/settings_tabs/settings_tab_base.py +0 -0
  69. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/string_importers.py +0 -0
  70. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/template_preview_item.py +0 -0
  71. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/template_preview_view.py +0 -0
  72. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/translation_dialog.py +0 -0
  73. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/ui_manager.py +0 -0
  74. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/user_template_dialog.py +0 -0
  75. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/view_3d_logic.py +0 -0
  76. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/ui/zoomable_view.py +0 -0
  77. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/utils/__init__.py +0 -0
  78. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/utils/constants.py +0 -0
  79. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/utils/default_settings.py +0 -0
  80. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/utils/sip_isdeleted_safe.py +0 -0
  81. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/utils/suppress_log.py +0 -0
  82. {moleditpy_linux-4.6.0 → moleditpy_linux-4.6.1}/src/moleditpy_linux/utils/system_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy-linux
3
- Version: 4.6.0
3
+ Version: 4.6.1
4
4
  Summary: A cross-platform, simple, and intuitive molecular structure editor built in Python. It allows 2D molecular drawing and 3D structure visualization. It supports exporting structure files for input to DFT calculation software.
5
5
  Author-email: HiroYokoyama <titech.yoko.hiro@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "MoleditPy-linux"
7
7
 
8
- version = "4.6.0"
8
+ version = "4.6.1"
9
9
 
10
10
  license = {file = "LICENSE"}
11
11
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MoleditPy-linux
3
- Version: 4.6.0
3
+ Version: 4.6.1
4
4
  Summary: A cross-platform, simple, and intuitive molecular structure editor built in Python. It allows 2D molecular drawing and 3D structure visualization. It supports exporting structure files for input to DFT calculation software.
5
5
  Author-email: HiroYokoyama <titech.yoko.hiro@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -34,7 +34,6 @@ from PyQt6.QtWidgets import (
34
34
  from ..utils.constants import (
35
35
  ATOM_RADIUS,
36
36
  CPK_COLORS,
37
- DESIRED_ATOM_PIXEL_RADIUS,
38
37
  FONT_FAMILY,
39
38
  FONT_WEIGHT_BOLD,
40
39
  )
@@ -332,7 +331,13 @@ class AtomItem(QGraphicsItem):
332
331
  return path
333
332
 
334
333
  def shape(self) -> QPainterPath:
335
- """Define the shape of the atom item for collision detection."""
334
+ """Define the shape of the atom item for collision detection.
335
+
336
+ The hit radius is derived from the ``bond_snapping_distance_2d``
337
+ setting so that hover highlight matches the snapping / keyboard
338
+ instant-switch zone exactly. The radius is expressed in screen
339
+ pixels and divided by the current view scale.
340
+ """
336
341
  scene = self.scene()
337
342
  if not scene or not scene.views():
338
343
  path = QPainterPath()
@@ -342,8 +347,16 @@ class AtomItem(QGraphicsItem):
342
347
 
343
348
  view = scene.views()[0]
344
349
  scale = view.transform().m11()
350
+ if scale <= 0.0:
351
+ scale = 1.0
345
352
 
346
- scene_radius = DESIRED_ATOM_PIXEL_RADIUS / scale
353
+ # Use the same setting that find_atom_near() uses for snapping,
354
+ # so hover highlight and snap zones are identical.
355
+ if hasattr(scene, "get_setting"):
356
+ hit_px = scene.get_setting("bond_snapping_distance_2d", 14.0)
357
+ else:
358
+ hit_px = 14.0
359
+ scene_radius = hit_px / scale
347
360
 
348
361
  path = QPainterPath()
349
362
  path.addEllipse(QPointF(0, 0), scene_radius, scene_radius)
@@ -36,7 +36,6 @@ from PyQt6.QtWidgets import (
36
36
  )
37
37
 
38
38
  from ..utils.constants import (
39
- DESIRED_BOND_PIXEL_WIDTH,
40
39
  EZ_LABEL_BOX_SIZE,
41
40
  EZ_LABEL_MARGIN,
42
41
  EZ_LABEL_TEXT_OUTLINE,
@@ -293,10 +292,25 @@ class BondItem(QGraphicsItem):
293
292
  path.moveTo(line.p1())
294
293
  path.lineTo(line.p2())
295
294
 
296
- # Stroke it to give it some width (e.g., 10px or dynamic based on settings) generally easier to click
297
- # even if the visual width is smaller.
295
+ # Use the exact same setting as atom hover highlight and snapping, zoom-aware.
296
+ scene = self.scene()
297
+ if scene and scene.views():
298
+ view = scene.views()[0]
299
+ scale = view.transform().m11()
300
+ if scale <= 0.0:
301
+ scale = 1.0
302
+ if hasattr(scene, "get_setting"):
303
+ hit_px = scene.get_setting("bond_snapping_distance_2d", 14.0)
304
+ else:
305
+ hit_px = 14.0
306
+ # width is diameter, so 2 * radius
307
+ scene_width = (hit_px * 2) / scale
308
+ else:
309
+ scene_width = 28.0
310
+
311
+ # Stroke it to give it some width
298
312
  stroker = QPainterPathStroker()
299
- stroker.setWidth(DESIRED_BOND_PIXEL_WIDTH) # Use constant (20.0)
313
+ stroker.setWidth(scene_width)
300
314
  path = stroker.createStroke(path)
301
315
 
302
316
  # If there's an E/Z label, add its rect to the selection shape
@@ -856,7 +856,10 @@ class KeyboardMixin:
856
856
  return
857
857
 
858
858
  view = self.views()[0]
859
- cursor_pos = view.mapToScene(view.mapFromGlobal(QCursor.pos()))
859
+ # mapToScene expects viewport coordinates. Mapping to the view widget directly
860
+ # includes the widget's frame margins, introducing a cursor offset that gets
861
+ # magnified when zooming.
862
+ cursor_pos = view.mapToScene(view.viewport().mapFromGlobal(QCursor.pos()))
860
863
  transform = view.transform()
861
864
  key = event.key()
862
865
  modifiers = event.modifiers()
@@ -1587,9 +1590,22 @@ class SceneQueryMixin:
1587
1590
  return False
1588
1591
 
1589
1592
  def find_atom_near(self, pos: Any, tol: float = 14.0) -> Any:
1590
- """Return the AtomItem within tolerance distance of pos, or None."""
1593
+ """Return the AtomItem within tolerance distance of pos, or None.
1594
+
1595
+ ``tol`` is specified in **screen pixels**. It is divided by the
1596
+ current view scale so that the effective snap radius stays constant
1597
+ on screen regardless of zoom level — matching the behaviour of
1598
+ ``AtomItem.shape()`` (hover highlight).
1599
+ """
1591
1600
  if pos is None:
1592
1601
  return None
1602
+ # Convert screen-pixel tolerance to scene units (zoom-aware).
1603
+ if self.views():
1604
+ xform = self.views()[0].transform()
1605
+ if xform is not None:
1606
+ scale = xform.m11()
1607
+ if scale > 0:
1608
+ tol = tol / scale
1593
1609
  # Create a small search rectangle around the position
1594
1610
  search_rect = QRectF(pos.x() - tol, pos.y() - tol, 2 * tol, 2 * tol)
1595
1611
  nearby_items = self.items(search_rect)
@@ -1002,8 +1002,8 @@ class MoleculeScene(
1002
1002
  # Find the active view for this scene
1003
1003
  for view in self.views():
1004
1004
  if view.isVisible():
1005
- # Map global cursor position to scene coordinates
1006
- local_pos = view.mapFromGlobal(global_pos)
1005
+ # Map global cursor position to scene coordinates (via viewport)
1006
+ local_pos = view.viewport().mapFromGlobal(global_pos)
1007
1007
  scene_pos = view.mapToScene(local_pos)
1008
1008
 
1009
1009
  # If the mouse is within the viewport, trigger the preview update
@@ -198,7 +198,10 @@ class Settings2DTab(SettingsTabBase):
198
198
  self._create_slider(5, 50, 1.0, is_int=True)
199
199
  )
200
200
  self.bond_snapping_distance_2d_slider.setToolTip(
201
- "The distance in pixels within which drawing a bond will snap to an existing atom."
201
+ "The distance in screen pixels (zoom-independent) within which:\n"
202
+ "• Drawing a bond snaps to an existing atom\n"
203
+ "• Keyboard shortcuts instantly edit the atom under cursor\n"
204
+ "• Atoms show hover highlight"
202
205
  )
203
206
  form_layout.addRow(
204
207
  "Bond Snapping Distance (px):",
File without changes