QuarkX
Updated 24 Dec 2021
|
Upper levels: - QuArK Information Base - 4. The Source Code |
4.8. QuarkX |
[ | - - ]
Index |
What QuArK expects to find from Python |
Armin Rigo - 05 Apr 2018 | [ Top ] |
When QuArK starts, it initializes the Python interpreter and loads the package called quarkpy . This should be a subdirectory in the directory that contains quark.exe . Once this package (i.e. the file quarkpy\__init__.py ) has been loaded, QuArK calls its function RunQuArK() . See the file __init__.py for more details about the start-up process. To answer to user actions, QuArK needs to call Python code. This is usually done by setting some variables that QuArK knows how to read so that they point to a Python function. In some cases, however, this is not possible; these cases are handled by the module qmacro.py which contains functions with special names, all beginning with MACRO_ . See below for a list of all macros that QuArK expects to find there. QuArK exposes all its features to Python code through the built-in module quarkx . Constant values and various utilities are found in the Python modules qutils.py and qeditor.py . For examples about all the following stuff, see the .py files included with QuArK. |
QuArK-specific functions of the module quarkx |
Armin Rigo - 07 Aug 2021 | [ Top ] |
|
Functions of the module quarkx that build special objects |
Armin Rigo - 05 Aug 2020 | [ Top ] |
|
Logging functions of the module quarkx |
DanielPharos - 05 Apr 2018 | [ Top ] |
The default filename for the main log file is 'QUARK.LOG'.
|
Texture functions of the module quarkx |
cdunde - 24 Dec 2021 | [ Top ] |
Functions for actually changing a texture image, weather it be in the Model Editor as a skin texture or the Map Editor as a face texture (not implemented yet). These can also be used to set and apply dialog pen colors to change a texture or in conjunction with a view's Canvas objects to set their various color functions. In addition, other useful related functions can be found in the quarkpy\qutils.py file Texture and Color Utilities section such as: As well as specific functions for the Model Editor in its quarkpy/mdlutils.py file for: Argument Definitions and examples to use for these functions:
|
Various general-purpose functions of the module quarkx |
Armin Rigo - 12 Dec 2021 | [ Top ] |
|
Read-only variables of the module quarkx |
Armin Rigo - 05 Aug 2020 | [ Top ] |
|
Read-write variables of the module quarkx |
Armin Rigo - 05 Apr 2018 | [ Top ] |
|
Internal QuArK objects |
Armin Rigo - 05 Apr 2018 | [ Top ] |
Internal Objects are all the objects that QuArK works with, stores in files, and displays in tree views. Each Internal object has a name, which usually contains an extension like files. The extension is called the type of the object, and the part of the name before the extension is the shortname. Internal File Objects are the Internal Objects that correspond directly to a file, e.g. BSP or QRK files. Such objects have the file extension as type, e.g. " .bsp " or " .qrk ". Non-File Objects are internals to a file, and cannot be stored into their own file. For example, polyhedrons and entities are Non-File. Such objects have a type that starts with " : " instead of " . ", e.g. " :p " for polyhedrons. Besides this, all Internal Objects have a list of Specifics/Arg, much like Quake entities, as well as sub-items, as displayed in tree views. See 'QObjects' for more information. |
Attributes common to all Internal objects |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Note that Internal Objects implement none of the operations like +,*,not, etc. Trying to use them, or even using an Internal Object in a boolean operation, will likely raise an Access Violation error. To test if a function returned an actual object or None , don’t write if obj:... but write if obj is not None:... |
Attributes common to Internal File objects |
Armin rigo - 01 Aug 2020 | [ Top ] |
All Internal File Objects have the following additional attributes.
Subclasses of Internal File Objects don’t have more attributes. Most information is stored as Specifics-Args pairs and in subitems. Three exceptions:
|
Attributes common to Internal objects of class "3DObject" |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Here are the additional attributes of Internal objects with "3DObject" in their class tuple. The Internal 3D Objects are the ones that have some kind of 3D position or shape. All objects present in the map editor’s tree view are Internal 3D Objects. This includes groups because you can move and resize whole groups.
|
Attributes common to Internal objects of class "TreeMap" |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Here are the additional attributes of Internal objects with "TreeMap" in their class tuple. All objects present in the map editor’s tree view are TreeMap objects, and no other one.
|
Attributes of Internal objects of class "Polyhedron" |
Armin Rigo - 05 Apr 2018 | [ Top ] |
Note: the class name "Polyhedron" is new in 5.0.c3. In version 5.0.c2, the name was in french, "Polyedre".
|
Attributes of Internal objects of class "Face" |
Armin Rigo - 05 Apr 2018 | [ Top ] |
These objects are polyhedron faces. They are often found within Polyhedron objects, but use the polyhedron’s faces attribute instead of its subitem method to find them, because:
|
Attributes of Internal objects of class "Duplicator" |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Here is the additional attribute of Internal objects with " Duplicator " in their class tuple.
|
Attributes of Internal objects of class "TreeMapBrush" |
Armin Rigo - 01 Aug 2020 | [ Top ] |
TreeMapBrush objects are all Quake's "Brush entities", that is, all entities with associated brushes. The top-level object worldspawn is a TreeMapBrush, and so are all doors, plats, etc. These objects have three additional read-only attributes.
|
Attributes of Internal objects of class "Bezier" |
Armin Rigo - 05 Apr 2018 | [ Top ] |
These objects are Bezier patches (for Quake 3). They can actually represent any "quilt" of m times n joined quadratic Bezier patches, where m or n can be zero (for Bezier lines). For more information about Bezier patches see 'Bezier.pas'.
|
Macros expected by QuArK in the module qmacro.py |
Armin Rigo - 05 Apr 2018 | [ Top ] |
|
3D Vector objects |
Armin Rigo - 01 Aug 2020 | [ Top ] |
3D Vector Objects are created with the function quarkx.vect . Vectors are immutable in the Python sense. Vector Objects usually represent 3D points or 3D vectors, but in some cases they are projections on a map view. See the second table below for the additional attributes that apply to projected vectors only. All vectors have a few attributes you can read, and you can use the arithmetic operations described below:
Note: do not compare two vectors with " v=w "! Instead, make their difference and check if the result is True or False with a boolean operation. About projected vectors: their x and y coordinates are pixels in the window, and the z coordinate represents the depth. Depending on the projection type, flat or perspective, the z coordinate has various meanings. You cannot tell which point is nearer by comparing their z values; instead, use the compare operators on the vectors themselves:
The control points of Bezier patches use an extension of the 3D vectors: 5D vectors. These vectors have two additional coordinates, representing the texture coordinates. 5D vectors have the same Python type as 3D vectors, and all operations you can do with 3D vectors can be done with 5D vectors too; here is the new stuff:
|
Quaternion objects |
DanielPharos - 05 Aug 2020 | [ Top ] |
Quaternions are four values that together represent a rotation in 3D space and a scaling. Use quarkx.quaternion to create quaternion. They are not immutable objects, because you can change values in individual cases, but in general they should be considered as immutable.
|
Matrix objects |
Armin Rigo - 05 Apr 2018 | [ Top ] |
3x3 matrices are used to represent linear mappings. Use quarkx.matrix to create matrices. They are not immutable objects, because you can change values in individual cases, but in general they should be considered as immutable.
|
The undo module |
Armin Rigo - 05 Apr 2018 | [ Top ] |
As a general rule, you must never directly modify map objects. This would prevent the user from undoing his actions. Instead, when you have changes to make, you must call quarkx.action() which returns a module object where you will find the functions described in the next table. Duplicate the objects you want to change using their copy() method, make changes in the copies, and use the following functions to give the new objects to QuArK’s undo mechanism. To finalize the undo call and action you must use the undo.ok(base, text) call. The base is the main object such as editor.Root and text is the string text message that will be posted to the editor's Undo / Redo list. One option does exist for this ok call for the text. In rare cases, the ability of the undo module to activate code that other functions do not, such as invlaidateallviews, the undo function can be called as described and finalized with its text argument like this undo.ok(base, "") giving no text within the two double quotes. This will still allow the acceptance of the undo action but will NOT post anything to the editor's Undo / Redo list.
|
The progressbar module |
Armin Rigo - 05 Apr 2018 | [ Top ] |
You create a progress bar by calling quarkx.progressbar(txt,count), which returns a copy of the module described in the following table.
|
Built-in process objects |
Armin Rigo - 05 Apr 2018 | [ Top ] |
A process object lets you know the state of a program executed by quarkx.runprogram . It has the following attributes:
Note that this object might become obsolete in a future version of QuArK. Don’t rely on it. The stdout and stderr mechanism can be used to know when console processes terminate. |
Image List objects |
Armin Rigo - 05 Apr 2018 | [ Top ] |
Image Lists are built with the function quarkx.loadimages. They are similar to immutable sequences of icons, but only the following operations are defined on them:
Do not use Image List objects in places where a sequence could normally be used, e.g. in for. Instead of for icon in imagelist: ... for i in range(0, len(imagelist)): icon = imagelist[i] ... |
Icon objects |
Armin Rigo - 05 Apr 2018 | [ Top ] |
Icon Objects are the individual items of Image Lists.
|
Windows (forms) |
Armin Rigo - 07 Aug 2021 | [ Top ] |
Window Objects (commonly called “ forms ”) are the Python objects with which you can control a window’s aspect. In the current versions, only the map and model editors are Window objects; other windows cannot be accessed from Python. Here are the attributes of Window objects.
|
Introduction to screen controls and panels |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Screen controls are the various units of a window design with which users interact. All screen controls - - map views, tree views, image displayers, data-entry forms, floating windows, etc. - - are distinct built-in object types, but they share common attributes. Note that toolbars are not screen controls in QuArK 5.0.c2, so they don’t have all these attributes, but this may change in a future version. Controls are not positioned on screen by setting coordinates. They are put into panels, which are screen controls themselves. Panels are dummy gray rectangles that can contains other screen controls and that know how to set their position. Usually, panels are nested, starting from the main panel, which covers the whole window except its border, its caption, and its menu bar. For example, in the map editor’s Classical layout, the main panel contains three controls: the two map view and a left-aligned panel, which in turn contains other panels, and so on. Panels are the only kind of screen controls that can contain other screen controls. Each panel knows how to align its own controls. There are two kinds of alignments a panel can perform: " full-size sections " and " padded to a border ". Within a panel, only subpanels can be padded to a border; other controls are always full-sized. A panel can be divided into sections, i.e. rows and columns, like a table. By default, there is only one row and one column, taking up the whole panel size. For each subcontrols, you choose in which section it goes, and it takes the whole size of the section. Row and column size is given with a percentage of the total width or height. This keeps the same proportions when the window is resized. The user can manually resize the sections. Panels can also contain border-padded subpanels. These subpanels are aligned so that they go along the whole left, top, right or bottom border. For left- and right-padded subpanels, you choose only the panel width, in pixels; for top- and bottom-padded subpanels, you choose only the panel height. The user can also resize these panels. The sizes are given in pixels and don’t change when the window is resized. Border-padded subpanels shrink the screen space allocated to sections. |
Attributes common to all screen controls |
Armin Rigo - 01 Aug 2020 | [ Top ] |
|
Additional attributes of Panel controls |
Armin Rigo - 05 Apr 2018 | [ Top ] |
|
Menu bars, pop-up menus and keyboard shortcuts |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Menus are not yet another type of built-in objects. Instead, they are completely defined with classic Python objects, and QuArK reads these objects’ attributes when it needs them to build the menu. A menu bar or a pop-up menu is a list of one Python class instance for each item. The items need not really be class instances, but QuArK expects them to have a few attributes, and instances of classes are, with modules, the only kind of object you can give the attributes you want. qmenu.py defines two classes, one for normal menu items and one for menu items that open pop-up menus. I recommend to always use instances of these classes to populate your menus. Please refer to qmenu.py for more information about the expected attributes. You set a Window’s menu bar by storing a list of instances of qmenu.popup into its menubar attribute. You can also assign keyboard shortcuts to menu items; however, this is not done by setting an attribute (e.g. shortcut) to the instances of the class qmenu.item . All shortcuts for a Window must be grouped in a dictionary that must be assigned to the Window’s shortcuts attribute. The dictionary should contain pairs "shortcutkey":menuitem, where "shortcutkey" is a string describing the key (e.g. "Ctrl+X") and menuitem is the item whose onclick attribute should be called. Although not required, I recommend that this menuitem appear somewhere in the menu bar, too. If it is the case, QuArK adds the shortcut key string to the right of the item in the menu. New in QuArK 5.5: a shortcut can be a number (a "virtual key code") as obtained in the configuration dialog box (page Map, Keys). These shortcuts must be put in the attribute numshortcuts. |
Callback functions in Python and Warning about circular references |
Armin Rigo - 01 Aug 2020 | [ Top ] |
At a lot of places, QuArK expects to find a callable Python object. For example, each menu item must have an attribute onclick that, if not None , will be called by QuArK. The arguments that the function should accept varies from case to case; for example, the menu item’s onclick is called with a single argument, which is the menu item itself. The call is made by simulating the Python command apply(onclick, args). This means that onclick doesn’t need to be a function; it can be anything that is valid to call with the arguments args. In the current Python code, it is often a method instead of a function: if you give onclick the value someobject.mymethod, that method will be called with one additional argument (often called self) before the normal ones given by QuArK: the object someobject itself. This is pretty useful in all cases where the arguments given by QuArK are not enough to really know what occurred. Typically, onclick will point to a method of the MapEditor object, so that we immediately know in which MapEditor instance we are. However, be careful about circular references: this technique makes a reference from the menu item’s onclick member to the given MapEditor instance, which in turn is likely to somehow reference the menu item through a pointer to the whole menu. In this kind of situation, neither the MapEditor instance nor the menu item will ever be freed from memory. This situation is allowed if you take care of breaking them: that’s why, when the MapEditor window is closed, a lot of its attributes are reset to None . This would free the menu, which in turn would let the MapEditor be freed. |
Floating toolbars, Toolbar panels, and Buttons |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Floating Toolbars correspond to a built-in type. You create toolbars with the method newtoolbar of Window objects. The user can move Floating toolbars and either dock them (put them along the border of the window) or make them float (appear as a small stand-alone window). Note that Toolbars are not screen controls, as mentionned above. Here are all their attributes.
Individual buttons are, like menu items, not built-in types, but rather instances of a standard Python class. See qtoolbar.py for more information. Besides Floating Toolbars, buttons can also be displayed on fixed panels. Such panels are called Button Panels, and are created with a panel’s newbtnpanel() method. They are screen controls, with a few additional attributes:
Button panels have additional formatting capabilities: by inserting special values in the list of buttons, you can create gaps between buttons, pad buttons to the right, or force a new button row to begin. See qtoolbar.py . |
Additional attributes of Floating Windows controls |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Floating windows are created by a window’s newfloating() method. They are screen controls, and as all screen controls are, they are attached to their owner window. Unlike other screen controls, however, they can float anywhere on the screen and are never automatically aligned by a parent panel. In fact, their parent attribute is always None.
|
Additional attributes of Tree view controls (Explorers) |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Tree views are created by a panel’s newexplorer() method. They are screen controls that display a hierarchical view of Internal QuArK Objects. Any number of objects in a tree view can be selected (they appear in blue), but only one can have the focus (a rectangle of dots around it). Note that if the object with the focus is in a closed group, the group itself will be displayed with the rectangle of dots, but the focus stays on the correct object. Objects are not considered selected themselves if they are into a group that is already selected; in this case, they are displayed with a blue border instead of a blue background.
|
Additional attributes of Data form controls |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Data Forms are created by a panel’s newdataform() method. They are screen controls that display a list of object parameters, like on the Specific/Args page, or like all pages of the Configuration dialog box.
Note: internally, data forms have other routines to read and set values of various types of data, but only the bit-spec ones are exposed to Python code now because I didn’t need the other ones yet. Just ask if you do. |
Additional attributes of Image Displayer controls |
Armin Rigo - 01 Aug 2020 | [ Top ] |
Image Displayers are created by a panel’s newimagectrl() method. They are screen controls that display an image. Additional drawings can be painted over the image by Python code.
|
Canvas objects |
Armin Rigo - 05 Apr 2018 | [ Top ] |
Canvas Objects let you draw dots and lines from Python code. You obtain a Canvas object by calling a screen control’s canvas() method. Currently, only Image Displayers and Map Views have a canvas() method. You cannot create off-screen bitmaps currently. Note that the Canvas returned by such an object should be considered as temporary: only use it right after you called canvas(). Don’t store it into something else than a local variable.
There are of course other drawing methods that could be implemented, e.g. polylines, arcs, and so on. Ask me if you need them. |
Methods of Map View controls |
Armin Rigo - 05 Apr 2018 | [ Top ] |
Map Views are the most important type of screen control in QuArK. Each Map View can display 3D objects under various projection types. Objects can be displayed in wireframe, solid, or textured.
|
Additional attributes of Map View controls |
Armin Rigo - 05 Aug 2020 | [ Top ] |
Methods are described above. The following table describes the other attributes only.
A useful feature of Map views is their ability to work with handles: the attribute handles can be set to a list of Python instances (like a menu bar or a list of buttons), where each instance must have an attribute pos corresponding to the 3D location of the handle, and an attribute cursor giving the cursor shape to use when the mouse cursor is over the handle. cursor can be a CR_XXX value or a callback function that will be called with the map view as single parameter and that should return a CR_XXX value. The value CR_DEFAULT is replaced by the value set in the map view’s handlecursor attribute. Normally, the area around the handle center where you can click is 10 by 10 pixels large, that is, the distance between the mouse click and the handle center must be less than 5 pixels horizontally and vertically. You can give a custom horizontal and vertical size in the handle's size attribute, which defaults to the tuple (5,5). You can set a string in the hint attribute. This string will be displayed in a small pop-up rectangle when the mouse is over the handle. To display hints over a blue background (for entity-specific information only), make the hint string begin with a question mark ("?"). QuArK does not draw the handles itself. The Python code is responsible for that. See maphandles.py. |
Internal objects related to the Model Editor |
cdunde - 05 Apr 2018 | [ Top ] |
From version 5.3, there are a few new types of QuArK Internal Objects. When editing a Model, the generic object in the tree view is of type MdlObject, which inherits all attributes and methods from 3Dobject (see above). A "component" of the Model is an object of type Component. A "frame" of the Model is an object of type Frame. A "skin" is a standard Image object. Here are the attributes and methods of the Component objects.
Additionally, the Component objects have a Tris Specific that lists the triangles of the component. Each triangle is given as three points of six bytes each: two for the vertex number, two for the first coordinate on the skin, and two for the second coordinate on the skin. Here are the attributes and methods of the Frame objects.
Frame objects usually have a Vertices Specific that gives the 3D position of all vertices in a frame. This is a single large list of Vector objects that give the X, Y and Z coordinates of each vertices. For additional information, please see the files mdl*.py. |
Copyright (c) 2022, GNU General Public License by The QuArK (Quake Army Knife) Community - https://quark.sourceforge.io/ |
[ Top - ] | -