MoleditPy-linux 2.4.1__py3-none-any.whl

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 (59) hide show
  1. moleditpy_linux/__init__.py +17 -0
  2. moleditpy_linux/__main__.py +29 -0
  3. moleditpy_linux/main.py +37 -0
  4. moleditpy_linux/modules/__init__.py +41 -0
  5. moleditpy_linux/modules/about_dialog.py +104 -0
  6. moleditpy_linux/modules/align_plane_dialog.py +292 -0
  7. moleditpy_linux/modules/alignment_dialog.py +272 -0
  8. moleditpy_linux/modules/analysis_window.py +209 -0
  9. moleditpy_linux/modules/angle_dialog.py +440 -0
  10. moleditpy_linux/modules/assets/file_icon.ico +0 -0
  11. moleditpy_linux/modules/assets/icon.icns +0 -0
  12. moleditpy_linux/modules/assets/icon.ico +0 -0
  13. moleditpy_linux/modules/assets/icon.png +0 -0
  14. moleditpy_linux/modules/atom_item.py +395 -0
  15. moleditpy_linux/modules/bond_item.py +464 -0
  16. moleditpy_linux/modules/bond_length_dialog.py +380 -0
  17. moleditpy_linux/modules/calculation_worker.py +766 -0
  18. moleditpy_linux/modules/color_settings_dialog.py +321 -0
  19. moleditpy_linux/modules/constants.py +88 -0
  20. moleditpy_linux/modules/constrained_optimization_dialog.py +678 -0
  21. moleditpy_linux/modules/custom_interactor_style.py +749 -0
  22. moleditpy_linux/modules/custom_qt_interactor.py +102 -0
  23. moleditpy_linux/modules/dialog3_d_picking_mixin.py +141 -0
  24. moleditpy_linux/modules/dihedral_dialog.py +443 -0
  25. moleditpy_linux/modules/main_window.py +850 -0
  26. moleditpy_linux/modules/main_window_app_state.py +787 -0
  27. moleditpy_linux/modules/main_window_compute.py +1242 -0
  28. moleditpy_linux/modules/main_window_dialog_manager.py +460 -0
  29. moleditpy_linux/modules/main_window_edit_3d.py +536 -0
  30. moleditpy_linux/modules/main_window_edit_actions.py +1565 -0
  31. moleditpy_linux/modules/main_window_export.py +917 -0
  32. moleditpy_linux/modules/main_window_main_init.py +2100 -0
  33. moleditpy_linux/modules/main_window_molecular_parsers.py +1044 -0
  34. moleditpy_linux/modules/main_window_project_io.py +434 -0
  35. moleditpy_linux/modules/main_window_string_importers.py +275 -0
  36. moleditpy_linux/modules/main_window_ui_manager.py +602 -0
  37. moleditpy_linux/modules/main_window_view_3d.py +1539 -0
  38. moleditpy_linux/modules/main_window_view_loaders.py +355 -0
  39. moleditpy_linux/modules/mirror_dialog.py +122 -0
  40. moleditpy_linux/modules/molecular_data.py +302 -0
  41. moleditpy_linux/modules/molecule_scene.py +2000 -0
  42. moleditpy_linux/modules/move_group_dialog.py +600 -0
  43. moleditpy_linux/modules/periodic_table_dialog.py +84 -0
  44. moleditpy_linux/modules/planarize_dialog.py +220 -0
  45. moleditpy_linux/modules/plugin_interface.py +215 -0
  46. moleditpy_linux/modules/plugin_manager.py +473 -0
  47. moleditpy_linux/modules/plugin_manager_window.py +274 -0
  48. moleditpy_linux/modules/settings_dialog.py +1503 -0
  49. moleditpy_linux/modules/template_preview_item.py +157 -0
  50. moleditpy_linux/modules/template_preview_view.py +74 -0
  51. moleditpy_linux/modules/translation_dialog.py +364 -0
  52. moleditpy_linux/modules/user_template_dialog.py +692 -0
  53. moleditpy_linux/modules/zoomable_view.py +129 -0
  54. moleditpy_linux-2.4.1.dist-info/METADATA +954 -0
  55. moleditpy_linux-2.4.1.dist-info/RECORD +59 -0
  56. moleditpy_linux-2.4.1.dist-info/WHEEL +5 -0
  57. moleditpy_linux-2.4.1.dist-info/entry_points.txt +2 -0
  58. moleditpy_linux-2.4.1.dist-info/licenses/LICENSE +674 -0
  59. moleditpy_linux-2.4.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ MoleditPy — A Python-based molecular editing software
