Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev-1 #17

Merged
merged 73 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
026e312
general
strubium Apr 18, 2024
c501465
Core
strubium Apr 18, 2024
dc12cfa
stop the cap
strubium Apr 18, 2024
bf55478
La toolbar
strubium Apr 18, 2024
05f6236
Icons!
strubium Apr 19, 2024
309b849
More missing buttons
strubium Apr 19, 2024
172e8d3
Large Grid Icon
strubium Apr 19, 2024
7537bd8
Edit Toolbar
strubium Apr 19, 2024
f7bdf8b
Button
strubium Apr 19, 2024
c52d750
Revert "Button"
strubium Apr 19, 2024
b682467
Revert "Edit Toolbar"
strubium Apr 19, 2024
5e28b63
push local
strubium Apr 19, 2024
bd0793f
Popup system works!
strubium Apr 19, 2024
f20acdc
Error popup!
strubium Apr 19, 2024
6752672
Menu tile
strubium Apr 20, 2024
8ba8f9d
Popup system 2
strubium Apr 20, 2024
6e5584b
About page get popup too
strubium Apr 20, 2024
b5b9d7e
grey out not working buttons
strubium Apr 20, 2024
8b2527b
Add basic Compile window
strubium Apr 20, 2024
c11cc07
Make sure search text isnt empty
strubium Apr 20, 2024
e14c355
New right toolbar
strubium Apr 24, 2024
8c0647b
The dropdowns
strubium Apr 24, 2024
75a34ee
Cancel Button!
strubium Apr 24, 2024
b73092f
Fix + Default Dropdown
strubium Apr 24, 2024
bf98589
compiles (Kinda)
strubium Apr 25, 2024
2dbf3d6
arguments?
strubium Apr 25, 2024
7ff0e9e
basic lang system
strubium Apr 25, 2024
c797b41
google translate
strubium Apr 25, 2024
db27510
Compile with arg's
strubium Apr 27, 2024
4198132
VMF path textbox as workaround
strubium May 14, 2024
3d148ae
popup for entity browser
strubium May 15, 2024
b24b45c
Default arguments
strubium May 15, 2024
9594025
""
strubium May 15, 2024
a713c5d
fix
strubium May 19, 2024
c5b922a
More lang
strubium May 19, 2024
21b5920
Merge branch 'smeagle' into lang-basics
strubium May 19, 2024
ea91034
Merge pull request #1 from strubium/lang-basics
strubium May 19, 2024
0cdccb6
Merge pull request #2 from strubium/compile-window-overhall
strubium May 19, 2024
3c9f03e
Remove text label
strubium May 19, 2024
ee6864b
More possibility
strubium May 20, 2024
7951064
lang!
strubium May 20, 2024
98f45ba
Update
strubium May 20, 2024
5da9bdc
langOk
strubium May 20, 2024
cfc8dc4
Open a URL for the condributors
strubium May 20, 2024
3c8541d
Add plans to filter by a max amount
strubium May 20, 2024
87bccde
Russian from google translate
strubium May 20, 2024
f40112c
Create properties.py
strubium May 20, 2024
e8a67ca
Add render mode
strubium May 20, 2024
2a72a86
Text
strubium May 20, 2024
b969aad
Language menu
strubium May 20, 2024
527dc5d
Link Prop menu in core.py
strubium May 20, 2024
f413a4a
Spanish!
strubium May 20, 2024
6c733ba
File, edit, and tools lang
strubium May 20, 2024
2a3a105
Update core.py
strubium May 20, 2024
d578b95
Opps
strubium May 20, 2024
482fd51
Add files via upload
strubium May 20, 2024
b687f75
Add logo
strubium May 20, 2024
353d7e6
save
strubium May 20, 2024
dd6df34
WIP!
strubium May 21, 2024
6ffb9e3
Merge pull request #3 from strubium/prop_menu
strubium May 21, 2024
f0a11c3
Create config_parser.py
strubium May 21, 2024
5520d2f
Update config_parser.py
strubium May 21, 2024
9d7cfd1
check if file path not empty!
strubium May 22, 2024
c582843
raycast
strubium May 22, 2024
ce11ff0
Update config_parser.py
strubium May 22, 2024
968cca1
Add language
strubium May 23, 2024
1d6cf4f
Add lang
strubium May 23, 2024
9d9bc8a
Update lang.py
strubium May 23, 2024
760b278
Delete QtPyHammer/utilities/config_parser.py
strubium May 23, 2024
3f96ca1
Update compile.py
strubium May 23, 2024
7a5d96c
Done!
strubium Jun 18, 2024
d6ac0d6
Merge pull request #4 from strubium/more-popups
strubium Jun 18, 2024
e6b0908
Merge pull request #16 from strubium/config_parser
strubium Jun 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,5 @@ dmypy.json

