From 026e312b0ba36569daf2457eeda0e7a46562cf07 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:09:34 -0500 Subject: [PATCH 01/67] general --- QtPyHammer/ui/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 62dc60c..86c658a 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -12,7 +12,7 @@ class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(QtWidgets.QMainWindow, self).__init__(parent) global current_dir - self.setWindowTitle("QtPyHammer") + self.setWindowTitle("QtPyHammer - Fork") self.setMinimumSize(640, 480) self.setTabPosition(QtCore.Qt.TopDockWidgetArea, QtWidgets.QTabWidget.North) self.tabs = QtWidgets.QTabWidget() @@ -288,8 +288,8 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) self.setMenuBar(self.main_menu) # TOOLBARS - # key_tools = QtWidgets.QToolBar("Tools 1") - # key_tools.setMovable(False) + key_tools = QtWidgets.QToolBar("Tools") + key_tools.setMovable(False) # button_1 = QtWidgets.QToolButton() # need icons (.png) # button_1.setToolTip("Toggle 2D grid visibility") # key_tools.addWidget(button_1) From c5014655e510ee28a0024d86f1f789cb75068035 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 Apr 2024 17:53:23 -0500 Subject: [PATCH 02/67] Core --- .gitignore | 1 + QtPyHammer/ui/core.py | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b089495..d023678 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,4 @@ dmypy.json # Visual Studio Code settings .vscode/ +/.vs diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 86c658a..fe1bbdc 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -259,7 +259,8 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["Help/About QPH"].triggered.connect(lambda: open_url(QtCore.QUrl( "https://github.com/snake-biscuits/QtPyHammer/wiki"))) self.actions["Help/About Qt"] = help_menu.addAction("About Qt") - self.actions["Help/About Qt"].setEnabled(False) + self.actions["Help/About Qt"].triggered.connect(lambda: open_url(QtCore.QUrl( + "https://github.com/spyder-ide/qtpy"))) # self.actions["Help/About Qt"].triggered.connect(ui. #QDialog self.actions["Help/License"] = help_menu.addAction("License") self.actions["Help/License"].setEnabled(False) @@ -271,8 +272,6 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["Help/VDC"] = help_menu.addAction("Valve Developer Community") self.actions["Help/VDC"].triggered.connect(lambda: open_url(QtCore.QUrl( "https://developer.valvesoftware.com/wiki/Main_Page"))) - self.actions["Help/TF2Maps"] = help_menu.addAction("TF2Maps.net") - self.actions["Help/TF2Maps"].triggered.connect(lambda: open_url(QtCore.QUrl("https://tf2maps.net"))) # attach all actions to hotkeys app = QtWidgets.QApplication.instance() From dc12cfa5c69910586a251636dafd2a6f2112d25b Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 Apr 2024 18:00:27 -0500 Subject: [PATCH 03/67] stop the cap --- QtPyHammer/ops/vmf.py | 2 +- QtPyHammer/ui/workspace.py | 2 - QtPyHammer/utilities/raycast.py | 86 --------------------------------- 3 files changed, 1 insertion(+), 89 deletions(-) delete mode 100644 QtPyHammer/utilities/raycast.py diff --git a/QtPyHammer/ops/vmf.py b/QtPyHammer/ops/vmf.py index 2d46017..45b2ed1 100644 --- a/QtPyHammer/ops/vmf.py +++ b/QtPyHammer/ops/vmf.py @@ -14,7 +14,7 @@ def __init__(self, parent, vmf_filename): self.parent.viewport.render_manager.add_brushes(*self.brushes) # track changes with CRDT for Undo & Redo # add entities - self.hidden = self._vmf.hidden + #self.hidden = self._vmf.hidden TODO:vmf_tool does not support hidden objects # TODO: apply hide to render_manager # TODO: inform hide related UI if anything is hidden diff --git a/QtPyHammer/ui/workspace.py b/QtPyHammer/ui/workspace.py index 1aa30dd..24c375f 100644 --- a/QtPyHammer/ui/workspace.py +++ b/QtPyHammer/ui/workspace.py @@ -5,7 +5,6 @@ from . import viewport from ..ops.vmf import VmfInterface -from ..utilities import raycast class SELECTION_MODE(enum.Enum): @@ -28,7 +27,6 @@ def __init__(self, vmf_path, new=True, parent=None): layout = QtWidgets.QVBoxLayout() # holds the viewport # ^ 2 QSplitter(s) will be used for quad viewports self.viewport = viewport.MapViewport3D(self) - self.viewport.raycast.connect(self.select) # self.viewport.setViewMode.connect(...) self.viewport.setFocus() # not working as intended layout.addWidget(self.viewport) diff --git a/QtPyHammer/utilities/raycast.py b/QtPyHammer/utilities/raycast.py deleted file mode 100644 index 9cbef1a..0000000 --- a/QtPyHammer/utilities/raycast.py +++ /dev/null @@ -1,86 +0,0 @@ -from typing import Dict, List - -from . import physics -from . import vector - - -class Ray: - origin: vector.vec3 - direction: vector.vec3 - length: float - - def __init__(self, origin, direction, length): - self.origin = origin - self.direction = direction - self.length = length - - def plane_intersect(self, plane: physics.Plane): - alignment = vector.dot(plane.normal, self.direction) - if alignment > 0: # skip backfaces - return None # no intersection - # similar method to utilities.solid.clip - origin_distance = vector.dot(plane.normal, self.origin) - plane.distance - end_distance = vector.dot(plane.normal, self.end) - plane.distance - origin_is_behind = bool(origin_distance < 0.01) - end_is_behind = bool(end_distance < 0.01) - if not origin_is_behind and end_is_behind: - t = origin_distance / (origin_distance - end_distance) - return t # lerp(self.origin, self.end, t) for coordinates - # t is great for sorting by intersect depth - - -def raycast_brushes(ray: Ray, brushes: List[object]) -> Dict[int, tuple]: - intersections = dict() - # ^ distance: ("brush", brush.id, brush.face.id) - # -- distance: (type, major_id, minor_id) - # if distance is already in intersection: - # -- z-fighting, special case! (need a margin of error) - for brush in brushes: - - probable_intersections = dict() # just this brush - # ^ {distance(t): face.id} - for face in brush.faces: - plane = physics.Plane(*face.plane) - t = Ray.plane_intersect(plane) - if t is not None: - probable_intersections[t] = face.id - - # check if any probable intersection actually touches the solid - for t, face_id in probable_intersections.items(): - P = vector.lerp(ray.origin, ray.end, t) - valid = True - for face in brush.faces: - if face.id == face_id: - continue # skip yourself, we're checking against all others - other_plane = physics.Plane(*face.plane) - if (vector.dot(other_plane.normal, P) - other_plane.distance) > -0.01: - valid = False # P is floating outside the brush - break - if valid: - brush_t = min(probable_intersections.keys()) - intersections[brush_t] = ("brush", brush.id, face_id) # Renderable.uuid - return intersections - - -def raycast(ray: Ray, map_file): - """Get the object hit by ray""" - intersections = dict() - # ^ distance: ("brush", brush.id, brush.face.id) - # -- distance: (type, major_id, minor_id) - # if distance is already in intersection: - # -- z-fighting, special case! - # TODO: only check against visible / selectable brushes - selectable_brushes = [b for b in map_file.brushes if b.id not in map_file.hidden["brushes"]] - intersections.update(raycast_brushes(ray, selectable_brushes)) - - if len(intersections) == 0: - return None # no intersections, move on - - closest = min(intersections.keys()) # smallest t - # TODO: if other distances are close, give a pop-up list; like Blender alt+select - selected = intersections[closest] - # TODO: selection mode - # -- do we want this object's group?, only the selected face? - # TODO: modifier keys, add to selection? subtract? new selection? - - return selected # let the caller deal with selection mode From bf554784877b1b613492ba8c95af029ba3ea940f Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 Apr 2024 18:04:22 -0500 Subject: [PATCH 04/67] La toolbar --- QtPyHammer/ui/core.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index fe1bbdc..c1996df 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -289,21 +289,15 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # TOOLBARS key_tools = QtWidgets.QToolBar("Tools") key_tools.setMovable(False) - # button_1 = QtWidgets.QToolButton() # need icons (.png) - # button_1.setToolTip("Toggle 2D grid visibility") - # key_tools.addWidget(button_1) - # button_2 = QtWidgets.QToolButton() - # button_2.setToolTip("Toggle 3D grid visibility") - # key_tools.addWidget(button_2) - # button_3 = QtWidgets.QToolButton() - # button_3.setToolTip("Grid scale - [") - # key_tools.addWidget(button_3) - # button_3 = QtWidgets.QToolButton() - # button_3.setDefaultAction(...) # shortcut "]" - # key_tools.addWidget(button_3) - # key_tools.addSeparator() + button_1 = QtWidgets.QToolButton() # need icons (.png) + button_1.setToolTip("Toggle 2D grid visibility") + key_tools.addWidget(button_1) + button_2 = QtWidgets.QToolButton() + button_2.setToolTip("Toggle 3D grid visibility") + key_tools.addWidget(button_2) + key_tools.addSeparator() - # self.addToolBar(QtCore.Qt.TopToolBarArea, key_tools) + self.addToolBar(QtCore.Qt.TopToolBarArea, key_tools) # undo redo | carve | group ungroup ignore | hide unhide alt-hide | # cut copy paste | cordon | TL | DD 3D DW DA | # compile helpers 2D_models fade CM prop_detail NO_DRAW From 05f6236a2953912672584fefeb50a96df9e4495d Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 18 Apr 2024 19:31:17 -0500 Subject: [PATCH 05/67] Icons! --- QtPyHammer/ui/core.py | 3 +++ icons/2DHammerIcon.png | Bin 0 -> 912 bytes icons/3DHammerIcon.png | Bin 0 -> 916 bytes 3 files changed, 3 insertions(+) create mode 100644 icons/2DHammerIcon.png create mode 100644 icons/3DHammerIcon.png diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index c1996df..0476f66 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -2,6 +2,7 @@ import os from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5.QtGui import QIcon from .. import ops from ..ui import entity @@ -291,9 +292,11 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) key_tools.setMovable(False) button_1 = QtWidgets.QToolButton() # need icons (.png) button_1.setToolTip("Toggle 2D grid visibility") + button_1.setIcon(QIcon("icons/2dHammerIcon")) key_tools.addWidget(button_1) button_2 = QtWidgets.QToolButton() button_2.setToolTip("Toggle 3D grid visibility") + button_2.setIcon(QIcon("icons/3dHammerIcon")) key_tools.addWidget(button_2) key_tools.addSeparator() diff --git a/icons/2DHammerIcon.png b/icons/2DHammerIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..52d721292c33935bfb6a5483a66e8d109084bbbc GIT binary patch literal 912 zcmV;B18@9^P)g2w2!}+U#m>dKcY9&?a(jEXw;v2Qv+vE^ zyxn>4&FqS*GAxXwJ%L^_RK|{mT@;ZSUbkmd7 zfF~~3cFJSZjup+jjeqJ1^V5zd=OVdXB|DeAahE6NK6iWI_r?iRBiL)Fel89@ymyH` zUuf)jO!%*j^zbt0JPNl$@*-B3t(QTG_rQ`()*i{*#?F?UOEzH5R6j zwy`}WH#Vyzl4o6z`PlV=FM+DcP(9h)*sPM&LEr@V5<%}a!B>X{e}E(46qq3Rvfy(J ze0TNxM)n){=IZx=Yc2nl>W3y+r}@lV14>R-qV-I??De&>BTu$(<-I!3_6>JCPL?x=h=*s8=F;<^4S6~A3=4F=6qQP-V@~70`Sb} z?*dgRd*#fW}LG__&j{_AEnWr@e1I)Rx!?+#lw$ zbY6L$%_u`aJYGIB?Z#EAR_ABbb}rRq|J<`4KMz^qaAvU(CBjl6&JQd@$`gfzRT8H;laM m)!)#(KmO{~*MJ9RT>b%7G=d)DZ%J?f0000N*U@-mxQLYx7*m{U0 zwbfas%pYKrAcAeu*$F}IZ0_Lff)I(7+FSw#6GV9yH!E{A@vh;&3mO>2tCqGw#q8slr*BC;wX)zO%e0#(H< zNEM(7XiQs)#+vc9gt2a0wCCp0Y{geIC|o_Fp$gRUG;{($L@IzCo@=Tqz#}IB77`*u zq6S3?%CPwM8M`5;7&g6M>5!nK!tV{1y^@)+a0`6O~ zLsh+LWOZQKp?j#R?Ks|C4FzsE=Xad`wU~J`9@%sfZ(%~WG<4h$B)y188@N4m;-lkN zD34C34;d+>Frix*Lqp}!X2x-DF8mFAGyN;TSx5fW952%Udi($mV|Wkp{i5jq5NKPn zwkx+}%bvOONxWs~9tR>a%h6We^CB`I^*y|iY{oNpRz%`>&xOjPTfkM|Ps&jDVf+Pt zn*Ie~(vk0(;}pF`JHWnmKbQ9))M7M+$0HdqNpd74$rA5Zn0K@=hK35=7r?Cy;~qQb zyTBXMe?WJ4(#C6ZoTa~(ehYk$;q8=pbleaskJj<$x-?uCk>#lG;f-YTp1E}^&$_r2 zDv$0Ezu%Jw4hj>xrJ>`7Q158gqW-;ez70Gz{g-tAm}TRhIo9dVmCxv=Bp>hRAggY) zW1a@j*T%l8elW6q4{s!!_t3R1xhpHqVpMK-9uwtuXI?0bq2+dG`I&Y~Q5Zw>{%ODE q=e*bV^NpiUG*ve0000 Date: Thu, 18 Apr 2024 20:34:13 -0500 Subject: [PATCH 06/67] More missing buttons --- QtPyHammer/ui/core.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 0476f66..de479f7 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -4,6 +4,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtGui import QIcon + from .. import ops from ..ui import entity from ..ui import workspace @@ -11,6 +12,8 @@ class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): + + super(QtWidgets.QMainWindow, self).__init__(parent) global current_dir self.setWindowTitle("QtPyHammer - Fork") @@ -298,6 +301,26 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) button_2.setToolTip("Toggle 3D grid visibility") button_2.setIcon(QIcon("icons/3dHammerIcon")) key_tools.addWidget(button_2) + button_3 = QtWidgets.QToolButton() + button_3.setToolTip("Smaller Grid") + key_tools.addWidget(button_3) + button_4 = QtWidgets.QToolButton() + button_4.setToolTip("Larger Grid") + key_tools.addWidget(button_4) + key_tools.addSeparator() + button_5= QtWidgets.QToolButton() + button_5.setToolTip("Load Window State") + key_tools.addWidget(button_5) + button_6= QtWidgets.QToolButton() + button_6.setToolTip("Save Window State") + key_tools.addWidget(button_6) + key_tools.addSeparator() + button_7= QtWidgets.QToolButton() + button_7.setToolTip("Undo") + key_tools.addWidget(button_7) + button_8= QtWidgets.QToolButton() + button_8.setToolTip("Redo") + key_tools.addWidget(button_8) key_tools.addSeparator() self.addToolBar(QtCore.Qt.TopToolBarArea, key_tools) From 172e8d3040b52728a50a3a524c1f272a74ef9c96 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:17:02 -0500 Subject: [PATCH 07/67] Large Grid Icon --- QtPyHammer/ui/core.py | 1 + icons/LargeGridIcon.png | Bin 0 -> 707 bytes 2 files changed, 1 insertion(+) create mode 100644 icons/LargeGridIcon.png diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index de479f7..a2ae1b8 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -306,6 +306,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) key_tools.addWidget(button_3) button_4 = QtWidgets.QToolButton() button_4.setToolTip("Larger Grid") + button_4.setIcon(QIcon("icons/LargeGridIcon")) key_tools.addWidget(button_4) key_tools.addSeparator() button_5= QtWidgets.QToolButton() diff --git a/icons/LargeGridIcon.png b/icons/LargeGridIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..ea31ad76c1d2a113e88ef147ea3339c7571addea GIT binary patch literal 707 zcmV;!0zCbRP)@IcWg0?>JzKW67oCnodlB2Pa9F2|SXlx`$ zV`F6;UD#RI>`i*WyM^5BU;3-?iB1py=^c%TX@s`OFwIV({TZ&?04@e?Ux4G1*Z;Ej zUWUMXTZ>0!&`I&AMshSZlB2PayS*4=dM*R!vn?WHr@sK!Jnf^1>^SW)aKqCkA~Gyv zw=RnIQ9Gb}LEA2n4d_9jb%7mMe+XO-^kGT6wUFM?*jSy#$Qbh+xT9zrO4}=AOx_vu znlWbN>X$;%(=@wRtA52$m9}&8X36WW6liBpuv4V1pWc;Xmf=e#%MVwW^`R_-qr1wq z9_94SrS0Oi#v+5xcpiIfOGIvohzSeuRO#Q(`YGDJryYc%r)hR8e?nDB`)G`OurupF zm!VDR)LB|V1QIRj9gPjUkA4O^ieDF$_HW(^C5$(J0$*KyQ#p)eTaIS8Y>swz@)iIa z^(zZh&(lL~$QNZq7;G`6Xm(w#a>o9;~8OKh~7p6;9% pDcu Date: Fri, 19 Apr 2024 11:43:59 -0500 Subject: [PATCH 08/67] Edit Toolbar --- QtPyHammer/ui/core.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index a2ae1b8..475f4e9 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -329,6 +329,10 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # cut copy paste | cordon | TL | DD 3D DW DA | # compile helpers 2D_models fade CM prop_detail NO_DRAW + edit_tools = QtGui.QToolBar("Edit Tools") + edit_tools.setMovable(True) + self.addToolBar(QtCore.Qt.LeftToolBarArea, toolbarBox) + def open(self, filename): # allows loading via drag & drop raw_filename, extension = os.path.splitext(filename) short_filename = os.path.basename(filename) From f7bdf8b6dc42ee12f7843a55402e8ecfce3f993a Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 11:56:38 -0500 Subject: [PATCH 09/67] Button --- QtPyHammer/ui/core.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 475f4e9..0e88353 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -331,6 +331,9 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) edit_tools = QtGui.QToolBar("Edit Tools") edit_tools.setMovable(True) + edit_button_1 = QtWidgets.QToolButton() # need icons (.png) + edit_button_1.setToolTip("Selection Tool") + edit_tools.addWidget(edit_button_1) self.addToolBar(QtCore.Qt.LeftToolBarArea, toolbarBox) def open(self, filename): # allows loading via drag & drop From c52d75008185662b30cefcbb4deca81836e2b9c5 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:22:13 -0500 Subject: [PATCH 10/67] Revert "Button" This reverts commit f7bdf8b6dc42ee12f7843a55402e8ecfce3f993a. --- QtPyHammer/ui/core.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 0e88353..475f4e9 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -331,9 +331,6 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) edit_tools = QtGui.QToolBar("Edit Tools") edit_tools.setMovable(True) - edit_button_1 = QtWidgets.QToolButton() # need icons (.png) - edit_button_1.setToolTip("Selection Tool") - edit_tools.addWidget(edit_button_1) self.addToolBar(QtCore.Qt.LeftToolBarArea, toolbarBox) def open(self, filename): # allows loading via drag & drop From b682467b5cfe35d2ccc0465b3e87b247498e9504 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:22:22 -0500 Subject: [PATCH 11/67] Revert "Edit Toolbar" This reverts commit 7537bd882de15ed5da4b84776d0909c93c2dbfa0. --- QtPyHammer/ui/core.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 475f4e9..a2ae1b8 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -329,10 +329,6 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # cut copy paste | cordon | TL | DD 3D DW DA | # compile helpers 2D_models fade CM prop_detail NO_DRAW - edit_tools = QtGui.QToolBar("Edit Tools") - edit_tools.setMovable(True) - self.addToolBar(QtCore.Qt.LeftToolBarArea, toolbarBox) - def open(self, filename): # allows loading via drag & drop raw_filename, extension = os.path.splitext(filename) short_filename = os.path.basename(filename) From 5e28b639be1bb794f73b12d39ec8566a4b101e5f Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:23:47 -0500 Subject: [PATCH 12/67] push local --- QtPyHammer/ui/__init__.py | 3 +- QtPyHammer/ui/core.py | 15 +- QtPyHammer/ui/popup.py | 20 +++ QtPyHammer/ui/texture_browser.py | 200 ++++++++++++++++++++++ QtPyHammer/ui/viewport.py | 2 +- README.md | 20 +-- Team Fortress 2/tf/mapsrc/smeagletest.vmf | 36 ++++ 7 files changed, 278 insertions(+), 18 deletions(-) create mode 100644 QtPyHammer/ui/popup.py create mode 100644 QtPyHammer/ui/texture_browser.py create mode 100644 Team Fortress 2/tf/mapsrc/smeagletest.vmf diff --git a/QtPyHammer/ui/__init__.py b/QtPyHammer/ui/__init__.py index 5606c66..31e1d52 100644 --- a/QtPyHammer/ui/__init__.py +++ b/QtPyHammer/ui/__init__.py @@ -3,6 +3,7 @@ from . import user_preferences from . import viewport from . import workspace +from . import popup -__all__ = ["core", "entity", "user_preferences", "viewport", "workspace"] +__all__ = ["core", "entity", "user_preferences", "viewport", "workspace", "popup"] diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index a2ae1b8..6d8f3fa 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -6,7 +6,7 @@ from .. import ops -from ..ui import entity +from ..ui import entity, popup, texture_browser from ..ui import workspace @@ -46,6 +46,12 @@ def save_file(): ops.save_file(self, self.map_browser) self.actions["File/Save As"] = file_menu.addAction("Save &As") def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["File/Save As"].triggered.connect(save_file_as) + self.actions["File/Error Test"] = file_menu.addAction("Example Popup (for testing)") + error_popup = popup.browser(parent=self) + self.actions["File/Error Test"].triggered.connect(error_popup.show) + self.actions["File/Texture Test"] = file_menu.addAction("Texture Menu (for testing)") + texture_popup = texture_browser.TextureBrowser(parent=self) + self.actions["File/Texture Test"].triggered.connect(texture_popup.show) file_menu.addSeparator() # self.import_menu = file_menu.addMenu("Import") # self.import_menu.addAction(".obj") @@ -117,8 +123,8 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) ent_browser = entity.browser(parent=self) self.actions["Tools/Brush to Entity"].triggered.connect(ent_browser.show) except Exception as exc: - # log the full exception for debug - print("Failed to load .fgds!") # use the builtin logger module + error_popup = popup.browser(parent=self) + self.actions["Tools/Brush to Entity"].triggered.connect(error_popup.show) self.actions["Tools/Brush to Entity"].setEnabled(False) raise exc self.actions["Tools/Entity to Brush"] = tools_menu.addAction("&Move to World") @@ -267,7 +273,8 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) "https://github.com/spyder-ide/qtpy"))) # self.actions["Help/About Qt"].triggered.connect(ui. #QDialog self.actions["Help/License"] = help_menu.addAction("License") - self.actions["Help/License"].setEnabled(False) + self.actions["Help/License"].triggered.connect(lambda: open_url(QtCore.QUrl( + "https://github.com/strubium/QtPyHammer/blob/master/LICENSE"))) # self.actions["Help/License"].triggered.connect(ui. #QDialog self.actions["Help/Contributors"] = help_menu.addAction("Contributors") self.actions["Help/Contributors"].setEnabled(False) diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py new file mode 100644 index 0000000..6e5a5a0 --- /dev/null +++ b/QtPyHammer/ui/popup.py @@ -0,0 +1,20 @@ +from PyQt5 import QtCore, QtGui, QtWidgets + +class browser(QtWidgets.QDialog): + def __init__(self, parent): + super(browser, self).__init__(parent, QtCore.Qt.Tool) + self.setWindowTitle("Popup") + # self.setWindowIcon(parent.entity_icon) + self.setGeometry(780, 220, 360, 640) + app = QtWidgets.QApplication.instance() + self.base_widget = QtWidgets.QTabWidget() + base_layout = QtWidgets.QVBoxLayout() + base_layout.addWidget(self.base_widget) + bottom_row = QtWidgets.QHBoxLayout() + bottom_row.addStretch(1) + ok_button = QtWidgets.QPushButton("Ok") + ok_button.clicked.connect(self.accept) + ok_button.setDefault(True) + bottom_row.addWidget(ok_button) + base_layout.addLayout(bottom_row) + self.setLayout(base_layout) \ No newline at end of file diff --git a/QtPyHammer/ui/texture_browser.py b/QtPyHammer/ui/texture_browser.py new file mode 100644 index 0000000..a39bb90 --- /dev/null +++ b/QtPyHammer/ui/texture_browser.py @@ -0,0 +1,200 @@ +import sys + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class TextureBrowser(QtWidgets.QDialog): + # https://doc.qt.io/qt-5/qdialog.html + def __init__(self, parent=None): + super().__init__(parent) + # pick a layout for the core widget + # top has a scrolling page of texture thumbnails + # bottom has filters, self.searchbar, OK & Cancel buttons + + main_layout = QtWidgets.QVBoxLayout() + self.setWindowTitle("Texture Browser") + self.setGeometry(780, 220, 360, 640) + # now this has scroll bar but it doesnt have flow layout + scroll = QtWidgets.QScrollArea() + groupbox = QtWidgets.QGroupBox("Textures") + flow_layout = FlowLayout(margin=10) + + container = QtWidgets.QWidget() + container_layout = QtWidgets.QVBoxLayout() + + # configure flow layout + flow_layout.heightChanged.connect(container.setMinimumHeight) + for i in range(400): + self.addTextureSquare(flow_layout) + + # set configured layout to the groupbox + groupbox.setLayout(flow_layout) + + container_layout.addWidget(groupbox) + container_layout.addStretch() + container.setLayout(container_layout) + + # configure scrollarea + scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) + + # set configured groupbox as widget of the scrollarea + scroll.setWidget(container) + scroll.setWidgetResizable(True) + + # finally add scrollarea widget to the outer QVBoxLayout + main_layout.addWidget(scroll) + main_layout.addWidget(QtWidgets.QLabel("Search Options")) + # list of checkboxes? + # colour-range (hue) slider (.vtf reflectivity value) + + self.searchbar = QtWidgets.QLineEdit() + main_layout.addWidget(self.searchbar) + + search_button = QtWidgets.QPushButton("Search") + search_button.clicked.connect(lambda: self.search(self.searchbar.text())) + search_button.setDefault(1) + + main_layout.addWidget(search_button) + + buttonbox = QtWidgets.QDialogButtonBox + buttons = buttonbox(buttonbox.Ok | buttonbox.Cancel) + buttons.accepted.connect(self.accept) + buttons.rejected.connect(self.reject) + main_layout.addWidget(buttons) + self.setLayout(main_layout) + + def addTextureSquare(self, layout): + image_label = QtWidgets.QLabel() + # Placeholder Image + magenta = b"\xFF\x00\xFF" + black = b"\x00\x00\x00" + data = magenta + black + black + magenta + + # Parse data into image + image = QtGui.QImage(data, 2, 2, QtGui.QImage.Format_RGB888) + image.setDevicePixelRatio(1 / 32) # scale *32 + image_label.setPixmap(QtGui.QPixmap.fromImage(image)) + + layout.addWidget(image_label) + + def search(self, keyword): + print(f"Trying to Search {keyword}!") + + +class FlowLayout(QtWidgets.QLayout): + """A ``QLayout`` that aranges its child widgets horizontally and + vertically. + + If enough horizontal space is available, it looks like an ``HBoxLayout``, + but if enough space is lacking, it automatically wraps its children into + multiple rows.""" + heightChanged = QtCore.pyqtSignal(int) + + def __init__(self, parent=None, margin=0, spacing=-1): + super().__init__(parent) + if parent is not None: + self.setContentsMargins(margin, margin, margin, margin) + self.setSpacing(spacing) + + self._item_list = [] + + def __del__(self): + while self.count(): + self.takeAt(0) + + def addItem(self, item): + self._item_list.append(item) + + def addSpacing(self, size): + self.addItem(QtWidgets.QSpacerItem(size, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)) + + def count(self): + return len(self._item_list) + + def itemAt(self, index): + if 0 <= index < len(self._item_list): + return self._item_list[index] + return None + + def takeAt(self, index): + if 0 <= index < len(self._item_list): + return self._item_list.pop(index) + return None + + def expandingDirections(self): + return QtCore.Qt.Orientations(QtCore.Qt.Orientation(0)) + + def hasHeightForWidth(self): + return True + + def heightForWidth(self, width): + height = self._do_layout(QtCore.QRect(0, 0, width, 0), True) + return height + + def setGeometry(self, rect): + super().setGeometry(rect) + self._do_layout(rect, False) + + def sizeHint(self): + return self.minimumSize() + + def minimumSize(self): + size = QtCore.QSize() + + for item in self._item_list: + minsize = item.minimumSize() + extent = item.geometry().bottomRight() + size = size.expandedTo(QtCore.QSize(minsize.width(), extent.y())) + + margin = self.contentsMargins().left() + size += QtCore.QSize(2 * margin, 2 * margin) + return size + + def _do_layout(self, rect, test_only=False): + m = self.contentsMargins() + effective_rect = rect.adjusted(+m.left(), +m.top(), -m.right(), -m.bottom()) + x = effective_rect.x() + y = effective_rect.y() + line_height = 0 + + for item in self._item_list: + wid = item.widget() + + space_x = self.spacing() + space_y = self.spacing() + if wid is not None: + space_x += wid.style().layoutSpacing(QtWidgets.QSizePolicy.PushButton, + QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Horizontal) + space_y += wid.style().layoutSpacing(QtWidgets.QSizePolicy.PushButton, + QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Vertical) + + next_x = x + item.sizeHint().width() + space_x + if next_x - space_x > effective_rect.right() and line_height > 0: + x = effective_rect.x() + y = y + line_height + space_y + next_x = x + item.sizeHint().width() + space_x + line_height = 0 + + if not test_only: + item.setGeometry(QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint())) + + x = next_x + line_height = max(line_height, item.sizeHint().height()) + + new_height = y + line_height - rect.y() + self.heightChanged.emit(new_height) + return new_height + + +if __name__ == "__main__": + def except_hook(cls, exception, traceback): + """Get tracebacks for python called by Qt functions & classes""" + sys.__excepthook__(cls, exception, traceback) + + sys.excepthook = except_hook + app = QtWidgets.QApplication(sys.argv) + browser = TextureBrowser() + browser.setGeometry(128, 64, 576, 576) + browser.show() + + app.exec_() diff --git a/QtPyHammer/ui/viewport.py b/QtPyHammer/ui/viewport.py index 3dda92f..e48c780 100644 --- a/QtPyHammer/ui/viewport.py +++ b/QtPyHammer/ui/viewport.py @@ -72,7 +72,7 @@ def initializeGL(self): app = QtWidgets.QApplication.instance() shader_folder = os.path.join(app.folder, f"shaders/{self.shader_version}/") self.render_manager.initialise(shader_folder) - self.set_view_mode("flat") # sets shaders & GL state + self.set_view_mode("textured") # sets shaders & GL state self.timer.start() # calling the slot by it's name creates a QVariant Error diff --git a/README.md b/README.md index 925ae40..f8e3845 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,17 @@ -[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=QtPyHammer-devs_QtPyHammer&metric=ncloc)](https://sonarcloud.io/dashboard?id=QtPyHammer-devs_QtPyHammer) -[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=QtPyHammer-devs_QtPyHammer&metric=bugs)](https://sonarcloud.io/dashboard?id=QtPyHammer-devs_QtPyHammer) -[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=QtPyHammer-devs_QtPyHammer&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=QtPyHammer-devs_QtPyHammer) -[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=QtPyHammer-devs_QtPyHammer&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=QtPyHammer-devs_QtPyHammer) - -# QtPyHammer -A Python alternative to Valve's Hammer Editor (4.X in particular) +# QtPyHammer - Fork +A Python alternative to Valve Hammer Editor 4.x, forked from https://github.com/QtPyHammer-devs/QtPyHammer # Creating the dev environment It's recommended to use a python virtual environment to preserve the version of dependencies, here's how you do that: First, open a terminal in the QtPyHammer-master folder (the top level!) Then, create a new python(3.8+) virtual environment -(Linux users may need to install python-venv first) -`$ python -m venv venv` -Activate your new virtual environment -Windows: `$ call venv/scripts/activate` -Mac / Linux: `$ source venv/bin/activate` +(Linux users may need to install python-venv first `$ python -m venv venv` ) + +## Activate your new virtual environment +* Windows: `$ call venv/scripts/activate` +* Mac / Linux: `$ source venv/bin/activate` + Finally, install all dependencies with pip `$ python -m pip install -r requirements.txt` diff --git a/Team Fortress 2/tf/mapsrc/smeagletest.vmf b/Team Fortress 2/tf/mapsrc/smeagletest.vmf new file mode 100644 index 0000000..4676f6f --- /dev/null +++ b/Team Fortress 2/tf/mapsrc/smeagletest.vmf @@ -0,0 +1,36 @@ +versioninfo +{ + "editorversion" "400" + "editorbuild" "7803" + "mapversion" "0" + "formatversion" "100" + "prefab" "0" +} +viewsettings +{ + "bSnapToGrid" "1" + "bShowGrid" "1" + "bShowLogicalGrid" "0" + "nGridSpacing" "64" + "bShow3DGrid" "0" +} +world +{ + "id" "1" + "mapversion" "0" + "classname" "worldspawn" + "skyname" "sky_tf2_04" + "maxpropscreenwidth" "-1" + "detailvbsp" "detail_2fort.vbsp" + "detailmaterial" "detail/detailsprites_2fort" +} +cameras +{ + "activecamera" "-1" +} +cordon +{ + "mins" "(-1024 -1024 -1024)" + "maxs" "(1024 1024 1024)" + "active" "0" +} From bd0793fab94248b6bf061d37734a3a0b1efc6019 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:41:19 -0500 Subject: [PATCH 13/67] Popup system works! --- QtPyHammer/ui/core.py | 2 +- QtPyHammer/ui/popup.py | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 6d8f3fa..0f5f6cd 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -47,7 +47,7 @@ def save_file(): ops.save_file(self, self.map_browser) def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["File/Save As"].triggered.connect(save_file_as) self.actions["File/Error Test"] = file_menu.addAction("Example Popup (for testing)") - error_popup = popup.browser(parent=self) + error_popup = popup.browser(parent=self,text="woow") self.actions["File/Error Test"].triggered.connect(error_popup.show) self.actions["File/Texture Test"] = file_menu.addAction("Texture Menu (for testing)") texture_popup = texture_browser.TextureBrowser(parent=self) diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py index 6e5a5a0..a35214e 100644 --- a/QtPyHammer/ui/popup.py +++ b/QtPyHammer/ui/popup.py @@ -1,15 +1,20 @@ from PyQt5 import QtCore, QtGui, QtWidgets class browser(QtWidgets.QDialog): - def __init__(self, parent): + def __init__(self, parent, text): super(browser, self).__init__(parent, QtCore.Qt.Tool) self.setWindowTitle("Popup") - # self.setWindowIcon(parent.entity_icon) - self.setGeometry(780, 220, 360, 640) - app = QtWidgets.QApplication.instance() - self.base_widget = QtWidgets.QTabWidget() + + # Add QLabel to display text + self.text_label = QtWidgets.QLabel(text) + self.text_label.setAlignment(QtCore.Qt.AlignCenter) # Center align text + self.text_label.setWordWrap(True) # Enable word wrap + self.text_label.setMargin(10) # Add margin to the label + self.text_label.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + + # Layout setup base_layout = QtWidgets.QVBoxLayout() - base_layout.addWidget(self.base_widget) + base_layout.addWidget(self.text_label) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) ok_button = QtWidgets.QPushButton("Ok") @@ -17,4 +22,7 @@ def __init__(self, parent): ok_button.setDefault(True) bottom_row.addWidget(ok_button) base_layout.addLayout(bottom_row) - self.setLayout(base_layout) \ No newline at end of file + self.setLayout(base_layout) + + # Resize the dialog to fit the text + self.adjustSize() \ No newline at end of file From f20acdcc6731e552974dbdb6dbc33c66a7142d8d Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:43:11 -0500 Subject: [PATCH 14/67] Error popup! --- QtPyHammer/ui/core.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 0f5f6cd..4e1da24 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -46,9 +46,6 @@ def save_file(): ops.save_file(self, self.map_browser) self.actions["File/Save As"] = file_menu.addAction("Save &As") def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["File/Save As"].triggered.connect(save_file_as) - self.actions["File/Error Test"] = file_menu.addAction("Example Popup (for testing)") - error_popup = popup.browser(parent=self,text="woow") - self.actions["File/Error Test"].triggered.connect(error_popup.show) self.actions["File/Texture Test"] = file_menu.addAction("Texture Menu (for testing)") texture_popup = texture_browser.TextureBrowser(parent=self) self.actions["File/Texture Test"].triggered.connect(texture_popup.show) @@ -123,7 +120,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) ent_browser = entity.browser(parent=self) self.actions["Tools/Brush to Entity"].triggered.connect(ent_browser.show) except Exception as exc: - error_popup = popup.browser(parent=self) + error_popup = popup.browser(parent=self,text="Failed to load .fgds!") self.actions["Tools/Brush to Entity"].triggered.connect(error_popup.show) self.actions["Tools/Brush to Entity"].setEnabled(False) raise exc From 6752672d4380d14bf7a9f5bfacdc086d16711514 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:29:39 -0500 Subject: [PATCH 15/67] Menu tile --- QtPyHammer/ui/core.py | 2 +- QtPyHammer/ui/popup.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 4e1da24..d87be53 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -120,7 +120,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) ent_browser = entity.browser(parent=self) self.actions["Tools/Brush to Entity"].triggered.connect(ent_browser.show) except Exception as exc: - error_popup = popup.browser(parent=self,text="Failed to load .fgds!") + error_popup = popup.browser(parent=self, popuptext="Error", msgtext="Failed to load .fgds!") self.actions["Tools/Brush to Entity"].triggered.connect(error_popup.show) self.actions["Tools/Brush to Entity"].setEnabled(False) raise exc diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py index a35214e..60e635b 100644 --- a/QtPyHammer/ui/popup.py +++ b/QtPyHammer/ui/popup.py @@ -1,12 +1,12 @@ from PyQt5 import QtCore, QtGui, QtWidgets class browser(QtWidgets.QDialog): - def __init__(self, parent, text): + def __init__(self, parent, popuptext, msgtext): super(browser, self).__init__(parent, QtCore.Qt.Tool) - self.setWindowTitle("Popup") + self.setWindowTitle(popuptext) # Add QLabel to display text - self.text_label = QtWidgets.QLabel(text) + self.text_label = QtWidgets.QLabel(msgtext) self.text_label.setAlignment(QtCore.Qt.AlignCenter) # Center align text self.text_label.setWordWrap(True) # Enable word wrap self.text_label.setMargin(10) # Add margin to the label From 8ba8f9d2720ffa19316c685849e910950100b98e Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:45:48 -0500 Subject: [PATCH 16/67] Popup system 2 --- QtPyHammer/ui/texture_browser.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/QtPyHammer/ui/texture_browser.py b/QtPyHammer/ui/texture_browser.py index a39bb90..abb8a85 100644 --- a/QtPyHammer/ui/texture_browser.py +++ b/QtPyHammer/ui/texture_browser.py @@ -2,6 +2,8 @@ from PyQt5 import QtCore, QtGui, QtWidgets +from ..ui import popup + class TextureBrowser(QtWidgets.QDialog): # https://doc.qt.io/qt-5/qdialog.html @@ -78,8 +80,9 @@ def addTextureSquare(self, layout): layout.addWidget(image_label) def search(self, keyword): - print(f"Trying to Search {keyword}!") - + search_popup = popup.browser(parent=self, popuptext="Notification", msgtext=f"Trying to Search {keyword}!") + search_popup.show() + # TODO: doesnt filter yet class FlowLayout(QtWidgets.QLayout): """A ``QLayout`` that aranges its child widgets horizontally and From 6e5584b1f6c4178f5a1b8b303427584705721ce7 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:55:32 -0500 Subject: [PATCH 17/67] About page get popup too --- QtPyHammer/ui/core.py | 7 +++++-- QtPyHammer/ui/texture_browser.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index d87be53..c6543b8 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -263,8 +263,8 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # self.actions["Help/Offline"].triggered.connect(ui. help_menu.addSeparator() self.actions["Help/About QPH"] = help_menu.addAction("About QtPyHammer") - self.actions["Help/About QPH"].triggered.connect(lambda: open_url(QtCore.QUrl( - "https://github.com/snake-biscuits/QtPyHammer/wiki"))) + about_popup = popup.browser(parent=self, popuptext="About", msgtext="A Python alternative to Valve Hammer Editor 4.x, forked from QtPyHammer\nVersion: v0.0.5forked") + self.actions["Help/About QPH"].triggered.connect(about_popup.show) self.actions["Help/About Qt"] = help_menu.addAction("About Qt") self.actions["Help/About Qt"].triggered.connect(lambda: open_url(QtCore.QUrl( "https://github.com/spyder-ide/qtpy"))) @@ -275,6 +275,9 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # self.actions["Help/License"].triggered.connect(ui. #QDialog self.actions["Help/Contributors"] = help_menu.addAction("Contributors") self.actions["Help/Contributors"].setEnabled(False) + self.actions["Help/QPH Wiki"] = help_menu.addAction("QtPyHammer Wiki") + self.actions["Help/QPH Wiki"].triggered.connect(lambda: open_url(QtCore.QUrl( + "https://github.com/snake-biscuits/QtPyHammer/wiki"))) # self.actions["Help/Contributors"].triggered.connect(ui. #QDialog help_menu.addSeparator() self.actions["Help/VDC"] = help_menu.addAction("Valve Developer Community") diff --git a/QtPyHammer/ui/texture_browser.py b/QtPyHammer/ui/texture_browser.py index abb8a85..edd353c 100644 --- a/QtPyHammer/ui/texture_browser.py +++ b/QtPyHammer/ui/texture_browser.py @@ -80,7 +80,7 @@ def addTextureSquare(self, layout): layout.addWidget(image_label) def search(self, keyword): - search_popup = popup.browser(parent=self, popuptext="Notification", msgtext=f"Trying to Search {keyword}!") + search_popup = popup.browser(parent=self, popuptext="Notification", msgtext=f"Searching for: {keyword}!") search_popup.show() # TODO: doesnt filter yet From b5b9d7e3cb08b99e71412687e7a7f8bf319bad8b Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:02:03 -0500 Subject: [PATCH 18/67] grey out not working buttons --- QtPyHammer/ui/core.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index c6543b8..d447263 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -303,31 +303,39 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) button_1 = QtWidgets.QToolButton() # need icons (.png) button_1.setToolTip("Toggle 2D grid visibility") button_1.setIcon(QIcon("icons/2dHammerIcon")) + button_1.setEnabled(False) key_tools.addWidget(button_1) button_2 = QtWidgets.QToolButton() button_2.setToolTip("Toggle 3D grid visibility") button_2.setIcon(QIcon("icons/3dHammerIcon")) + button_2.setEnabled(False) key_tools.addWidget(button_2) button_3 = QtWidgets.QToolButton() button_3.setToolTip("Smaller Grid") + button_3.setEnabled(False) key_tools.addWidget(button_3) button_4 = QtWidgets.QToolButton() button_4.setToolTip("Larger Grid") button_4.setIcon(QIcon("icons/LargeGridIcon")) + button_4.setEnabled(False) key_tools.addWidget(button_4) key_tools.addSeparator() button_5= QtWidgets.QToolButton() button_5.setToolTip("Load Window State") + button_5.setEnabled(False) key_tools.addWidget(button_5) button_6= QtWidgets.QToolButton() button_6.setToolTip("Save Window State") + button_6.setEnabled(False) key_tools.addWidget(button_6) key_tools.addSeparator() button_7= QtWidgets.QToolButton() button_7.setToolTip("Undo") + button_7.setEnabled(False) key_tools.addWidget(button_7) button_8= QtWidgets.QToolButton() button_8.setToolTip("Redo") + button_8.setEnabled(False) key_tools.addWidget(button_8) key_tools.addSeparator() From 8b2527b8c5511fcb21afdf17a48078b39133f762 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Sat, 20 Apr 2024 14:21:10 -0500 Subject: [PATCH 19/67] Add basic Compile window --- QtPyHammer/ui/__init__.py | 3 ++- QtPyHammer/ui/compile.py | 44 ++++++++++++++++++++++++++++++++++++++ QtPyHammer/ui/core.py | 8 +++---- QtPyHammer/ui/popup.py | 2 +- QtPyHammer/ui/workspace.py | 5 +++-- 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 QtPyHammer/ui/compile.py diff --git a/QtPyHammer/ui/__init__.py b/QtPyHammer/ui/__init__.py index 31e1d52..1d12a58 100644 --- a/QtPyHammer/ui/__init__.py +++ b/QtPyHammer/ui/__init__.py @@ -4,6 +4,7 @@ from . import viewport from . import workspace from . import popup +from . import compile -__all__ = ["core", "entity", "user_preferences", "viewport", "workspace", "popup"] +__all__ = ["core", "entity", "user_preferences", "viewport", "workspace", "popup", "compile"] diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py new file mode 100644 index 0000000..3a0c49e --- /dev/null +++ b/QtPyHammer/ui/compile.py @@ -0,0 +1,44 @@ +from PyQt5 import QtCore, QtGui, QtWidgets + +class browser(QtWidgets.QDialog): + def __init__(self, parent): + super(browser, self).__init__(parent, QtCore.Qt.Tool) + self.setWindowTitle("Run Map") + + # Add QLabel to display text + self.text_label = QtWidgets.QLabel("The Compile Menu is not implemented yet") + self.text_label.setAlignment(QtCore.Qt.AlignCenter) # Center align text + self.text_label.setWordWrap(True) # Enable word wrap + self.text_label.setMargin(10) # Add margin to the label + self.text_label.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + + # Add QLabel widgets + self.box1 = QtWidgets.QLabel() + self.box1.setText("Run BSP") + self.box1.setAlignment(QtCore.Qt.AlignCenter) + + self.box2 = QtWidgets.QLabel() + self.box2.setText("Run VIS") + self.box2.setAlignment(QtCore.Qt.AlignCenter) + + self.box3 = QtWidgets.QLabel() + self.box3.setText("Run RAD") + self.box3.setAlignment(QtCore.Qt.AlignCenter) + + # Layout setup + base_layout = QtWidgets.QVBoxLayout() + base_layout.addWidget(self.text_label) + base_layout.addWidget(self.box1) + base_layout.addWidget(self.box2) + base_layout.addWidget(self.box3) + bottom_row = QtWidgets.QHBoxLayout() + bottom_row.addStretch(1) + ok_button = QtWidgets.QPushButton("Ok") + ok_button.clicked.connect(self.accept) + ok_button.setDefault(True) + bottom_row.addWidget(ok_button) + base_layout.addLayout(bottom_row) + self.setLayout(base_layout) + + # Resize the dialog to fit the text + self.adjustSize() \ No newline at end of file diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index d447263..26be6d6 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -6,7 +6,7 @@ from .. import ops -from ..ui import entity, popup, texture_browser +from ..ui import entity, popup, texture_browser, compile from ..ui import workspace @@ -63,8 +63,8 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # self.actions["File/Options"].triggered.connect(ui.settings) file_menu.addSeparator() self.actions["File/Compile"] = file_menu.addAction("Compile") - self.actions["File/Compile"].setEnabled(False) - # self.actions["File/Compile"].triggered.connect(ui.compile) + compile_menu = compile.browser(parent=self) + self.actions["File/Compile"].triggered.connect(compile_menu.show) file_menu.addSeparator() self.actions["File/Exit"] = file_menu.addAction("Exit") self.actions["File/Exit"].triggered.connect(QtCore.QCoreApplication.quit) @@ -263,7 +263,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # self.actions["Help/Offline"].triggered.connect(ui. help_menu.addSeparator() self.actions["Help/About QPH"] = help_menu.addAction("About QtPyHammer") - about_popup = popup.browser(parent=self, popuptext="About", msgtext="A Python alternative to Valve Hammer Editor 4.x, forked from QtPyHammer\nVersion: v0.0.5forked") + about_popup = popup.browser(parent=self, popuptext="About", msgtext="A Python alternative to Valve Hammer Editor 4.x, forked from QtPyHammer\n\nVersion: v0.0.5forked") self.actions["Help/About QPH"].triggered.connect(about_popup.show) self.actions["Help/About Qt"] = help_menu.addAction("About Qt") self.actions["Help/About Qt"].triggered.connect(lambda: open_url(QtCore.QUrl( diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py index 60e635b..079adbe 100644 --- a/QtPyHammer/ui/popup.py +++ b/QtPyHammer/ui/popup.py @@ -9,7 +9,7 @@ def __init__(self, parent, popuptext, msgtext): self.text_label = QtWidgets.QLabel(msgtext) self.text_label.setAlignment(QtCore.Qt.AlignCenter) # Center align text self.text_label.setWordWrap(True) # Enable word wrap - self.text_label.setMargin(10) # Add margin to the label + self.text_label.setMargin(15) # Add margin to the label self.text_label.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) # Layout setup diff --git a/QtPyHammer/ui/workspace.py b/QtPyHammer/ui/workspace.py index 24c375f..795505b 100644 --- a/QtPyHammer/ui/workspace.py +++ b/QtPyHammer/ui/workspace.py @@ -3,7 +3,7 @@ from PyQt5 import QtWidgets -from . import viewport +from . import viewport, popup from ..ops.vmf import VmfInterface @@ -55,7 +55,8 @@ def save_to_file(self): # - hidden state of objects (visgroups included) self.map_file.save(self.filename) except Exception as exc: - print() + error_popup = popup.browser(parent=self, popuptext="Error", msgtext="Error when saving") + error_popup.show() raise exc print("Saved!") self.never_saved = False From c11cc07da7568db309a61d2ec3aefd86d04179de Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Sat, 20 Apr 2024 14:43:42 -0500 Subject: [PATCH 20/67] Make sure search text isnt empty --- QtPyHammer/ui/texture_browser.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/QtPyHammer/ui/texture_browser.py b/QtPyHammer/ui/texture_browser.py index edd353c..fefed6f 100644 --- a/QtPyHammer/ui/texture_browser.py +++ b/QtPyHammer/ui/texture_browser.py @@ -80,9 +80,13 @@ def addTextureSquare(self, layout): layout.addWidget(image_label) def search(self, keyword): - search_popup = popup.browser(parent=self, popuptext="Notification", msgtext=f"Searching for: {keyword}!") - search_popup.show() - # TODO: doesnt filter yet + if not keyword: + error_popup = popup.browser(parent=self, popuptext="Error", msgtext="Search text cannot be empty") + error_popup.show() + else: + search_popup = popup.browser(parent=self, popuptext="Notification", msgtext=f"Searching for: {keyword}!") + search_popup.show() + # TODO: doesnt filter yet class FlowLayout(QtWidgets.QLayout): """A ``QLayout`` that aranges its child widgets horizontally and From e14c355494b41ed5e75c9efa26530edd7108176f Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:59:54 -0500 Subject: [PATCH 21/67] New right toolbar --- .gitignore | 1 + QtPyHammer/ui/core.py | 32 +++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index d023678..3800025 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,4 @@ dmypy.json # Visual Studio Code settings .vscode/ /.vs +/.idea diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 26be6d6..893d93a 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -46,9 +46,6 @@ def save_file(): ops.save_file(self, self.map_browser) self.actions["File/Save As"] = file_menu.addAction("Save &As") def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["File/Save As"].triggered.connect(save_file_as) - self.actions["File/Texture Test"] = file_menu.addAction("Texture Menu (for testing)") - texture_popup = texture_browser.TextureBrowser(parent=self) - self.actions["File/Texture Test"].triggered.connect(texture_popup.show) file_menu.addSeparator() # self.import_menu = file_menu.addMenu("Import") # self.import_menu.addAction(".obj") @@ -344,6 +341,35 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # cut copy paste | cordon | TL | DD 3D DW DA | # compile helpers 2D_models fade CM prop_detail NO_DRAW + right_toolbar = QtWidgets.QToolBar("Sidebar") + right_toolbar.setFixedWidth(115) + label_1 = QtWidgets.QLabel("Select:") + right_toolbar.addWidget(label_1) + right_toolbar.setMovable(False) + button_1 = QtWidgets.QPushButton("Groups") + button_1.setFixedSize(100, 25) + button_1.setEnabled(False) + right_toolbar.addWidget(button_1) + button_2 = QtWidgets.QPushButton("Objects") + button_2.setFixedSize(100, 25) + button_2.setEnabled(False) + right_toolbar.addWidget(button_2) + button_3 = QtWidgets.QPushButton("Solids") + button_3.setFixedSize(100, 25) + button_3.setEnabled(False) + right_toolbar.addWidget(button_3) + right_toolbar.addSeparator() + + label_2 = QtWidgets.QLabel("Texture Selection:") + right_toolbar.addWidget(label_2) + button_4 = QtWidgets.QPushButton("Browse") + button_4.setFixedSize(100, 25) + texture_popup = texture_browser.TextureBrowser(parent=self) + button_4.clicked.connect(texture_popup.show) + right_toolbar.addWidget(button_4) + + self.addToolBar(QtCore.Qt.RightToolBarArea, right_toolbar) + def open(self, filename): # allows loading via drag & drop raw_filename, extension = os.path.splitext(filename) short_filename = os.path.basename(filename) From 8c0647b8baeec51f741d2af4ca9ce9ab60fc536e Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:02:18 -0500 Subject: [PATCH 22/67] The dropdowns --- QtPyHammer/ui/compile.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index 3a0c49e..aff54ba 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -13,24 +13,36 @@ def __init__(self, parent): self.text_label.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) # Add QLabel widgets - self.box1 = QtWidgets.QLabel() - self.box1.setText("Run BSP") - self.box1.setAlignment(QtCore.Qt.AlignCenter) + self.box1 = QtWidgets.QLabel("Run BSP") + bsp_combo_box = QtWidgets.QComboBox() + bsp_combo_box.setGeometry(200, 150, 120, 40) + bsp_combo_box.addItem("No") + bsp_combo_box.addItem("Normal") + bsp_combo_box.addItem("Only Entities") - self.box2 = QtWidgets.QLabel() - self.box2.setText("Run VIS") - self.box2.setAlignment(QtCore.Qt.AlignCenter) + self.box2 = QtWidgets.QLabel("Run VIS") + vis_combo_box = QtWidgets.QComboBox() + vis_combo_box.setGeometry(200, 150, 120, 40) + vis_combo_box.addItem("No") + vis_combo_box.addItem("Normal") + vis_combo_box.addItem("Fast") - self.box3 = QtWidgets.QLabel() - self.box3.setText("Run RAD") - self.box3.setAlignment(QtCore.Qt.AlignCenter) + self.box3 = QtWidgets.QLabel("Run RAD") + rad_combo_box = QtWidgets.QComboBox() + rad_combo_box.setGeometry(200, 150, 120, 40) + rad_combo_box.addItem("No") + rad_combo_box.addItem("Normal") + rad_combo_box.addItem("Fast") # Layout setup base_layout = QtWidgets.QVBoxLayout() base_layout.addWidget(self.text_label) base_layout.addWidget(self.box1) + base_layout.addWidget(self.bsp_combo_box) base_layout.addWidget(self.box2) + base_layout.addWidget(self.vis_combo_box) base_layout.addWidget(self.box3) + base_layout.addWidget(self.rad_combo_box) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) ok_button = QtWidgets.QPushButton("Ok") @@ -41,4 +53,4 @@ def __init__(self, parent): self.setLayout(base_layout) # Resize the dialog to fit the text - self.adjustSize() \ No newline at end of file + self.adjustSize() From 75a34ee76719e5cba2ff8774e815385a9296259e Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:03:49 -0500 Subject: [PATCH 23/67] Cancel Button! --- QtPyHammer/ui/compile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index aff54ba..1152120 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -45,6 +45,9 @@ def __init__(self, parent): base_layout.addWidget(self.rad_combo_box) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) + cancel_button = QtWidgets.QPushButton("Cancel") + cancel_button.clicked.connect(self.reject) + bottom_row.addWidget(cancel_button) ok_button = QtWidgets.QPushButton("Ok") ok_button.clicked.connect(self.accept) ok_button.setDefault(True) From b73092facb0045147e88120568d9f7732d09c266 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:22:58 -0500 Subject: [PATCH 24/67] Fix + Default Dropdown --- QtPyHammer/ui/compile.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index 1152120..22ee7aa 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -14,35 +14,38 @@ def __init__(self, parent): # Add QLabel widgets self.box1 = QtWidgets.QLabel("Run BSP") - bsp_combo_box = QtWidgets.QComboBox() - bsp_combo_box.setGeometry(200, 150, 120, 40) - bsp_combo_box.addItem("No") - bsp_combo_box.addItem("Normal") + bsp_combo_box = QtWidgets.QComboBox() + bsp_combo_box.setGeometry(200, 150, 120, 40) + bsp_combo_box.addItem("No") + bsp_combo_box.addItem("Normal") bsp_combo_box.addItem("Only Entities") + bsp_combo_box.setCurrentIndex(bsp_combo_box.findText("Normal")) self.box2 = QtWidgets.QLabel("Run VIS") - vis_combo_box = QtWidgets.QComboBox() - vis_combo_box.setGeometry(200, 150, 120, 40) - vis_combo_box.addItem("No") - vis_combo_box.addItem("Normal") + vis_combo_box = QtWidgets.QComboBox() + vis_combo_box.setGeometry(200, 150, 120, 40) + vis_combo_box.addItem("No") + vis_combo_box.addItem("Normal") vis_combo_box.addItem("Fast") + vis_combo_box.setCurrentIndex(vis_combo_box.findText("Normal")) self.box3 = QtWidgets.QLabel("Run RAD") - rad_combo_box = QtWidgets.QComboBox() - rad_combo_box.setGeometry(200, 150, 120, 40) - rad_combo_box.addItem("No") - rad_combo_box.addItem("Normal") + rad_combo_box = QtWidgets.QComboBox() + rad_combo_box.setGeometry(200, 150, 120, 40) + rad_combo_box.addItem("No") + rad_combo_box.addItem("Normal") rad_combo_box.addItem("Fast") + rad_combo_box.setCurrentIndex(rad_combo_box.findText("Fast")) # Layout setup base_layout = QtWidgets.QVBoxLayout() base_layout.addWidget(self.text_label) base_layout.addWidget(self.box1) - base_layout.addWidget(self.bsp_combo_box) + base_layout.addWidget(bsp_combo_box) base_layout.addWidget(self.box2) - base_layout.addWidget(self.vis_combo_box) + base_layout.addWidget(vis_combo_box) base_layout.addWidget(self.box3) - base_layout.addWidget(self.rad_combo_box) + base_layout.addWidget(rad_combo_box) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) cancel_button = QtWidgets.QPushButton("Cancel") From bf98589283b7baa8d87064b707f31cc0d1710b59 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 24 Apr 2024 21:09:49 -0500 Subject: [PATCH 25/67] compiles (Kinda) --- QtPyHammer/ui/compile.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index 22ee7aa..86e4d18 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -1,4 +1,5 @@ from PyQt5 import QtCore, QtGui, QtWidgets +import subprocess class browser(QtWidgets.QDialog): def __init__(self, parent): @@ -52,7 +53,7 @@ def __init__(self, parent): cancel_button.clicked.connect(self.reject) bottom_row.addWidget(cancel_button) ok_button = QtWidgets.QPushButton("Ok") - ok_button.clicked.connect(self.accept) + ok_button.clicked.connect(self.on_ok_clicked) ok_button.setDefault(True) bottom_row.addWidget(ok_button) base_layout.addLayout(bottom_row) @@ -60,3 +61,20 @@ def __init__(self, parent): # Resize the dialog to fit the text self.adjustSize() + def on_ok_clicked(self): + vbsp_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vbsp.exe' + vvis_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vvis.exe' + vrad_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vrad.exe' + + game_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf' + file_path = r'C:\Users\hudso\OneDrive\Desktop\SCP Maps\Slammin Test.vmf' + + vvis_arguments = ['-game', game_path, file_path] + + vbsp_command = [vbsp_path] + vvis_arguments + vvis_command = [vvis_path] + vvis_arguments + vrad_command = [vrad_path] + vvis_arguments + subprocess.run(vbsp_command, check=True) + subprocess.run(vvis_command, check=True) + subprocess.run(vrad_command, check=True) + self.accept() \ No newline at end of file From 2dbf3d6d784ec4caff2eabceaecbfe5d596564c4 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:43:45 -0500 Subject: [PATCH 26/67] arguments? this could def not work --- QtPyHammer/ui/compile.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index 86e4d18..ac946b9 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -69,11 +69,39 @@ def on_ok_clicked(self): game_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf' file_path = r'C:\Users\hudso\OneDrive\Desktop\SCP Maps\Slammin Test.vmf' + bsp_index = self.bsp_combo_box.currentIndex() + vis_index = self.vis_combo_box.currentIndex() + rad_index = self.rad_combo_box.currentIndex() + + vbsp_arguments = ['-game', game_path, file_path, '-leaktest'] vvis_arguments = ['-game', game_path, file_path] + vrad_arguments = ['-game', game_path, file_path] + + if bsp_index == 0: + vbsp_arguments += [] + elif bsp_index == 1: + vbsp_arguments += [] + elif bsp_index == 2: + vbsp_arguments += ['-onlyents'] + + if vis_index == 0: + vvis_arguments += [] + elif vis_index == 1: + vvis_arguments += [] + elif vis_index == 2: + vvis_arguments += ['-fast'] - vbsp_command = [vbsp_path] + vvis_arguments + if rad_index == 0: + vrad_arguments += [] + elif rad_index == 1: + vrad_arguments += [] + elif rad_index == 2: + vrad_arguments += ['-fast'] + + vbsp_command = [vbsp_path] + vbsp_arguments vvis_command = [vvis_path] + vvis_arguments - vrad_command = [vrad_path] + vvis_arguments + vrad_command = [vrad_path] + vrad_arguments + subprocess.run(vbsp_command, check=True) subprocess.run(vvis_command, check=True) subprocess.run(vrad_command, check=True) From 7ff0e9ea90bffafeb94fddf77a2c81dee1658633 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:02:32 -0500 Subject: [PATCH 27/67] basic lang system --- QtPyHammer/ui/core.py | 5 ++++- QtPyHammer/utilities/lang.py | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 QtPyHammer/utilities/lang.py diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 62dc60c..7dd171c 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -6,12 +6,15 @@ from .. import ops from ..ui import entity from ..ui import workspace +from ..utilities import lang + class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(QtWidgets.QMainWindow, self).__init__(parent) global current_dir + lang.setLanguage("english") self.setWindowTitle("QtPyHammer") self.setMinimumSize(640, 480) self.setTabPosition(QtCore.Qt.TopDockWidgetArea, QtWidgets.QTabWidget.North) @@ -63,7 +66,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["File/Exit"].triggered.connect(QtCore.QCoreApplication.quit) edit_menu = self.main_menu.addMenu("&Edit") - self.actions["Edit/Undo"] = edit_menu.addAction("Undo") + self.actions["Edit/Undo"] = edit_menu.addAction(lang.langUndo()) self.actions["Edit/Undo"].setEnabled(False) # self.actions["Edit/Undo"].triggered.connect( # edit timeline self.actions["Edit/Redo"] = edit_menu.addAction("Redo") diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py new file mode 100644 index 0000000..60af2a5 --- /dev/null +++ b/QtPyHammer/utilities/lang.py @@ -0,0 +1,23 @@ +usingLanguage = "english" # Default language + +def setLanguage(language): + global usingLanguage + usingLanguage = language.lower() + +def langOk(language=usingLanguage): + match(language): + case "english": + return "Ok" + case "french": + return "D'accord" + case _: + return "Ok" + +def langUndo(language=usingLanguage): + match(language): + case "english": + return "Undo" + case "french": + return "Annuler" + case _: + return "Undo" \ No newline at end of file From c797b41955a4f9c3e3b4b6cab0f93b30bf93dba4 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:12:31 -0500 Subject: [PATCH 28/67] google translate --- QtPyHammer/utilities/lang.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index 60af2a5..c202007 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -10,6 +10,12 @@ def langOk(language=usingLanguage): return "Ok" case "french": return "D'accord" + case "spanish": + return "De acuerdo" + case "german": + return "Ok" + case "italian": + return "Ok" case _: return "Ok" @@ -19,5 +25,11 @@ def langUndo(language=usingLanguage): return "Undo" case "french": return "Annuler" + case "spanish": + return "Deshacer" + case "german": + return "Rückgängig machen" + case "italian": + return "Annulla" case _: return "Undo" \ No newline at end of file From db2751092372ef0c1fc49ef25d920d61e84b204d Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:39:38 -0500 Subject: [PATCH 29/67] Compile with arg's --- QtPyHammer/ui/compile.py | 81 ++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index ac946b9..f8f43ca 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -14,53 +14,54 @@ def __init__(self, parent): self.text_label.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) # Add QLabel widgets - self.box1 = QtWidgets.QLabel("Run BSP") - bsp_combo_box = QtWidgets.QComboBox() - bsp_combo_box.setGeometry(200, 150, 120, 40) - bsp_combo_box.addItem("No") - bsp_combo_box.addItem("Normal") - bsp_combo_box.addItem("Only Entities") - bsp_combo_box.setCurrentIndex(bsp_combo_box.findText("Normal")) - - self.box2 = QtWidgets.QLabel("Run VIS") - vis_combo_box = QtWidgets.QComboBox() - vis_combo_box.setGeometry(200, 150, 120, 40) - vis_combo_box.addItem("No") - vis_combo_box.addItem("Normal") - vis_combo_box.addItem("Fast") - vis_combo_box.setCurrentIndex(vis_combo_box.findText("Normal")) - - self.box3 = QtWidgets.QLabel("Run RAD") - rad_combo_box = QtWidgets.QComboBox() - rad_combo_box.setGeometry(200, 150, 120, 40) - rad_combo_box.addItem("No") - rad_combo_box.addItem("Normal") - rad_combo_box.addItem("Fast") - rad_combo_box.setCurrentIndex(rad_combo_box.findText("Fast")) + self.box1 = QtWidgets.QLabel("Run BSP:") + self.bsp_combo_box = QtWidgets.QComboBox() + self.bsp_combo_box.setGeometry(200, 150, 120, 40) + self.bsp_combo_box.addItem("No") + self.bsp_combo_box.addItem("Normal") + self.bsp_combo_box.addItem("Only Entities") + self.bsp_combo_box.setCurrentIndex(self.bsp_combo_box.findText("Normal")) + + self.box2 = QtWidgets.QLabel("Run VIS:") + self.vis_combo_box = QtWidgets.QComboBox() + self.vis_combo_box.setGeometry(200, 150, 120, 40) + self.vis_combo_box.addItem("No") + self.vis_combo_box.addItem("Normal") + self.vis_combo_box.addItem("Fast") + self.vis_combo_box.setCurrentIndex(self.vis_combo_box.findText("Normal")) + + self.box3 = QtWidgets.QLabel("Run RAD:") + self.rad_combo_box = QtWidgets.QComboBox() + self.rad_combo_box.setGeometry(200, 150, 120, 40) + self.rad_combo_box.addItem("No") + self.rad_combo_box.addItem("Normal") + self.rad_combo_box.addItem("Fast") + self.rad_combo_box.setCurrentIndex(self.rad_combo_box.findText("Fast")) # Layout setup base_layout = QtWidgets.QVBoxLayout() base_layout.addWidget(self.text_label) base_layout.addWidget(self.box1) - base_layout.addWidget(bsp_combo_box) + base_layout.addWidget(self.bsp_combo_box) base_layout.addWidget(self.box2) - base_layout.addWidget(vis_combo_box) + base_layout.addWidget(self.vis_combo_box) base_layout.addWidget(self.box3) - base_layout.addWidget(rad_combo_box) + base_layout.addWidget(self.rad_combo_box) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) cancel_button = QtWidgets.QPushButton("Cancel") cancel_button.clicked.connect(self.reject) - bottom_row.addWidget(cancel_button) + bottom_row.addWidget(cancel_button) ok_button = QtWidgets.QPushButton("Ok") ok_button.clicked.connect(self.on_ok_clicked) ok_button.setDefault(True) - bottom_row.addWidget(ok_button) + bottom_row.addWidget(ok_button) base_layout.addLayout(bottom_row) self.setLayout(base_layout) # Resize the dialog to fit the text self.adjustSize() + def on_ok_clicked(self): vbsp_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vbsp.exe' vvis_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vvis.exe' @@ -73,30 +74,30 @@ def on_ok_clicked(self): vis_index = self.vis_combo_box.currentIndex() rad_index = self.rad_combo_box.currentIndex() - vbsp_arguments = ['-game', game_path, file_path, '-leaktest'] - vvis_arguments = ['-game', game_path, file_path] - vrad_arguments = ['-game', game_path, file_path] + vbsp_arguments = ['-game', game_path] + vvis_arguments = ['-game', game_path] + vrad_arguments = ['-game', game_path] if bsp_index == 0: - vbsp_arguments += [] + vbsp_arguments += ['-leaktest', file_path] elif bsp_index == 1: - vbsp_arguments += [] + vbsp_arguments += ['-leaktest', file_path] elif bsp_index == 2: - vbsp_arguments += ['-onlyents'] + vbsp_arguments += ['-leaktest', '-onlyents', file_path] if vis_index == 0: - vvis_arguments += [] + vvis_arguments += [file_path] elif vis_index == 1: - vvis_arguments += [] + vvis_arguments += [file_path] elif vis_index == 2: - vvis_arguments += ['-fast'] + vvis_arguments += ['-fast', file_path] if rad_index == 0: - vrad_arguments += [] + vrad_arguments += [file_path] elif rad_index == 1: - vrad_arguments += [] + vrad_arguments += [file_path] elif rad_index == 2: - vrad_arguments += ['-fast'] + vrad_arguments += ['-fast', file_path] vbsp_command = [vbsp_path] + vbsp_arguments vvis_command = [vvis_path] + vvis_arguments From 4198132834a78380596fc649df24a9b017302947 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 14 May 2024 15:44:18 -0500 Subject: [PATCH 30/67] VMF path textbox as workaround --- QtPyHammer/ui/compile.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index f8f43ca..54df342 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -37,6 +37,10 @@ def __init__(self, parent): self.rad_combo_box.addItem("Normal") self.rad_combo_box.addItem("Fast") self.rad_combo_box.setCurrentIndex(self.rad_combo_box.findText("Fast")) + + self.box4 = QtWidgets.QLabel("Path to VMF") + self.textbox = QtWidgets.QLineEdit(self) + self.textbox.resize(280,40) # Layout setup base_layout = QtWidgets.QVBoxLayout() @@ -67,7 +71,7 @@ def on_ok_clicked(self): vvis_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vvis.exe' vrad_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vrad.exe' - game_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf' + game_path = self.textbox.text() file_path = r'C:\Users\hudso\OneDrive\Desktop\SCP Maps\Slammin Test.vmf' bsp_index = self.bsp_combo_box.currentIndex() @@ -106,4 +110,4 @@ def on_ok_clicked(self): subprocess.run(vbsp_command, check=True) subprocess.run(vvis_command, check=True) subprocess.run(vrad_command, check=True) - self.accept() \ No newline at end of file + self.accept() From 3d148ae0b84ebfae191759ae1e639ac02df86369 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 15 May 2024 10:06:04 -0500 Subject: [PATCH 31/67] popup for entity browser --- QtPyHammer/ui/entity.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/QtPyHammer/ui/entity.py b/QtPyHammer/ui/entity.py index 7c44a78..d70b7dd 100644 --- a/QtPyHammer/ui/entity.py +++ b/QtPyHammer/ui/entity.py @@ -16,7 +16,8 @@ def __init__(self, parent): self.setGeometry(780, 220, 360, 640) app = QtWidgets.QApplication.instance() if len(app.fgd.entities) == 0: - raise RuntimeError("No entites to browse!") + error_popup = popup.browser(parent=self, popuptext="Error", msgtext="No entites to browse!") + error_popup.show() def is_point_or_solid(e): return e.class_type in ("PointClass", "SolidClass") From b24b45cb0975d6ff56a4db2de19f4e18809556f3 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 15 May 2024 10:19:12 -0500 Subject: [PATCH 32/67] Default arguments --- QtPyHammer/ui/popup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py index 079adbe..a261f92 100644 --- a/QtPyHammer/ui/popup.py +++ b/QtPyHammer/ui/popup.py @@ -1,7 +1,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class browser(QtWidgets.QDialog): - def __init__(self, parent, popuptext, msgtext): + def __init__(self, parent, popuptext='Error', msgtext='Something's wrong, but we don't know what'): super(browser, self).__init__(parent, QtCore.Qt.Tool) self.setWindowTitle(popuptext) @@ -25,4 +25,4 @@ def __init__(self, parent, popuptext, msgtext): self.setLayout(base_layout) # Resize the dialog to fit the text - self.adjustSize() \ No newline at end of file + self.adjustSize() From 9594025433e62c0ee1cb140db94b8b4dd795b39c Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 15 May 2024 11:12:18 -0500 Subject: [PATCH 33/67] "" --- QtPyHammer/ui/popup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py index a261f92..4aa9c37 100644 --- a/QtPyHammer/ui/popup.py +++ b/QtPyHammer/ui/popup.py @@ -1,7 +1,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class browser(QtWidgets.QDialog): - def __init__(self, parent, popuptext='Error', msgtext='Something's wrong, but we don't know what'): + def __init__(self, parent, popuptext="Error", msgtext="Something's wrong, but we don't know what"): super(browser, self).__init__(parent, QtCore.Qt.Tool) self.setWindowTitle(popuptext) From a713c5d3c1653dc453e305afc7b39878d0860ae6 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Sun, 19 May 2024 14:39:00 -0500 Subject: [PATCH 34/67] fix --- QtPyHammer/ui/compile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index 54df342..bef2f7d 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -51,6 +51,8 @@ def __init__(self, parent): base_layout.addWidget(self.vis_combo_box) base_layout.addWidget(self.box3) base_layout.addWidget(self.rad_combo_box) + base_layout.addWidget(self.box4) + base_layout.addWidget(self.textbox) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) cancel_button = QtWidgets.QPushButton("Cancel") @@ -71,8 +73,8 @@ def on_ok_clicked(self): vvis_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vvis.exe' vrad_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vrad.exe' - game_path = self.textbox.text() - file_path = r'C:\Users\hudso\OneDrive\Desktop\SCP Maps\Slammin Test.vmf' + game_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf' + file_path = self.textbox.text() bsp_index = self.bsp_combo_box.currentIndex() vis_index = self.vis_combo_box.currentIndex() From c5b922ad1338ac4e94d0ca1ce0a3ad97c547eb5c Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Sun, 19 May 2024 14:52:48 -0500 Subject: [PATCH 35/67] More lang --- .idea/.gitignore | 3 +++ QtPyHammer/ui/core.py | 6 +++--- QtPyHammer/utilities/lang.py | 22 +++++++++++++++++++++- 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 .idea/.gitignore diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 7dd171c..34ffa64 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -58,18 +58,18 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["File/Options"].setEnabled(False) # self.actions["File/Options"].triggered.connect(ui.settings) file_menu.addSeparator() - self.actions["File/Compile"] = file_menu.addAction("Compile") + self.actions["File/Compile"] = file_menu.addAction(lang.langCompile()) self.actions["File/Compile"].setEnabled(False) # self.actions["File/Compile"].triggered.connect(ui.compile) file_menu.addSeparator() - self.actions["File/Exit"] = file_menu.addAction("Exit") + self.actions["File/Exit"] = file_menu.addAction(lang.langExit()) self.actions["File/Exit"].triggered.connect(QtCore.QCoreApplication.quit) edit_menu = self.main_menu.addMenu("&Edit") self.actions["Edit/Undo"] = edit_menu.addAction(lang.langUndo()) self.actions["Edit/Undo"].setEnabled(False) # self.actions["Edit/Undo"].triggered.connect( # edit timeline - self.actions["Edit/Redo"] = edit_menu.addAction("Redo") + self.actions["Edit/Redo"] = edit_menu.addAction(lang.langRedo()) self.actions["Edit/Redo"].setEnabled(False) # self.actions["Edit/Redo"].triggered.connect( # edit timeline self.actions["Edit/History"] = edit_menu.addMenu("&History...") diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index c202007..ee89b14 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -32,4 +32,24 @@ def langUndo(language=usingLanguage): case "italian": return "Annulla" case _: - return "Undo" \ No newline at end of file + return "Undo" +def langRedo(language=usingLanguage): + match(language): + case "english": + return "Redo" + case _: + return "Redo" + +def langCompile(language=usingLanguage): + match(language): + case "english": + return "Compile" + case _: + return "Compile" + +def langExit(language=usingLanguage): + match(language): + case "english": + return "Exit" + case _: + return "Exit" \ No newline at end of file From 3c9f03eba2598b53c10cac22fd7b45ce6e65debe Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Sun, 19 May 2024 15:17:48 -0500 Subject: [PATCH 36/67] Remove text label --- QtPyHammer/ui/compile.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index bef2f7d..b49275e 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -6,13 +6,6 @@ def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) self.setWindowTitle("Run Map") - # Add QLabel to display text - self.text_label = QtWidgets.QLabel("The Compile Menu is not implemented yet") - self.text_label.setAlignment(QtCore.Qt.AlignCenter) # Center align text - self.text_label.setWordWrap(True) # Enable word wrap - self.text_label.setMargin(10) # Add margin to the label - self.text_label.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) - # Add QLabel widgets self.box1 = QtWidgets.QLabel("Run BSP:") self.bsp_combo_box = QtWidgets.QComboBox() @@ -44,7 +37,6 @@ def __init__(self, parent): # Layout setup base_layout = QtWidgets.QVBoxLayout() - base_layout.addWidget(self.text_label) base_layout.addWidget(self.box1) base_layout.addWidget(self.bsp_combo_box) base_layout.addWidget(self.box2) From ee6864b271c441d92c91137efd793197573a6040 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 09:13:21 -0500 Subject: [PATCH 37/67] More possibility --- QtPyHammer/utilities/lang.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index ee89b14..23fbb13 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -33,6 +33,7 @@ def langUndo(language=usingLanguage): return "Annulla" case _: return "Undo" + def langRedo(language=usingLanguage): match(language): case "english": @@ -52,4 +53,25 @@ def langExit(language=usingLanguage): case "english": return "Exit" case _: - return "Exit" \ No newline at end of file + return "Exit" + +def langNo(language=usingLanguage): + match(language): + case "english": + return "No" + case _: + return "No" + +def langNormal(language=usingLanguage): + match(language): + case "english": + return "Normal" + case _: + return "Normal" + +def langFast(language=usingLanguage): + match(language): + case "english": + return "Fast" + case _: + return "Fast" From 7951064058b44165c26cf3cd11f59882771032d0 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 09:19:51 -0500 Subject: [PATCH 38/67] lang! --- QtPyHammer/ui/compile.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index b49275e..e08cffc 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -1,4 +1,6 @@ from PyQt5 import QtCore, QtGui, QtWidgets + +from ..utilities import lang import subprocess class browser(QtWidgets.QDialog): @@ -10,26 +12,26 @@ def __init__(self, parent): self.box1 = QtWidgets.QLabel("Run BSP:") self.bsp_combo_box = QtWidgets.QComboBox() self.bsp_combo_box.setGeometry(200, 150, 120, 40) - self.bsp_combo_box.addItem("No") - self.bsp_combo_box.addItem("Normal") + self.bsp_combo_box.addItem(lang.langNo()) + self.bsp_combo_box.addItem(lang.langNormal()) self.bsp_combo_box.addItem("Only Entities") self.bsp_combo_box.setCurrentIndex(self.bsp_combo_box.findText("Normal")) self.box2 = QtWidgets.QLabel("Run VIS:") self.vis_combo_box = QtWidgets.QComboBox() self.vis_combo_box.setGeometry(200, 150, 120, 40) - self.vis_combo_box.addItem("No") - self.vis_combo_box.addItem("Normal") - self.vis_combo_box.addItem("Fast") - self.vis_combo_box.setCurrentIndex(self.vis_combo_box.findText("Normal")) + self.vis_combo_box.addItem(lang.langNo()) + self.vis_combo_box.addItem(lang.langNormal()) + self.vis_combo_box.addItem(lang.langFast()) + self.vis_combo_box.setCurrentIndex(self.vis_combo_box.findText(lang.langNormal())) self.box3 = QtWidgets.QLabel("Run RAD:") self.rad_combo_box = QtWidgets.QComboBox() self.rad_combo_box.setGeometry(200, 150, 120, 40) - self.rad_combo_box.addItem("No") - self.rad_combo_box.addItem("Normal") - self.rad_combo_box.addItem("Fast") - self.rad_combo_box.setCurrentIndex(self.rad_combo_box.findText("Fast")) + self.rad_combo_box.addItem(lang.langNo()) + self.rad_combo_box.addItem(lang.langNormal()) + self.rad_combo_box.addItem(lang.langFast()) + self.rad_combo_box.setCurrentIndex(self.rad_combo_box.findText(lang.langFast())) self.box4 = QtWidgets.QLabel("Path to VMF") self.textbox = QtWidgets.QLineEdit(self) From 98f45ba3eca0ccf9c5746536dbcb1ba7fafad50d Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 09:29:21 -0500 Subject: [PATCH 39/67] Update --- QtPyHammer/utilities/lang.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index 23fbb13..cf5d4d1 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -8,14 +8,8 @@ def langOk(language=usingLanguage): match(language): case "english": return "Ok" - case "french": - return "D'accord" case "spanish": return "De acuerdo" - case "german": - return "Ok" - case "italian": - return "Ok" case _: return "Ok" @@ -52,6 +46,8 @@ def langExit(language=usingLanguage): match(language): case "english": return "Exit" + case "french": + return "Sortir" case _: return "Exit" @@ -59,6 +55,8 @@ def langNo(language=usingLanguage): match(language): case "english": return "No" + case "french": + return "Non" case _: return "No" @@ -66,6 +64,8 @@ def langNormal(language=usingLanguage): match(language): case "english": return "Normal" + case "french": + return "Normale" case _: return "Normal" @@ -73,5 +73,7 @@ def langFast(language=usingLanguage): match(language): case "english": return "Fast" + case "french": + return "Rapide" case _: return "Fast" From 5da9bdc9bf60b57f71917f304f15f686da1071fc Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 09:42:31 -0500 Subject: [PATCH 40/67] langOk --- QtPyHammer/ui/popup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py index 079adbe..cc6c275 100644 --- a/QtPyHammer/ui/popup.py +++ b/QtPyHammer/ui/popup.py @@ -1,4 +1,5 @@ from PyQt5 import QtCore, QtGui, QtWidgets +from ..utilities import lang class browser(QtWidgets.QDialog): def __init__(self, parent, popuptext, msgtext): @@ -17,7 +18,7 @@ def __init__(self, parent, popuptext, msgtext): base_layout.addWidget(self.text_label) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) - ok_button = QtWidgets.QPushButton("Ok") + ok_button = QtWidgets.QPushButton(lang.langOk()) ok_button.clicked.connect(self.accept) ok_button.setDefault(True) bottom_row.addWidget(ok_button) @@ -25,4 +26,4 @@ def __init__(self, parent, popuptext, msgtext): self.setLayout(base_layout) # Resize the dialog to fit the text - self.adjustSize() \ No newline at end of file + self.adjustSize() From cfc8dc43bd958babd95b3eca1a1e402da6b30f0b Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 10:24:47 -0500 Subject: [PATCH 41/67] Open a URL for the condributors --- QtPyHammer/ui/core.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 115b027..c84c27d 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -274,11 +274,10 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) "https://github.com/strubium/QtPyHammer/blob/master/LICENSE"))) # self.actions["Help/License"].triggered.connect(ui. #QDialog self.actions["Help/Contributors"] = help_menu.addAction("Contributors") - self.actions["Help/Contributors"].setEnabled(False) + self.actions["Help/Contributors"].triggered.connect(lambda: open_url(QtCore.QUrl("https://github.com/QtPyHammer-devs/QtPyHammer/graphs/contributors"))) self.actions["Help/QPH Wiki"] = help_menu.addAction("QtPyHammer Wiki") self.actions["Help/QPH Wiki"].triggered.connect(lambda: open_url(QtCore.QUrl( "https://github.com/snake-biscuits/QtPyHammer/wiki"))) - # self.actions["Help/Contributors"].triggered.connect(ui. #QDialog help_menu.addSeparator() self.actions["Help/VDC"] = help_menu.addAction("Valve Developer Community") self.actions["Help/VDC"].triggered.connect(lambda: open_url(QtCore.QUrl( From 3c8541dfc1f7ed66fb1919c5610c1ded26a728db Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 10:42:22 -0500 Subject: [PATCH 42/67] Add plans to filter by a max amount --- QtPyHammer/ui/texture_browser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/QtPyHammer/ui/texture_browser.py b/QtPyHammer/ui/texture_browser.py index fefed6f..76673e9 100644 --- a/QtPyHammer/ui/texture_browser.py +++ b/QtPyHammer/ui/texture_browser.py @@ -46,6 +46,9 @@ def __init__(self, parent=None): # finally add scrollarea widget to the outer QVBoxLayout main_layout.addWidget(scroll) main_layout.addWidget(QtWidgets.QLabel("Search Options")) + # main_layout.addWidget(QtWidgets.QLabel("Max:")) + # main_layout.addWidget(QtWidgets.QLineEdit(self).setPlaceholderText("400").resize(280,40)) + # list of checkboxes? # colour-range (hue) slider (.vtf reflectivity value) From 87bccdeb11c2ad8219599e2cfd82dabe89da00d3 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 10:53:12 -0500 Subject: [PATCH 43/67] Russian from google translate --- QtPyHammer/utilities/lang.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index cf5d4d1..6d66dea 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -10,6 +10,8 @@ def langOk(language=usingLanguage): return "Ok" case "spanish": return "De acuerdo" + case "russian": + return "Хорошо" case _: return "Ok" @@ -25,6 +27,8 @@ def langUndo(language=usingLanguage): return "Rückgängig machen" case "italian": return "Annulla" + case "russian": + return "Отменить" case _: return "Undo" @@ -32,6 +36,8 @@ def langRedo(language=usingLanguage): match(language): case "english": return "Redo" + case "russian": + return "Повторить" case _: return "Redo" @@ -39,6 +45,8 @@ def langCompile(language=usingLanguage): match(language): case "english": return "Compile" + case "russian": + return "Скомпилировать" case _: return "Compile" @@ -48,6 +56,8 @@ def langExit(language=usingLanguage): return "Exit" case "french": return "Sortir" + case "russian": + return "Выход" case _: return "Exit" @@ -57,6 +67,8 @@ def langNo(language=usingLanguage): return "No" case "french": return "Non" + case "russian": + return "Нет" case _: return "No" @@ -66,6 +78,8 @@ def langNormal(language=usingLanguage): return "Normal" case "french": return "Normale" + case "russian": + return "Нормальный" case _: return "Normal" @@ -75,5 +89,7 @@ def langFast(language=usingLanguage): return "Fast" case "french": return "Rapide" + case "russian": + return "Быстрый" case _: return "Fast" From f40112c77171a8ae8a76763df071e3f628ac35d2 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 11:16:22 -0500 Subject: [PATCH 44/67] Create properties.py --- QtPyHammer/ui/properties.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 QtPyHammer/ui/properties.py diff --git a/QtPyHammer/ui/properties.py b/QtPyHammer/ui/properties.py new file mode 100644 index 0000000..527721f --- /dev/null +++ b/QtPyHammer/ui/properties.py @@ -0,0 +1,21 @@ +from PyQt5 import QtCore, QtGui, QtWidgets +from ..utilities import lang + +class browser(QtWidgets.QDialog): + def __init__(self, parent): + super(browser, self).__init__(parent, QtCore.Qt.Tool) + self.setWindowTitle("Properties") + + # Layout setup + base_layout = QtWidgets.QVBoxLayout() + bottom_row = QtWidgets.QHBoxLayout() + bottom_row.addStretch(1) + ok_button = QtWidgets.QPushButton(lang.langOk()) + ok_button.clicked.connect(self.accept) + ok_button.setDefault(True) + bottom_row.addWidget(ok_button) + base_layout.addLayout(bottom_row) + self.setLayout(base_layout) + + # Resize the dialog to fit the text + self.adjustSize() From e8a67cab1713291bef2414e89febc968595bde65 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 11:20:44 -0500 Subject: [PATCH 45/67] Add render mode --- QtPyHammer/ui/properties.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/QtPyHammer/ui/properties.py b/QtPyHammer/ui/properties.py index 527721f..7e98cb4 100644 --- a/QtPyHammer/ui/properties.py +++ b/QtPyHammer/ui/properties.py @@ -5,9 +5,20 @@ class browser(QtWidgets.QDialog): def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) self.setWindowTitle("Properties") + + self.box1 = QtWidgets.QLabel("Render Mode") + self.render_mod_combo_box = QtWidgets.QComboBox() + self.render_mod_combo_box.setGeometry(200, 150, 120, 40) + self.render_mod_combo_box.addItem("Flat") + self.render_mod_combo_box.addItem("Textured") + self.render_mod_combo_box.addItem("Wireframe") + self.render_mod_combo_box.setCurrentIndex(self.render_mod_combo_box.findText("Textured")) # Layout setup base_layout = QtWidgets.QVBoxLayout() + base_layout.addWidget(self.box1) + base_layout.addWidget(self.render_mod_combo_box) + bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) ok_button = QtWidgets.QPushButton(lang.langOk()) From 2a72a864a76eda7393d033f7f9d46d02eb32a53d Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 11:25:46 -0500 Subject: [PATCH 46/67] Text --- QtPyHammer/ui/properties.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QtPyHammer/ui/properties.py b/QtPyHammer/ui/properties.py index 7e98cb4..d6513e5 100644 --- a/QtPyHammer/ui/properties.py +++ b/QtPyHammer/ui/properties.py @@ -4,9 +4,9 @@ class browser(QtWidgets.QDialog): def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) - self.setWindowTitle("Properties") + self.setWindowTitle("QtPyHammer Properties") - self.box1 = QtWidgets.QLabel("Render Mode") + self.box1 = QtWidgets.QLabel("Render Mode:") self.render_mod_combo_box = QtWidgets.QComboBox() self.render_mod_combo_box.setGeometry(200, 150, 120, 40) self.render_mod_combo_box.addItem("Flat") From b969aade77f713e87b9b30979e60bb4c1e8b0800 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 11:34:04 -0500 Subject: [PATCH 47/67] Language menu --- QtPyHammer/ui/properties.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/QtPyHammer/ui/properties.py b/QtPyHammer/ui/properties.py index d6513e5..f7266aa 100644 --- a/QtPyHammer/ui/properties.py +++ b/QtPyHammer/ui/properties.py @@ -14,15 +14,27 @@ def __init__(self, parent): self.render_mod_combo_box.addItem("Wireframe") self.render_mod_combo_box.setCurrentIndex(self.render_mod_combo_box.findText("Textured")) + self.box2 = QtWidgets.QLabel("Language:") + self.lang_combo_box = QtWidgets.QComboBox() + self.lang_combo_box.setGeometry(200, 150, 120, 40) + self.lang_combo_box.addItem("English") + self.lang_combo_box.addItem("Spanish") + self.lang_combo_box.addItem("German") + self.lang_combo_box.addItem("Italian") + self.lang_combo_box.addItem("Russian") + self.lang_combo_box.setCurrentIndex(self.lang_combo_box.findText("English")) + # Layout setup base_layout = QtWidgets.QVBoxLayout() base_layout.addWidget(self.box1) base_layout.addWidget(self.render_mod_combo_box) + base_layout.addWidget(self.box2) + base_layout.addWidget(self.lang_combo_box) bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) ok_button = QtWidgets.QPushButton(lang.langOk()) - ok_button.clicked.connect(self.accept) + ok_button.clicked.connect(self.on_ok_clicked) ok_button.setDefault(True) bottom_row.addWidget(ok_button) base_layout.addLayout(bottom_row) @@ -30,3 +42,8 @@ def __init__(self, parent): # Resize the dialog to fit the text self.adjustSize() + + + def on_ok_clicked(self): + render_mod_index = self.render_mod_combo_box.currentIndex() + lang.setLanguage(self.lang_combo_box.text()) From 527dc5d60f4fb5be3bb858ca0305d18656c67cfd Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 11:47:48 -0500 Subject: [PATCH 48/67] Link Prop menu in core.py --- QtPyHammer/ui/core.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index c84c27d..88bd2dc 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -6,7 +6,7 @@ from .. import ops -from ..ui import entity, popup, texture_browser, compile +from ..ui import entity, popup, texture_browser, compile, properties from ..ui import workspace from ..utilities import lang @@ -18,7 +18,6 @@ def __init__(self, parent=None): super(QtWidgets.QMainWindow, self).__init__(parent) global current_dir - lang.setLanguage("english") self.setWindowTitle("QtPyHammer - Fork") self.setMinimumSize(640, 480) self.setTabPosition(QtCore.Qt.TopDockWidgetArea, QtWidgets.QTabWidget.North) @@ -59,8 +58,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # export_menu.addAction(".smd") file_menu.addSeparator() self.actions["File/Options"] = file_menu.addAction("&Options") - self.actions["File/Options"].setEnabled(False) - # self.actions["File/Options"].triggered.connect(ui.settings) + self.actions["File/Options"].triggered.connect(properties_menu.show) file_menu.addSeparator() self.actions["File/Compile"] = file_menu.addAction(lang.langCompile()) compile_menu = compile.browser(parent=self) From f413a4ad2108572b88f16c2a85c7d863ff104c53 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 11:53:13 -0500 Subject: [PATCH 49/67] Spanish! --- QtPyHammer/utilities/lang.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index 6d66dea..010aae0 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -36,6 +36,8 @@ def langRedo(language=usingLanguage): match(language): case "english": return "Redo" + case "spanish": + return "Rehacer" case "russian": return "Повторить" case _: @@ -45,6 +47,8 @@ def langCompile(language=usingLanguage): match(language): case "english": return "Compile" + case "spanish": + return "Compilar" case "russian": return "Скомпилировать" case _: @@ -56,6 +60,8 @@ def langExit(language=usingLanguage): return "Exit" case "french": return "Sortir" + case "spanish": + return "Salida" case "russian": return "Выход" case _: @@ -78,6 +84,8 @@ def langNormal(language=usingLanguage): return "Normal" case "french": return "Normale" + case "spanish": + return "Normala" case "russian": return "Нормальный" case _: @@ -89,6 +97,8 @@ def langFast(language=usingLanguage): return "Fast" case "french": return "Rapide" + case "spanish": + return "Rapido" case "russian": return "Быстрый" case _: From 6c733ba1c59fbd7402bd64bc9fd5462e9a544c19 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 12:05:51 -0500 Subject: [PATCH 50/67] File, edit, and tools lang --- QtPyHammer/utilities/lang.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index 010aae0..97494c3 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -3,7 +3,40 @@ def setLanguage(language): global usingLanguage usingLanguage = language.lower() + +def langFile(language=usingLanguage): + match(language): + case "english": + return "File" + case "spanish": + return "Archivo" + case "russian": + return "Файл" + case _: + return "File" + +def langEdit(language=usingLanguage): + match(language): + case "english": + return "Edit" + case "spanish": + return "Editar" + case "russian": + return "Редактировать" + case _: + return "Edit" +def langTools(language=usingLanguage): + match(language): + case "english": + return "Tools" + case "spanish": + return "Herramientas" + case "russian": + return "Инструменты" + case _: + return "Tools" + def langOk(language=usingLanguage): match(language): case "english": From 2a3a105baaa0e4521a76c1f11ed877edb8533966 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 12:07:08 -0500 Subject: [PATCH 51/67] Update core.py --- QtPyHammer/ui/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 88bd2dc..e49f987 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -35,7 +35,7 @@ def __init__(self, parent=None): self.actions = {} # ^ {"identifier": action} self.main_menu = QtWidgets.QMenuBar() - file_menu = self.main_menu.addMenu("&File") + file_menu = self.main_menu.addMenu(lang.langFile()) self.actions["File/New"] = file_menu.addAction("&New") def new_file(): ops.new_file(self) self.actions["File/New"].triggered.connect(new_file) @@ -67,7 +67,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["File/Exit"] = file_menu.addAction(lang.langExit()) self.actions["File/Exit"].triggered.connect(QtCore.QCoreApplication.quit) - edit_menu = self.main_menu.addMenu("&Edit") + edit_menu = self.main_menu.addMenu(lang.langEdit()) self.actions["Edit/Undo"] = edit_menu.addAction(lang.langUndo()) self.actions["Edit/Undo"].setEnabled(False) # self.actions["Edit/Undo"].triggered.connect( # edit timeline @@ -105,7 +105,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) self.actions["Edit/Properties"].setEnabled(False) # self.actions["Edit/Properties"].triggered.connect( - tools_menu = self.main_menu.addMenu("&Tools") + tools_menu = self.main_menu.addMenu(lang.langTools()) self.actions["Tools/Group"] = tools_menu.addAction("&Group") self.actions["Tools/Group"].setEnabled(False) # self.actions["Tools/Group"].triggered.connect( From d578b958b303ea99f7058d48ddf9e0171f4c2144 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 12:22:24 -0500 Subject: [PATCH 52/67] Opps --- QtPyHammer/ui/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index e49f987..8366c1f 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -58,6 +58,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # export_menu.addAction(".smd") file_menu.addSeparator() self.actions["File/Options"] = file_menu.addAction("&Options") + properties_menu = properties.browser(parent=self) self.actions["File/Options"].triggered.connect(properties_menu.show) file_menu.addSeparator() self.actions["File/Compile"] = file_menu.addAction(lang.langCompile()) From 482fd511ea1ee044e71c6349d963dca66f0c38ad Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 12:27:49 -0500 Subject: [PATCH 53/67] Add files via upload --- icons/HammerLogo.png | Bin 0 -> 1179 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 icons/HammerLogo.png diff --git a/icons/HammerLogo.png b/icons/HammerLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..76bc64f75329695e0a0e0e592f2050868e5d667b GIT binary patch literal 1179 zcmV;M1Z4Y(P)C00009a7bBm000XT z000XT0n*)m`~Uz1O-V#SRA_T2u*Zya1tv^Na&&gIk=29M?iq3Ib>M~5$xHLWyzA8psT&Ty**z$pOjRZ zovzuQdb{50>h4{owPpxWN=3j5*l4ZSop!FZZmqxqNJ{KWU<+s<2cj%lKyARvSqAzoX33jEQ~`91pe210nBlsIq=Y>sr^)n%U`)+H~#1fF#Oz$SUCDYp#7 zJn+IlkKlbBO?t}-cGKju7QC;kv%Wyw04{oV-fGqdotD&_@4M7_Cm=BOpo>|jiCzL{ zK;8-jrXG~dNPXxQ_`!>K<0OabdeE1iNd!W`8cn&DK0`Wx0i0JvCvHrqfoSv>J$F7Y2LT~K(i+ZRViLE={!-L! z%Z3CoE8+DPIIZCQbMO8&aK{eNARy#rNx-?Zg7+ElU7-D3`m`IZcqkANy8?Ay!Ta3h zJMhZ0FQwg{RdsSePzgd_8eqo_i|j z=Se5^q7DfEz@XMr!Et&e_p87_oD2d&97u&a%SN3Ws?CI!FG3(Va!Yy)i0IhR6Q1QB z0^ie7?Pwj!8X#hC7Q4$~jajsLhmsfdDoUvYcn`Po~lYwuRG{9n_t)%G>?sYW^PwXFrgA^hTIWisuYq?w``efTSzm^ZgpB?Ngx6## z@CjzNsvV6nB7xTWH}*&SXW&!${0s0IW=T@J!?B{VK=vVoe^$0W#10J~od8$tqOb@&cDv~NgX|~jh*HWrz6E~7RBkKRm_nFJ z9_`E6R4SmAtEZU4x20f}JG$c@h?(R32Drmv9XZ&_PKHialu|3;ec)r@R^X8<%;ssg zl^uKZ3nEhWi&ZkY*(o4Zi@%jpYWC)C>`^a>gnO7>r0FCR+XJ$w0HKlN)X62bD@v)1 zaB^FDq_v(;9mE{?wc@caCk+BXDU||Wlst0%e*j^V{M~^03RsPvz%`TH|7~N7Q!7Sy tumO;q-HFKFNyy~sWJQuZ(pqP}?LWr#wMMUQ>QVpz002ovPDHLkV1n~HG3EdO literal 0 HcmV?d00001 From b687f758244a5468ac7a3fb36180bab635f5efc7 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 12:33:23 -0500 Subject: [PATCH 54/67] Add logo --- QtPyHammer/ui/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index 8366c1f..cf572ae 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -18,6 +18,7 @@ def __init__(self, parent=None): super(QtWidgets.QMainWindow, self).__init__(parent) global current_dir + self.setWindowIcon(QtGui.QIcon('HammerLogo.png')) self.setWindowTitle("QtPyHammer - Fork") self.setMinimumSize(640, 480) self.setTabPosition(QtCore.Qt.TopDockWidgetArea, QtWidgets.QTabWidget.North) From 353d7e689816faab3423e89737f63bf72ca370d0 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Mon, 20 May 2024 17:53:45 -0500 Subject: [PATCH 55/67] save --- QtPyHammer/ui/properties.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/QtPyHammer/ui/properties.py b/QtPyHammer/ui/properties.py index f7266aa..7580eec 100644 --- a/QtPyHammer/ui/properties.py +++ b/QtPyHammer/ui/properties.py @@ -1,6 +1,5 @@ from PyQt5 import QtCore, QtGui, QtWidgets from ..utilities import lang - class browser(QtWidgets.QDialog): def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) @@ -30,7 +29,6 @@ def __init__(self, parent): base_layout.addWidget(self.render_mod_combo_box) base_layout.addWidget(self.box2) base_layout.addWidget(self.lang_combo_box) - bottom_row = QtWidgets.QHBoxLayout() bottom_row.addStretch(1) ok_button = QtWidgets.QPushButton(lang.langOk()) @@ -46,4 +44,5 @@ def __init__(self, parent): def on_ok_clicked(self): render_mod_index = self.render_mod_combo_box.currentIndex() - lang.setLanguage(self.lang_combo_box.text()) + lang.setLanguage(self.lang_combo_box.currentText()) + self.accept() From dd6df348946f232f61e7614d5234abb6c04b20ad Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 21 May 2024 11:54:36 -0500 Subject: [PATCH 56/67] WIP! --- QtPyHammer/ui/properties.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/QtPyHammer/ui/properties.py b/QtPyHammer/ui/properties.py index 7580eec..55cacad 100644 --- a/QtPyHammer/ui/properties.py +++ b/QtPyHammer/ui/properties.py @@ -3,7 +3,7 @@ class browser(QtWidgets.QDialog): def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) - self.setWindowTitle("QtPyHammer Properties") + self.setWindowTitle("QtPyHammer Properties - WIP") self.box1 = QtWidgets.QLabel("Render Mode:") self.render_mod_combo_box = QtWidgets.QComboBox() @@ -43,6 +43,6 @@ def __init__(self, parent): def on_ok_clicked(self): - render_mod_index = self.render_mod_combo_box.currentIndex() - lang.setLanguage(self.lang_combo_box.currentText()) + # render_mod_index = self.render_mod_combo_box.currentIndex() + # lang.setLanguage(self.lang_combo_box.currentText()) self.accept() From f0a11c35288b465e0e2933598ecb25cc134aa9ab Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 21 May 2024 12:06:03 -0500 Subject: [PATCH 57/67] Create config_parser.py --- QtPyHammer/utilities/config_parser.py | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 QtPyHammer/utilities/config_parser.py diff --git a/QtPyHammer/utilities/config_parser.py b/QtPyHammer/utilities/config_parser.py new file mode 100644 index 0000000..a16a18e --- /dev/null +++ b/QtPyHammer/utilities/config_parser.py @@ -0,0 +1,47 @@ +import os +import sys + +import valvefgd +from PyQt5 import QtCore, QtWidgets + +from QtPyHammer.ui.core import MainWindow +from QtPyHammer.ui.user_preferences.theme import load_theme + +def load_ini(ini): + # perhaps return an encapsulated QSettings + # with more direct access to variables (convert from default string etc.) + # it would also be handy to have defaults saved in the code, so we can restore + return QtCore.QSettings(ini, QtCore.QSettings.IniFormat) + +def get_theme(): + return theme + +def __init__(self, argv): + self.folder = os.path.dirname(__file__) + self.preferences = load_ini("configs/preferences.ini") + game = self.preferences.value("Game", "Team Fortress 2") + self.game_config = load_ini(f"configs/games/{game}.ini") + self.hotkeys = load_ini("configs/controls/hammer.ini") + self.themes = dict() + # ^ {theme_name: theme} + for filename in os.listdir("configs/themes/"): + theme_name = filename.rpartition(".")[0] # filename without extention + self.themes[theme_name] = load_theme(f"configs/themes/{filename}") + theme = self.preferences.value("Theme", "default") + if theme not in self.themes: + theme = "default" + self.setStyle(QtWidgets.QStyleFactory.create("Fusion")) + self.setPalette(self.themes[theme]) + if sys.platform == "win32": + reg = QtCore.QSettings(r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", + QtCore.QSettings.NativeFormat) + if reg.value("AppsUseLightTheme") == 0: # windows system darkmode + dark_theme = f"{theme}_dark" + if dark_theme not in self.themes: + dark_theme = "default_dark" + self.setPalette(self.themes[dark_theme]) + self.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }") + # ^ TODO: allow themes to include .css files + # -- and have them locked to individual widgets? + fgd_file = self.game_config.value("Hammer/GameData0") + self.fgd = valvefgd.parser.FgdParse(fgd_file) From 5520d2f216d618e3deb8ec5dfd8011c8c5a79e8c Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 21 May 2024 14:39:11 -0500 Subject: [PATCH 58/67] Update config_parser.py --- QtPyHammer/utilities/config_parser.py | 34 +++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/QtPyHammer/utilities/config_parser.py b/QtPyHammer/utilities/config_parser.py index a16a18e..0379757 100644 --- a/QtPyHammer/utilities/config_parser.py +++ b/QtPyHammer/utilities/config_parser.py @@ -14,16 +14,11 @@ def load_ini(ini): return QtCore.QSettings(ini, QtCore.QSettings.IniFormat) def get_theme(): - return theme - -def __init__(self, argv): - self.folder = os.path.dirname(__file__) - self.preferences = load_ini("configs/preferences.ini") - game = self.preferences.value("Game", "Team Fortress 2") - self.game_config = load_ini(f"configs/games/{game}.ini") - self.hotkeys = load_ini("configs/controls/hammer.ini") - self.themes = dict() - # ^ {theme_name: theme} + return theme + +def load_theme(): + self.themes = dict() + # ^ {theme_name: theme} for filename in os.listdir("configs/themes/"): theme_name = filename.rpartition(".")[0] # filename without extention self.themes[theme_name] = load_theme(f"configs/themes/{filename}") @@ -43,5 +38,20 @@ def __init__(self, argv): self.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }") # ^ TODO: allow themes to include .css files # -- and have them locked to individual widgets? - fgd_file = self.game_config.value("Hammer/GameData0") - self.fgd = valvefgd.parser.FgdParse(fgd_file) + +def load_fgd(): + fgd_file = self.game_config.value("Hammer/GameData0") + self.fgd = valvefgd.parser.FgdParse(fgd_file) + +def load_configs(): + self.folder = os.path.dirname(__file__) + self.preferences = load_ini("configs/preferences.ini") + game = self.preferences.value("Game", "Team Fortress 2") + self.game_config = load_ini(f"configs/games/{game}.ini") + self.hotkeys = load_ini("configs/controls/hammer.ini") + load_theme() + load_fgd() + +def __init__(self, argv): + load_configs() + From 9d7cfd1255a9753bb2171055819b39108d2529a1 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 21 May 2024 19:51:30 -0500 Subject: [PATCH 59/67] check if file path not empty! --- QtPyHammer/ui/compile.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index e08cffc..124799a 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -1,6 +1,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets from ..utilities import lang +from ..ui import popup import subprocess class browser(QtWidgets.QDialog): @@ -70,6 +71,10 @@ def on_ok_clicked(self): game_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf' file_path = self.textbox.text() + if not file_path: + no_text_popup = popup.browser(parent=self, popuptext="Error", msgtext="File path cannot be empty") + no_text_popup.show() + return bsp_index = self.bsp_combo_box.currentIndex() vis_index = self.vis_combo_box.currentIndex() rad_index = self.rad_combo_box.currentIndex() From c58284318dc579c149ceacdab3d4266f3b729548 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 21 May 2024 20:28:43 -0500 Subject: [PATCH 60/67] raycast --- QtPyHammer/ui/viewport.py | 11 ++++---- QtPyHammer/ui/workspace.py | 25 +++++++++++++---- QtPyHammer/utilities/raycast.py | 49 +++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 QtPyHammer/utilities/raycast.py diff --git a/QtPyHammer/ui/viewport.py b/QtPyHammer/ui/viewport.py index e48c780..5f1b224 100644 --- a/QtPyHammer/ui/viewport.py +++ b/QtPyHammer/ui/viewport.py @@ -130,17 +130,17 @@ def resizeGL(self, width, height): # Qt Signals def do_raycast(self, click_x, click_y): - camera_right = vector.vec3(x=1).rotate(*-self.camera.rotation) - camera_up = vector.vec3(z=1).rotate(*-self.camera.rotation) - camera_forward = vector.vec3(y=1).rotate(*-self.camera.rotation) + camera_right = vector.vec3(x=1).rotate(1) + camera_up = vector.vec3(z=1).rotate(1) + camera_forward = vector.vec3(y=1).rotate(1) width, height = self.width(), self.height() x_offset = camera_right * ((click_x * 2 - width) / width) x_offset *= width / height # aspect ratio y_offset = camera_up * ((click_y * 2 - height) / height) - fov_scalar = math.tan(math.radians(self.render_manager.field_of_view / 2)) + fov_scalar = math.tan(math.radians(90 / 2)) x_offset *= fov_scalar y_offset *= fov_scalar - ray_origin = self.camera.position + ray_origin = camera.freecam.position ray_direction = camera_forward + x_offset + y_offset return ray_origin, ray_direction @@ -178,7 +178,6 @@ def mouseReleaseEvent(self, event): x = self.width() / 2 y = self.height() / 2 ray_origin, ray_direction = self.do_raycast(x, self.height() - y) - self.raycast.emit(ray_origin, ray_direction) super(MapViewport3D, self).mouseReleaseEvent(event) def wheelEvent(self, event): diff --git a/QtPyHammer/ui/workspace.py b/QtPyHammer/ui/workspace.py index 795505b..e10a18c 100644 --- a/QtPyHammer/ui/workspace.py +++ b/QtPyHammer/ui/workspace.py @@ -1,9 +1,9 @@ """QtPyHammer Workspace that holds and manages an open .vmf file""" import enum - -from PyQt5 import QtWidgets - +from PyQt5 import QtWidgets, QtCore +from PyQt5.QtGui import QMouseEvent from . import viewport, popup +from ..utilities import raycast from ..ops.vmf import VmfInterface @@ -37,13 +37,26 @@ def __init__(self, vmf_path, new=True, parent=None): # ^ define the VmfInterface last so it can connect to everything # undo & redo is tied directly to the VmfInterface + def mousePressEvent(self, event: QMouseEvent): + """Override the mouse press event to handle selection""" + if event.button() == QtCore.Qt.LeftButton: + # Convert the mouse position to normalized device coordinates + ndc_x = (2.0 * event.x()) / self.viewport.width() - 1.0 + ndc_y = 1.0 - (2.0 * event.y()) / self.viewport.height() + + # Use a raycasting method to find the selection + ray_origin, ray_direction = viewport.MapViewport3D.do_raycast(self, ndc_x, ndc_y) + self.select(ray_origin, ray_direction) + def select(self, ray_origin, ray_direction): """Get the object hit by ray""" ray_length = self.viewport.render_manager.draw_distance ray = raycast.Ray(ray_origin, ray_direction, ray_length) - selection = raycast.raycast(ray, self.map_file) - self.map_file.selection.add(selection) - # TODO: highlight selection in renderer + objects = self.map_file.get_objects() # Access objects from VmfInterface + selection = raycast(ray, objects) + if selection: + self.selection.add(selection) + # TODO: highlight selection in renderer def save_to_file(self): print(f"Saving {self.filename}... ", end="") diff --git a/QtPyHammer/utilities/raycast.py b/QtPyHammer/utilities/raycast.py new file mode 100644 index 0000000..1fdf988 --- /dev/null +++ b/QtPyHammer/utilities/raycast.py @@ -0,0 +1,49 @@ +import math + +class Ray: + def __init__(self, origin, direction, length): + self.origin = origin + self.direction = direction + self.length = length + +def ray_aabb_intersection(ray, aabb_min, aabb_max): + tmin = (aabb_min[0] - ray.origin[0]) / ray.direction[0] + tmax = (aabb_max[0] - ray.origin[0]) / ray.direction[0] + if tmin > tmax: + tmin, tmax = tmax, tmin + + tymin = (aabb_min[1] - ray.origin[1]) / ray.direction[1] + tymax = (aabb_max[1] - ray.origin[1]) / ray.direction[1] + if tymin > tymax: + tymin, tymax = tymax, tymin + + if (tmin > tymax) or (tymin > tmax): + return False + + if tymin > tmin: + tmin = tymin + if tymax < tmax: + tmax = tymax + + tzmin = (aabb_min[2] - ray.origin[2]) / ray.direction[2] + tzmax = (aabb_max[2] - ray.origin[2]) / ray.direction[2] + if tzmin > tzmax: + tzmin, tzmax = tzmax, tzmin + + if (tmin > tzmax) or (tzmin > tmax): + return False + + if tzmin > tmin: + tmin = tzmin + if tzmax < tmax: + tmax = tzmax + + return (tmin < ray.length) and (tmax > 0) + +def raycast(ray, objects): + for obj in objects: + aabb_min = obj.bounding_box_min # Assuming these are lists + aabb_max = obj.bounding_box_max + if ray_aabb_intersection(ray, aabb_min, aabb_max): + return obj # Return the first object hit by the ray + return None From ce11ff0f09d4de3b3b6780e6bcd41ba90448af01 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Wed, 22 May 2024 11:11:02 -0500 Subject: [PATCH 61/67] Update config_parser.py --- QtPyHammer/utilities/config_parser.py | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/QtPyHammer/utilities/config_parser.py b/QtPyHammer/utilities/config_parser.py index 0379757..9c72412 100644 --- a/QtPyHammer/utilities/config_parser.py +++ b/QtPyHammer/utilities/config_parser.py @@ -8,9 +8,9 @@ from QtPyHammer.ui.user_preferences.theme import load_theme def load_ini(ini): - # perhaps return an encapsulated QSettings + # Perhaps return an encapsulated QSettings # with more direct access to variables (convert from default string etc.) - # it would also be handy to have defaults saved in the code, so we can restore + # It would also be handy to have defaults saved in the code, so we can restore return QtCore.QSettings(ini, QtCore.QSettings.IniFormat) def get_theme(): @@ -18,26 +18,26 @@ def get_theme(): def load_theme(): self.themes = dict() - # ^ {theme_name: theme} - for filename in os.listdir("configs/themes/"): - theme_name = filename.rpartition(".")[0] # filename without extention - self.themes[theme_name] = load_theme(f"configs/themes/{filename}") - theme = self.preferences.value("Theme", "default") - if theme not in self.themes: - theme = "default" - self.setStyle(QtWidgets.QStyleFactory.create("Fusion")) - self.setPalette(self.themes[theme]) - if sys.platform == "win32": - reg = QtCore.QSettings(r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", - QtCore.QSettings.NativeFormat) - if reg.value("AppsUseLightTheme") == 0: # windows system darkmode - dark_theme = f"{theme}_dark" - if dark_theme not in self.themes: - dark_theme = "default_dark" - self.setPalette(self.themes[dark_theme]) - self.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }") - # ^ TODO: allow themes to include .css files - # -- and have them locked to individual widgets? + # ^ {theme_name: theme} + for filename in os.listdir("configs/themes/"): + theme_name = filename.rpartition(".")[0] # Filename without extension + self.themes[theme_name] = load_theme(f"configs/themes/{filename}") + theme = self.preferences.value("Theme", "default") + if theme not in self.themes: + theme = "default" + self.setStyle(QtWidgets.QStyleFactory.create("Fusion")) + self.setPalette(self.themes[theme]) + if sys.platform == "win32": + reg = QtCore.QSettings(r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", + QtCore.QSettings.NativeFormat) + if reg.value("AppsUseLightTheme") == 0: # Windows system dark mode + dark_theme = f"{theme}_dark" + if dark_theme not in self.themes: + dark_theme = "default_dark" + self.setPalette(self.themes[dark_theme]) + self.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }") + # ^ TODO: Allow themes to include .css files + # -- and have them locked to individual widgets? def load_fgd(): fgd_file = self.game_config.value("Hammer/GameData0") @@ -47,11 +47,11 @@ def load_configs(): self.folder = os.path.dirname(__file__) self.preferences = load_ini("configs/preferences.ini") game = self.preferences.value("Game", "Team Fortress 2") - self.game_config = load_ini(f"configs/games/{game}.ini") + self.game_config = load_ini(f"configs/game_{game}.ini") self.hotkeys = load_ini("configs/controls/hammer.ini") - load_theme() - load_fgd() def __init__(self, argv): load_configs() + load_fgd() + load_theme() From 968cca1ecd295b06fb5b91dd70558efca73baf1d Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 23 May 2024 10:10:11 -0500 Subject: [PATCH 62/67] Add language --- configs/preferences.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/preferences.ini b/configs/preferences.ini index b27790b..f682c61 100644 --- a/configs/preferences.ini +++ b/configs/preferences.ini @@ -1,6 +1,7 @@ [General] Game=Team Fortress 2 Theme=light_mode +Language=English [Input] MouseSensitivity=2.0 From 1d6cf4f6b3a2ad63fbefb81aa34253a4e8cf50f1 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 23 May 2024 10:11:45 -0500 Subject: [PATCH 63/67] Add lang --- hammer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hammer.py b/hammer.py index 5662249..77ec78d 100644 --- a/hammer.py +++ b/hammer.py @@ -25,6 +25,7 @@ def __init__(self, argv): self.folder = os.path.dirname(__file__) self.preferences = load_ini("configs/preferences.ini") game = self.preferences.value("Game", "Team Fortress 2") + lang = self.preferences.value("Language", "English") self.game_config = load_ini(f"configs/games/{game}.ini") self.hotkeys = load_ini("configs/controls/hammer.ini") self.themes = dict() From 9d9bc8a4d5b91fe97e53e446010c34321d4e75b9 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 23 May 2024 10:12:46 -0500 Subject: [PATCH 64/67] Update lang.py --- QtPyHammer/utilities/lang.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index 97494c3..0f573f7 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -1,4 +1,8 @@ -usingLanguage = "english" # Default language +from PyQt5 import QtCore, QtGui, QtWidgets + +app = QtWidgets.QApplication.instance() + +usingLanguage = app.lang # Default language def setLanguage(language): global usingLanguage From 760b27834b631fb6f0066739a6d63c36fa03d374 Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 23 May 2024 10:17:49 -0500 Subject: [PATCH 65/67] Delete QtPyHammer/utilities/config_parser.py --- QtPyHammer/utilities/config_parser.py | 57 --------------------------- 1 file changed, 57 deletions(-) delete mode 100644 QtPyHammer/utilities/config_parser.py diff --git a/QtPyHammer/utilities/config_parser.py b/QtPyHammer/utilities/config_parser.py deleted file mode 100644 index 9c72412..0000000 --- a/QtPyHammer/utilities/config_parser.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys - -import valvefgd -from PyQt5 import QtCore, QtWidgets - -from QtPyHammer.ui.core import MainWindow -from QtPyHammer.ui.user_preferences.theme import load_theme - -def load_ini(ini): - # Perhaps return an encapsulated QSettings - # with more direct access to variables (convert from default string etc.) - # It would also be handy to have defaults saved in the code, so we can restore - return QtCore.QSettings(ini, QtCore.QSettings.IniFormat) - -def get_theme(): - return theme - -def load_theme(): - self.themes = dict() - # ^ {theme_name: theme} - for filename in os.listdir("configs/themes/"): - theme_name = filename.rpartition(".")[0] # Filename without extension - self.themes[theme_name] = load_theme(f"configs/themes/{filename}") - theme = self.preferences.value("Theme", "default") - if theme not in self.themes: - theme = "default" - self.setStyle(QtWidgets.QStyleFactory.create("Fusion")) - self.setPalette(self.themes[theme]) - if sys.platform == "win32": - reg = QtCore.QSettings(r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", - QtCore.QSettings.NativeFormat) - if reg.value("AppsUseLightTheme") == 0: # Windows system dark mode - dark_theme = f"{theme}_dark" - if dark_theme not in self.themes: - dark_theme = "default_dark" - self.setPalette(self.themes[dark_theme]) - self.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }") - # ^ TODO: Allow themes to include .css files - # -- and have them locked to individual widgets? - -def load_fgd(): - fgd_file = self.game_config.value("Hammer/GameData0") - self.fgd = valvefgd.parser.FgdParse(fgd_file) - -def load_configs(): - self.folder = os.path.dirname(__file__) - self.preferences = load_ini("configs/preferences.ini") - game = self.preferences.value("Game", "Team Fortress 2") - self.game_config = load_ini(f"configs/game_{game}.ini") - self.hotkeys = load_ini("configs/controls/hammer.ini") - -def __init__(self, argv): - load_configs() - load_fgd() - load_theme() - From 3f96ca18a751c291413e76a2fc010e9c175c667d Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Thu, 23 May 2024 10:27:47 -0500 Subject: [PATCH 66/67] Update compile.py --- QtPyHammer/ui/compile.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index e08cffc..1b5af08 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -6,6 +6,7 @@ class browser(QtWidgets.QDialog): def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) + app = QtWidgets.QApplication.instance() self.setWindowTitle("Run Map") # Add QLabel widgets @@ -15,7 +16,7 @@ def __init__(self, parent): self.bsp_combo_box.addItem(lang.langNo()) self.bsp_combo_box.addItem(lang.langNormal()) self.bsp_combo_box.addItem("Only Entities") - self.bsp_combo_box.setCurrentIndex(self.bsp_combo_box.findText("Normal")) + self.bsp_combo_box.setCurrentIndex(self.bsp_combo_box.findText(lang.langNormal)) self.box2 = QtWidgets.QLabel("Run VIS:") self.vis_combo_box = QtWidgets.QComboBox() @@ -52,7 +53,7 @@ def __init__(self, parent): cancel_button = QtWidgets.QPushButton("Cancel") cancel_button.clicked.connect(self.reject) bottom_row.addWidget(cancel_button) - ok_button = QtWidgets.QPushButton("Ok") + ok_button = QtWidgets.QPushButton(lang.langOk()) ok_button.clicked.connect(self.on_ok_clicked) ok_button.setDefault(True) bottom_row.addWidget(ok_button) @@ -63,9 +64,9 @@ def __init__(self, parent): self.adjustSize() def on_ok_clicked(self): - vbsp_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vbsp.exe' - vvis_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vvis.exe' - vrad_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\vrad.exe' + vbsp_path = app.game_config.value("Hammer/BSP", "Team Fortress 2/bin/vbsp.exe") + vvis_path = app.game_config.value("Hammer/Vis", "Team Fortress 2/bin/vvis.exe") + vrad_path = app.game_config.value("Hammer/Light", "Team Fortress 2/bin/vrad.exe") game_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf' file_path = self.textbox.text() From 7a5d96c9cab36bd27311915de87f0b4428f08d4f Mon Sep 17 00:00:00 2001 From: strubium <113206902+strubium@users.noreply.github.com> Date: Tue, 18 Jun 2024 13:36:03 -0500 Subject: [PATCH 67/67] Done! --- QtPyHammer/ui/compile.py | 13 ++++---- QtPyHammer/ui/core.py | 52 ++++++++++++++++++------------- QtPyHammer/ui/entity.py | 2 +- QtPyHammer/ui/popup.py | 1 + QtPyHammer/ui/properties.py | 11 ++++--- QtPyHammer/ui/texture_browser.py | 9 ++++-- QtPyHammer/ui/viewport.py | 4 +-- QtPyHammer/ui/workspace.py | 3 +- QtPyHammer/utilities/lang.py | 5 +-- QtPyHammer/utilities/obj.py | 2 +- QtPyHammer/utilities/physics.py | 2 ++ configs/games/Team Fortress 2.ini | 8 ++--- hammer.py | 1 - 13 files changed, 64 insertions(+), 49 deletions(-) diff --git a/QtPyHammer/ui/compile.py b/QtPyHammer/ui/compile.py index 1b5af08..3fdef10 100644 --- a/QtPyHammer/ui/compile.py +++ b/QtPyHammer/ui/compile.py @@ -6,7 +6,7 @@ class browser(QtWidgets.QDialog): def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) - app = QtWidgets.QApplication.instance() + self.setWindowTitle("Run Map") # Add QLabel widgets @@ -16,7 +16,7 @@ def __init__(self, parent): self.bsp_combo_box.addItem(lang.langNo()) self.bsp_combo_box.addItem(lang.langNormal()) self.bsp_combo_box.addItem("Only Entities") - self.bsp_combo_box.setCurrentIndex(self.bsp_combo_box.findText(lang.langNormal)) + self.bsp_combo_box.setCurrentIndex(self.bsp_combo_box.findText(lang.langNormal())) self.box2 = QtWidgets.QLabel("Run VIS:") self.vis_combo_box = QtWidgets.QComboBox() @@ -64,11 +64,12 @@ def __init__(self, parent): self.adjustSize() def on_ok_clicked(self): - vbsp_path = app.game_config.value("Hammer/BSP", "Team Fortress 2/bin/vbsp.exe") - vvis_path = app.game_config.value("Hammer/Vis", "Team Fortress 2/bin/vvis.exe") - vrad_path = app.game_config.value("Hammer/Light", "Team Fortress 2/bin/vrad.exe") + preferences = QtWidgets.QApplication.instance().game_config + vbsp_path = preferences.value("Hammer/BSP", r"C:/Program Files (x86)/Steam/steamapps/common/Team Fortress 2/bin/vbsp.exe") + vvis_path = preferences.value("Hammer/Vis", r"C:/Program Files (x86)/Steam/steamapps/common/Team Fortress 2/bin/vvis.exe") + vrad_path = preferences.value("Hammer/Light", r"C:/Program Files (x86)/Steam/steamapps/common/Team Fortress 2/bin/vrad.exe") - game_path = r'C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf' + game_path = preferences.value("General/GameDir", r"C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf") file_path = self.textbox.text() bsp_index = self.bsp_combo_box.currentIndex() diff --git a/QtPyHammer/ui/core.py b/QtPyHammer/ui/core.py index cf572ae..b5ba7bf 100644 --- a/QtPyHammer/ui/core.py +++ b/QtPyHammer/ui/core.py @@ -4,18 +4,14 @@ from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtGui import QIcon - from .. import ops from ..ui import entity, popup, texture_browser, compile, properties from ..ui import workspace from ..utilities import lang - class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): - - super(QtWidgets.QMainWindow, self).__init__(parent) global current_dir self.setWindowIcon(QtGui.QIcon('HammerLogo.png')) @@ -38,16 +34,28 @@ def __init__(self, parent=None): self.main_menu = QtWidgets.QMenuBar() file_menu = self.main_menu.addMenu(lang.langFile()) self.actions["File/New"] = file_menu.addAction("&New") - def new_file(): ops.new_file(self) + + def new_file(): + ops.new_file(self) + self.actions["File/New"].triggered.connect(new_file) self.actions["File/Open"] = file_menu.addAction("&Open") - def open_files(): ops.open_files(self, self.map_browser) + + def open_files(): + ops.open_files(self, self.map_browser) + self.actions["File/Open"].triggered.connect(open_files) self.actions["File/Save"] = file_menu.addAction("&Save") - def save_file(): ops.save_file(self, self.map_browser) + + def save_file(): + ops.save_file(self, self.map_browser) + self.actions["File/Save"].triggered.connect(save_file) self.actions["File/Save As"] = file_menu.addAction("Save &As") - def save_file_as(): ops.save_file_as(self, self.map_browser) + + def save_file_as(): + ops.save_file_as(self, self.map_browser) + self.actions["File/Save As"].triggered.connect(save_file_as) file_menu.addSeparator() # self.import_menu = file_menu.addMenu("Import") @@ -263,25 +271,27 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # self.actions["Help/Offline"].triggered.connect(ui. help_menu.addSeparator() self.actions["Help/About QPH"] = help_menu.addAction("About QtPyHammer") - about_popup = popup.browser(parent=self, popuptext="About", msgtext="A Python alternative to Valve Hammer Editor 4.x, forked from QtPyHammer\n\nVersion: v0.0.5forked") + about_popup = popup.browser(parent=self, popuptext="About", + msgtext="A Python alternative to Valve Hammer Editor 4.x, forked from QtPyHammer\n\nVersion: v0.0.5forked") self.actions["Help/About QPH"].triggered.connect(about_popup.show) self.actions["Help/About Qt"] = help_menu.addAction("About Qt") self.actions["Help/About Qt"].triggered.connect(lambda: open_url(QtCore.QUrl( - "https://github.com/spyder-ide/qtpy"))) + "https://github.com/spyder-ide/qtpy"))) # self.actions["Help/About Qt"].triggered.connect(ui. #QDialog self.actions["Help/License"] = help_menu.addAction("License") self.actions["Help/License"].triggered.connect(lambda: open_url(QtCore.QUrl( - "https://github.com/strubium/QtPyHammer/blob/master/LICENSE"))) + "https://github.com/strubium/QtPyHammer/blob/master/LICENSE"))) # self.actions["Help/License"].triggered.connect(ui. #QDialog self.actions["Help/Contributors"] = help_menu.addAction("Contributors") - self.actions["Help/Contributors"].triggered.connect(lambda: open_url(QtCore.QUrl("https://github.com/QtPyHammer-devs/QtPyHammer/graphs/contributors"))) + self.actions["Help/Contributors"].triggered.connect( + lambda: open_url(QtCore.QUrl("https://github.com/QtPyHammer-devs/QtPyHammer/graphs/contributors"))) self.actions["Help/QPH Wiki"] = help_menu.addAction("QtPyHammer Wiki") self.actions["Help/QPH Wiki"].triggered.connect(lambda: open_url(QtCore.QUrl( - "https://github.com/snake-biscuits/QtPyHammer/wiki"))) + "https://github.com/snake-biscuits/QtPyHammer/wiki"))) help_menu.addSeparator() self.actions["Help/VDC"] = help_menu.addAction("Valve Developer Community") self.actions["Help/VDC"].triggered.connect(lambda: open_url(QtCore.QUrl( - "https://developer.valvesoftware.com/wiki/Main_Page"))) + "https://developer.valvesoftware.com/wiki/Main_Page"))) # attach all actions to hotkeys app = QtWidgets.QApplication.instance() @@ -298,8 +308,8 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) # TOOLBARS key_tools = QtWidgets.QToolBar("Tools") - key_tools.setMovable(False) - button_1 = QtWidgets.QToolButton() # need icons (.png) + key_tools.setMovable(True) + button_1 = QtWidgets.QToolButton() # need icons (.png) button_1.setToolTip("Toggle 2D grid visibility") button_1.setIcon(QIcon("icons/2dHammerIcon")) button_1.setEnabled(False) @@ -319,20 +329,20 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) button_4.setEnabled(False) key_tools.addWidget(button_4) key_tools.addSeparator() - button_5= QtWidgets.QToolButton() + button_5 = QtWidgets.QToolButton() button_5.setToolTip("Load Window State") button_5.setEnabled(False) key_tools.addWidget(button_5) - button_6= QtWidgets.QToolButton() + button_6 = QtWidgets.QToolButton() button_6.setToolTip("Save Window State") button_6.setEnabled(False) key_tools.addWidget(button_6) key_tools.addSeparator() - button_7= QtWidgets.QToolButton() + button_7 = QtWidgets.QToolButton() button_7.setToolTip("Undo") button_7.setEnabled(False) key_tools.addWidget(button_7) - button_8= QtWidgets.QToolButton() + button_8 = QtWidgets.QToolButton() button_8.setToolTip("Redo") button_8.setEnabled(False) key_tools.addWidget(button_8) @@ -347,7 +357,7 @@ def save_file_as(): ops.save_file_as(self, self.map_browser) right_toolbar.setFixedWidth(115) label_1 = QtWidgets.QLabel("Select:") right_toolbar.addWidget(label_1) - right_toolbar.setMovable(False) + right_toolbar.setMovable(True) button_1 = QtWidgets.QPushButton("Groups") button_1.setFixedSize(100, 25) button_1.setEnabled(False) diff --git a/QtPyHammer/ui/entity.py b/QtPyHammer/ui/entity.py index 7c44a78..efaa315 100644 --- a/QtPyHammer/ui/entity.py +++ b/QtPyHammer/ui/entity.py @@ -112,7 +112,7 @@ def load_entity(self, index): # ADD SmartEdit toggle & tooltips outputs = [*filter(lambda o: isinstance(o, valvefgd.parser.FgdEntityOutput), entity.properties)] # split properly in some version of valvefgd (prob 1.0.0 but it's broken?) if len(inputs) > 0 or len(outputs) > 0: # OR ANY inputs recieved - logic_widget = QtWidgets.QWidget() # <- make it's own class + logic_widget = QtWidgets.QWidget() # <- make it its own class logic_widget.setLayout(QtWidgets.QVBoxLayout()) logic_widget.layout().addWidget(QtWidgets.QLabel("Inputs")) logic_widget.layout().addWidget(QtWidgets.QLabel("Outputs")) diff --git a/QtPyHammer/ui/popup.py b/QtPyHammer/ui/popup.py index cc6c275..fd56d74 100644 --- a/QtPyHammer/ui/popup.py +++ b/QtPyHammer/ui/popup.py @@ -1,6 +1,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets from ..utilities import lang + class browser(QtWidgets.QDialog): def __init__(self, parent, popuptext, msgtext): super(browser, self).__init__(parent, QtCore.Qt.Tool) diff --git a/QtPyHammer/ui/properties.py b/QtPyHammer/ui/properties.py index 55cacad..e9bf0cf 100644 --- a/QtPyHammer/ui/properties.py +++ b/QtPyHammer/ui/properties.py @@ -1,10 +1,12 @@ from PyQt5 import QtCore, QtGui, QtWidgets from ..utilities import lang + + class browser(QtWidgets.QDialog): def __init__(self, parent): super(browser, self).__init__(parent, QtCore.Qt.Tool) self.setWindowTitle("QtPyHammer Properties - WIP") - + self.box1 = QtWidgets.QLabel("Render Mode:") self.render_mod_combo_box = QtWidgets.QComboBox() self.render_mod_combo_box.setGeometry(200, 150, 120, 40) @@ -40,9 +42,8 @@ def __init__(self, parent): # Resize the dialog to fit the text self.adjustSize() - - + def on_ok_clicked(self): - # render_mod_index = self.render_mod_combo_box.currentIndex() - # lang.setLanguage(self.lang_combo_box.currentText()) + # render_mod_index = self.render_mod_combo_box.currentIndex() + # lang.setLanguage(self.lang_combo_box.currentText()) self.accept() diff --git a/QtPyHammer/ui/texture_browser.py b/QtPyHammer/ui/texture_browser.py index 76673e9..14cb2b6 100644 --- a/QtPyHammer/ui/texture_browser.py +++ b/QtPyHammer/ui/texture_browser.py @@ -16,7 +16,7 @@ def __init__(self, parent=None): main_layout = QtWidgets.QVBoxLayout() self.setWindowTitle("Texture Browser") self.setGeometry(780, 220, 360, 640) - # now this has scroll bar but it doesnt have flow layout + # now this has scroll bar, but it doesn't have flow layout scroll = QtWidgets.QScrollArea() groupbox = QtWidgets.QGroupBox("Textures") flow_layout = FlowLayout(margin=10) @@ -48,7 +48,7 @@ def __init__(self, parent=None): main_layout.addWidget(QtWidgets.QLabel("Search Options")) # main_layout.addWidget(QtWidgets.QLabel("Max:")) # main_layout.addWidget(QtWidgets.QLineEdit(self).setPlaceholderText("400").resize(280,40)) - + # list of checkboxes? # colour-range (hue) slider (.vtf reflectivity value) @@ -91,6 +91,7 @@ def search(self, keyword): search_popup.show() # TODO: doesnt filter yet + class FlowLayout(QtWidgets.QLayout): """A ``QLayout`` that aranges its child widgets horizontally and vertically. @@ -131,7 +132,8 @@ def takeAt(self, index): return self._item_list.pop(index) return None - def expandingDirections(self): + @staticmethod + def expandingDirections(): return QtCore.Qt.Orientations(QtCore.Qt.Orientation(0)) def hasHeightForWidth(self): @@ -201,6 +203,7 @@ def except_hook(cls, exception, traceback): """Get tracebacks for python called by Qt functions & classes""" sys.__excepthook__(cls, exception, traceback) + sys.excepthook = except_hook app = QtWidgets.QApplication(sys.argv) browser = TextureBrowser() diff --git a/QtPyHammer/ui/viewport.py b/QtPyHammer/ui/viewport.py index e48c780..100d496 100644 --- a/QtPyHammer/ui/viewport.py +++ b/QtPyHammer/ui/viewport.py @@ -75,7 +75,7 @@ def initializeGL(self): self.set_view_mode("textured") # sets shaders & GL state self.timer.start() - # calling the slot by it's name creates a QVariant Error + # calling the slot by its name creates a QVariant Error # which for some reason does not trace correctly @QtCore.pyqtSlot(str, name="setViewMode") # connected to UI def set_view_mode(self, view_mode): # C++: void setViewMode(QString) @@ -146,7 +146,7 @@ def do_raycast(self, click_x, click_y): # Rebound Qt Methods def keyPressEvent(self, event): # not registering arrow keys? - # BUG? auto repeat can "give the camera velocity" by jamming a key down virtually? + # BUG? auto-repeat can "give the camera velocity" by jamming a key down virtually? # ^ obsered once by @snake-biscuits self.keys.add(event.key()) diff --git a/QtPyHammer/ui/workspace.py b/QtPyHammer/ui/workspace.py index 795505b..689ced8 100644 --- a/QtPyHammer/ui/workspace.py +++ b/QtPyHammer/ui/workspace.py @@ -58,7 +58,8 @@ def save_to_file(self): error_popup = popup.browser(parent=self, popuptext="Error", msgtext="Error when saving") error_popup.show() raise exc - print("Saved!") + saved_popup = popup.browser(parent=self, popuptext="Status", msgtext="Saved") + saved_popup.show() self.never_saved = False def close(self): diff --git a/QtPyHammer/utilities/lang.py b/QtPyHammer/utilities/lang.py index 0f573f7..57db017 100644 --- a/QtPyHammer/utilities/lang.py +++ b/QtPyHammer/utilities/lang.py @@ -1,8 +1,5 @@ -from PyQt5 import QtCore, QtGui, QtWidgets -app = QtWidgets.QApplication.instance() - -usingLanguage = app.lang # Default language +usingLanguage = "English" # Default language def setLanguage(language): global usingLanguage diff --git a/QtPyHammer/utilities/obj.py b/QtPyHammer/utilities/obj.py index 298a53e..5c8913d 100644 --- a/QtPyHammer/utilities/obj.py +++ b/QtPyHammer/utilities/obj.py @@ -44,7 +44,7 @@ def raycast_intersects(self, ray_direction, ray_length): @staticmethod def load_from_file(filename) -> Obj: # noqa: C901 - """Creates a Obj object from the definition in filename""" + """Creates an Obj object from the definition in filename""" vertex_data = {"v": [], "vt": [], "vn": []} faces = [] current_object = None diff --git a/QtPyHammer/utilities/physics.py b/QtPyHammer/utilities/physics.py index 571a0a2..9bd1cf5 100644 --- a/QtPyHammer/utilities/physics.py +++ b/QtPyHammer/utilities/physics.py @@ -26,6 +26,8 @@ class AxisAlignedBoundingBox: maxs: vector.vec3 def __init__(self, mins: vector.vec3, maxs: vector.vec3): + self.max = None + self.min = None self.mins = vector.vec3(*mins) self.maxs = vector.vec3(*maxs) diff --git a/configs/games/Team Fortress 2.ini b/configs/games/Team Fortress 2.ini index c7944f7..255b219 100644 --- a/configs/games/Team Fortress 2.ini +++ b/configs/games/Team Fortress 2.ini @@ -1,8 +1,8 @@ [General] -GameDir=Team Fortress 2/tf +GameDir=C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf [Hammer] -BSP=Team Fortress 2/bin/vbsp.exe +BSP=C:/Program Files (x86)/Steam/steamapps/common/Team Fortress 2/bin/vbsp.exe BSPDir=Team Fortress 2/tf/maps CordonTexture=tools/toolsskybox DefaultLightmapScale=16 @@ -12,9 +12,9 @@ DefaultTextureScale=0.250000 GameData0=Team Fortress 2/bin/tf-puddy.fgd GameExe=Team Fortress 2/hl2.exe GameExeDir=Team Fortress 2 -Light=Team Fortress 2/bin/vrad.exe +Light=C:/Program Files (x86)/Steam/steamapps/common/Team Fortress 2/bin/vrad.exe MapDir=Team Fortress 2/tf/mapsrc MapFormat=4 MaterialExcludeCount=0 TextureFormat=5 -Vis=Team Fortress 2/bin/vvis.exe +Vis=C:/Program Files (x86)/Steam/steamapps/common/Team Fortress 2/bin/vvis.exe diff --git a/hammer.py b/hammer.py index 77ec78d..5662249 100644 --- a/hammer.py +++ b/hammer.py @@ -25,7 +25,6 @@ def __init__(self, argv): self.folder = os.path.dirname(__file__) self.preferences = load_ini("configs/preferences.ini") game = self.preferences.value("Game", "Team Fortress 2") - lang = self.preferences.value("Language", "English") self.game_config = load_ini(f"configs/games/{game}.ini") self.hotkeys = load_ini("configs/controls/hammer.ini") self.themes = dict()