6
+
7
+ Author: Hiromichi Yokoyama
8
+ License: GPL-3.0 license
9
+ Repo: https://github.com/HiroYokoyama/python_molecular_editor
10
+ DOI: 10.5281/zenodo.17268532
11
+ """
12
+
13
+ from PyQt6.QtWidgets import (
14
+ QGraphicsView
15
+ )
16
+
17
+
18
+ from PyQt6.QtCore import (
19
+ Qt, QPointF, QEvent
20
+ )
21
+
22
+ class ZoomableView(QGraphicsView):
23
+ """ マウスホイールでのズームと、中ボタン or Shift+左ドラッグでのパン機能を追加したQGraphicsView """
24
+ def __init__(self, scene, parent=None):
25
+ super().__init__(scene, parent)
26
+ self.setTransformationAnchor(QGraphicsView.ViewportAnchor.AnchorUnderMouse)
27
+ self.setResizeAnchor(QGraphicsView.ViewportAnchor.AnchorViewCenter)
28
+ self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
29
+ self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
30
+ self.setDragMode(QGraphicsView.DragMode.NoDrag)
31
+
32
+ self.main_window = parent
33
+ self.setAcceptDrops(False)
34
+
35
+ self._is_panning = False
36
+ self._pan_start_pos = QPointF()
37
+ self._pan_start_scroll_h = 0
38
+ self._pan_start_scroll_v = 0
39
+
40
+ def wheelEvent(self, event):
41
+ """ マウスホイールを回した際のイベント """
42
+ if event.modifiers() & Qt.KeyboardModifier.ControlModifier:
43
+ zoom_in_factor = 1.1
44
+ zoom_out_factor = 1 / zoom_in_factor
45
+
46
+ transform = self.transform()
47
+ current_scale = transform.m11()
48
+ min_scale, max_scale = 0.05, 20.0
49
+
50
+ if event.angleDelta().y() > 0:
51
+ if max_scale > current_scale:
52
+ self.scale(zoom_in_factor, zoom_in_factor)
53
+ else:
54
+ if min_scale < current_scale:
55
+ self.scale(zoom_out_factor, zoom_out_factor)
56
+
57
+ event.accept()
58
+ else:
59
+ super().wheelEvent(event)
60
+
61
+ def mousePressEvent(self, event):
62
+ """ 中ボタン or Shift+左ボタンが押されたらパン(視点移動)モードを開始 """
63
+ is_middle_button = event.button() == Qt.MouseButton.MiddleButton
64
+ is_shift_left_button = (event.button() == Qt.MouseButton.LeftButton and
65
+ event.modifiers() & Qt.KeyboardModifier.ShiftModifier)
66
+
67
+ if is_middle_button or is_shift_left_button:
68
+ self._is_panning = True
69
+ self._pan_start_pos = event.pos() # ビューポート座標で開始点を記録
70
+ # 現在のスクロールバーの位置を記録
71
+ self._pan_start_scroll_h = self.horizontalScrollBar().value()
72
+ self._pan_start_scroll_v = self.verticalScrollBar().value()
73
+ self.setCursor(Qt.CursorShape.ClosedHandCursor)
74
+ event.accept()
75
+ else:
76
+ super().mousePressEvent(event)
77
+
78
+ def mouseMoveEvent(self, event):
79
+ """ パンモード中にマウスを動かしたら、スクロールバーを操作して視点を移動させる """
80
+ if self._is_panning:
81
+ delta = event.pos() - self._pan_start_pos # マウスの移動量を計算
82
+ # 開始時のスクロール位置から移動量を引いた値を新しいスクロール位置に設定
83
+ self.horizontalScrollBar().setValue(self._pan_start_scroll_h - delta.x())
84
+ self.verticalScrollBar().setValue(self._pan_start_scroll_v - delta.y())
85
+ event.accept()
86
+ else:
87
+ super().mouseMoveEvent(event)
88
+
89
+ def mouseReleaseEvent(self, event):
90
+ """ パンに使用したボタンが離されたらパンモードを終了 """
91
+ # パンを開始したボタン(中 or 左)のどちらかが離されたかをチェック
92
+ is_middle_button_release = event.button() == Qt.MouseButton.MiddleButton
93
+ is_left_button_release = event.button() == Qt.MouseButton.LeftButton
94
+
95
+ if self._is_panning and (is_middle_button_release or is_left_button_release):
96
+ self._is_panning = False
97
+ # 現在の描画モードに応じたカーソルに戻す
98
+ current_mode = self.scene().mode if self.scene() else 'select'
99
+ if current_mode == 'select':
100
+ self.setCursor(Qt.CursorShape.ArrowCursor)
101
+ elif current_mode.startswith(('atom', 'bond', 'template')):
102
+ self.setCursor(Qt.CursorShape.CrossCursor)
103
+ elif current_mode.startswith(('charge', 'radical')):
104
+ self.setCursor(Qt.CursorShape.CrossCursor)
105
+ else:
106
+ self.setCursor(Qt.CursorShape.ArrowCursor)
107
+ event.accept()
108
+ else:
109
+ super().mouseReleaseEvent(event)
110
+
111
+ def viewportEvent(self, event):
112
+ """ Macのトラックパッドなどのネイティブジェスチャー(ピンチ)に対応 """
113
+ if event.type() == QEvent.Type.NativeGesture:
114
+ # ピンチズーム(ZoomNativeGesture)の場合
115
+ if event.gestureType() == Qt.NativeGestureType.ZoomNativeGesture:
116
+ # event.value() は拡大縮小の倍率差分を返します
117
+ # 例: 拡大時は正の値、縮小時は負の値
118
+ factor = 1.0 + event.value()
119
+
120
+ # 既存の最大・最小スケール制限を考慮する場合(オプション)
121
+ current_scale = self.transform().m11()
122
+ min_scale, max_scale = 0.05, 20.0
123
+
124
+ # 制限内であればスケールを適用
125
+ # (厳密に制限を守るならif文でガードしますが、最小実装としては以下で動作します)
126
+ self.scale(factor, factor)
127
+ return True
128
+
129
+ return super().viewportEvent(event)