# Visual Studio Code settings
.vscode/
/.vs
/.idea
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion QtPyHammer/ops/vmf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion QtPyHammer/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from . import user_preferences
from . import viewport
from . import workspace
from . import popup
from . import compile


__all__ = ["core", "entity", "user_preferences", "viewport", "workspace"]
__all__ = ["core", "entity", "user_preferences", "viewport", "workspace", "popup", "compile"]
116 changes: 116 additions & 0 deletions QtPyHammer/ui/compile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from PyQt5 import QtCore, QtGui, QtWidgets

from ..utilities import lang
from ..ui import popup
import subprocess

class browser(QtWidgets.QDialog):
def __init__(self, parent):
super(browser, self).__init__(parent, QtCore.Qt.Tool)

self.setWindowTitle("Run Map")

# Add QLabel widgets
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(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.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(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(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)
self.textbox.resize(280,40)

# Layout setup
base_layout = QtWidgets.QVBoxLayout()
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)
base_layout.addWidget(self.box4)
base_layout.addWidget(self.textbox)
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(lang.langOk())
ok_button.clicked.connect(self.on_ok_clicked)
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()

def on_ok_clicked(self):
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 = preferences.value("General/GameDir", 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()

vbsp_arguments = ['-game', game_path]
vvis_arguments = ['-game', game_path]
vrad_arguments = ['-game', game_path]

if bsp_index == 0:
vbsp_arguments += ['-leaktest', file_path]
elif bsp_index == 1:
vbsp_arguments += ['-leaktest', file_path]
elif bsp_index == 2:
vbsp_arguments += ['-leaktest', '-onlyents', file_path]

if vis_index == 0:
vvis_arguments += [file_path]
elif vis_index == 1:
vvis_arguments += [file_path]
elif vis_index == 2:
vvis_arguments += ['-fast', file_path]

if rad_index == 0:
vrad_arguments += [file_path]
elif rad_index == 1:
vrad_arguments += [file_path]
elif rad_index == 2:
vrad_arguments += ['-fast', file_path]

vbsp_command = [vbsp_path] + vbsp_arguments
vvis_command = [vvis_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)
self.accept()
161 changes: 117 additions & 44 deletions QtPyHammer/ui/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@
import os

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QIcon

from .. import ops
from ..ui import entity
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.setWindowTitle("QtPyHammer")
self.setWindowIcon(QtGui.QIcon('HammerLogo.png'))
self.setWindowTitle("QtPyHammer - Fork")
self.setMinimumSize(640, 480)
self.setTabPosition(QtCore.Qt.TopDockWidgetArea, QtWidgets.QTabWidget.North)
self.tabs = QtWidgets.QTabWidget()
Expand All @@ -29,18 +32,30 @@ 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)

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")
Expand All @@ -52,21 +67,21 @@ 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)
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("Compile")
self.actions["File/Compile"].setEnabled(False)
# self.actions["File/Compile"].triggered.connect(ui.compile)
self.actions["File/Compile"] = file_menu.addAction(lang.langCompile())
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"] = 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("Undo")
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
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...")
Expand Down Expand Up @@ -100,7 +115,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(
Expand All @@ -113,8 +128,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, 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
self.actions["Tools/Entity to Brush"] = tools_menu.addAction("&Move to World")
Expand Down Expand Up @@ -256,23 +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")
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\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"].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)
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)
# self.actions["Help/Contributors"].triggered.connect(ui. #QDialog
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")))
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")))
self.actions["Help/TF2Maps"] = help_menu.addAction("TF2Maps.net")
self.actions["Help/TF2Maps"].triggered.connect(lambda: open_url(QtCore.QUrl("https://tf2maps.net")))
"https://developer.valvesoftware.com/wiki/Main_Page")))

# attach all actions to hotkeys
app = QtWidgets.QApplication.instance()
Expand All @@ -288,27 +307,81 @@ 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)
# 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()
key_tools = QtWidgets.QToolBar("Tools")
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)
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()

# 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 <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(True)
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)
Expand Down
Loading
Loading