75 Commits

Author SHA1 Message Date
32c6297765 Fixed game version combobox not selecting proper version on profile editing. 2016-11-25 04:49:19 +05:00
190f76eb82 Fixed profiles editing crashing application if profile wasn't saved in database. 2016-11-25 04:44:46 +05:00
5c295f08ab Prettify options window. 2016-11-25 04:31:45 +05:00
061bfcaeb9 UI design updates.
Got rid of visible separators, replaced them with HBox and VBox.

Reworked profile add/edit window, now it looks prettier and
organic.
2016-11-25 04:11:44 +05:00
5ca8299714 Show selected server's information on active tab changing.
URTrator will now show information about selected server on
activated tab. E.g. when you switched from "Servers" to
"Favorites", sidebar informational widget will be updated with
server's data for selected server on "Favorites" tab.
2016-11-25 03:12:05 +05:00
9c8aa1cc34 Preparing to 0.1.0 release. 2016-11-23 10:13:01 +05:00
5fcbd8536c Update selected server's info in sidebar after updating server's data. 2016-11-23 10:10:11 +05:00
fb7a471aec Shw message in toolbar when updating selected server's data. 2016-11-23 10:02:58 +05:00
8c9d948a52 Fixed tooltip text for "Update all servers" button. 2016-11-23 09:53:09 +05:00
8b44d194b5 Hide private servers checkboxes. 2016-11-23 09:49:39 +05:00
3b0a93e63a By default srting players by name as well as cvars in sidebar. 2016-11-23 07:51:41 +05:00
b85ba0470c Fixed rendering of logo on launch button.
Also, made this logo smaller to beautify interface.
2016-11-23 07:42:58 +05:00
f127fdc9f4 Fixed players counting on servers update. 2016-11-23 07:41:14 +05:00
5ef54d943e Removed unneded "Additional information" button. 2016-11-23 07:35:10 +05:00
9e6cdfc869 Increased max ping requests to servers. Fixes #3. 2016-11-22 18:50:56 +05:00
bfd3f884b3 Automatic profile selection. Fixes #14.
Automatically select first added profile on every profiles list
update. Yes, quick hack. In future we will autodetect profiles
based on server version, and profiles combobox will only be
needed for quick connect.
2016-11-22 18:33:53 +05:00
7e6b698c1c Proper sorting by servers names. Fixing #12. 2016-11-22 18:23:43 +05:00
4516abb916 go-gtk fixed default sorting, so unlock it for all OSes. 2016-11-22 17:14:02 +05:00
e731653652 Fix for previous commit, wrong sorting call was masked on Windows. 2016-11-22 14:37:11 +05:00
e16d6fa878 Disabling setting default sort column on windows until it will
be fixed in go-gtk (https://github.com/mattn/go-gtk/issues/291).
2016-11-22 14:25:16 +05:00
89298d894b Hello, 0.1.0-beta5! 2016-11-22 12:02:12 +05:00
88b9b31f6a Updated README about required Go version. 2016-11-22 11:56:48 +05:00
1fe49871f1 Proper sorting by server name. 2016-11-22 11:53:54 +05:00
4f5bf90dbe Set 4.3.1 as default version in profiles dialog. 2016-11-22 11:38:48 +05:00
25bebf87df Re-enabled sorting for servers lists and hide offline checkboxes default value.
Re-enabled sorting for servers lists, which forces to use devel
version of Go. 1.7.3 have problems with GC and URTrator will
segfault.

Hide offline checkboxes for all servers and favorites now
checked by default.
2016-11-22 11:36:17 +05:00
c4ed421106 Temporary disable sorting in servers list until fixed in go-gtk. 2016-11-22 10:51:48 +05:00
0c0fcd5b24 First "sort by server name" implementation and button name fix.
First implementation of "Sort by server name" algo. Shitty, kinda
unreliable, but better than GTK's default.

Added Colorizer.Clear() func, which clears passed data from
colorcodes.

Fixed name on "Add to favorites" button.

Still cannot be successfully launched until some race conditions
will be fixed in go-gtk.
2016-11-22 09:48:19 +05:00
4d466a9d2b Servers sorting by ping and players count.
For now only on "Servers" tab, and REQUIRES custom go-gtk build
(see https://github.com/mattn/go-gtk/issues/290#issuecomment-262127956)
2016-11-22 07:36:27 +05:00
2cdee94efe Clipboard monitoring is here, so updating README. 2016-11-22 05:42:15 +05:00
2b1caac8f6 Fixed caching servers not updating profile to use in database. 2016-11-22 05:03:30 +05:00
862b336556 Windows-related build script and game launching fixes.
Fixed Windows build script to install gcc in MSYS2, which is
needed for some dependencies.

Fixed game launching on Windows, now ioq3 will search for game
data in proper directory.
2016-11-22 04:56:18 +05:00
90f888bdfb Toolbar icons is now (temporary) hardcoded. 2016-11-22 03:30:58 +05:00
a132ee0f7b Fixed icons loading and changed icons from svg to png. 2016-11-22 02:55:48 +05:00
8b06dff083 Forcing icons for servers lists. 2016-11-22 02:15:07 +05:00
ea8bdde224 Temporary disabled all modals on Linuxes due to mattn/go-gtk#289. 2016-11-22 01:10:31 +05:00
6495e90737 gdk_threads are deprecated, as well as glib_threads. 2016-11-21 03:32:22 +05:00
3e89df1009 Missing return definition for functions in prev commit. 2016-11-21 02:52:26 +05:00
c00ff2cea5 Check window position and size and hpane size in glib thread. 2016-11-21 02:49:05 +05:00
93d2bb7fc1 Reverting moving LockOSThread to main module. 2016-11-21 02:43:05 +05:00
0392f510f5 Moved runtime.LockOSThread() to urtrator.go. 2016-11-21 01:33:04 +05:00
57a5f7cb4c Bumping to beta4. Not tagging, as Windows fix is coming. 2016-11-21 01:19:06 +05:00
8a3f2a9a2e Stop updating servers if we're failed to connect to master server. 2016-11-04 19:37:50 +05:00
4e9a6ae970 GLib threads initialization. 2016-11-04 18:46:07 +05:00
7f80f99529 GTK actions fix WIP and icon size fix.
Again, possibly fixed GTK actions calls from other goroutines
by wrapping events calls in glib.IdleAdd(). This should prevent
executing more than one event simultaneously, which will also
prevent crashes.

Fixed icons sizing for couple of icons.
2016-11-04 18:28:52 +05:00
b1d38bbdcf Possibly solved crashes on GTK's actions. 2016-11-02 22:28:15 +05:00
e487b8521c Fixed clipboard watcher not watching after copying server's creds. 2016-10-13 02:40:27 +05:00
e12c76e424 Saving passwords for favorited private servers. 2016-10-12 23:26:43 +05:00
640020d23f Fixed server name putting into status label.
Some server's names (like Turnpike City) was tructating without
preserving Pango markup integrity. This commit fixes it.
2016-10-12 22:18:36 +05:00
a64c842e19 Messageboxes fixes and copy server's creds to clipboard.
Fixed all messageboxes that can use struct object as self name
(e.g. m for messageboxes in mainwindow). Should help to avoid some
errors.

Added possibility to copy server's credentials into clipboard
for ease of sharing.
2016-10-12 19:23:10 +05:00
1330699f41 Favorites servers and profiles fix.
If favorite server for some reason have no profile defined - pop up
an error message and do nothing.
2016-10-11 20:07:10 +05:00
a97b041679 Improved clipboard watching mechanism.
And it will look only within first string in clipboard.
2016-10-11 19:49:02 +05:00
68bd842c1f First variant of clipboard watching. 2016-10-11 13:14:08 +05:00
9be55c982e Beta3 is here. 2016-10-11 00:18:10 +05:00
35097c3805 Changed order for applying OS-specific workarounds. 2016-10-11 00:14:37 +05:00
3537b05dce Moved windows actions to mainwindow_init_win.go. 2016-10-11 00:14:00 +05:00
56c0d2787a Mac GTK+2 theme initialization fix. 2016-10-10 21:19:04 +05:00
f8b29a03d3 Added initial Windows build script. 2016-10-10 21:09:05 +05:00
eaaa8b565f Windows: import fixes. 2016-10-10 20:21:10 +05:00
e817a8fe64 Windows theming with default theme. 2016-10-10 20:18:59 +05:00
1a15c6cd4d Added Windows-related initialization things. 2016-10-10 20:11:41 +05:00
2746e0e315 Options window tabs moved to left. 2016-10-10 19:22:21 +05:00
2784586f8d More Mac integration works - now it is able to load and use GTK+
themes. Configuration interface on ToDo.

This also indicates that URTrator is now able to perform basic
window theming.
2016-10-10 19:16:51 +05:00
25dfa5072b Add "-a" to macOS's open command.
On my machine this prevents terminal window to be opened.
2016-10-09 21:27:17 +05:00
df4d6a3cca macOS fixes for profiles and launching. Version bump.
More fixes here. First, fixed binary path parsing for profiles,
so you should be able to add a profile on macOS now. Only one
requirement - you should add Quake3-UrT.x86_64 file, which located
inside Urban Terror's application bundle, under Contents/MacOS
directory.

Fixed the way we call Urban Terror on macOS and tested it. Should
work now flawlessly.

Bumped to 0.1.0-beta2, and mac-only release for now.
2016-10-09 17:06:47 +05:00
eaffb1f1ab Oops, wrong removing of wrong import. Now fixed. 2016-10-09 13:27:16 +05:00
c5349ab336 Unused import removed. 2016-10-09 13:25:43 +05:00
f283e93719 One more possible fix. 2016-10-09 13:23:59 +05:00
bbe03c485e Prossible MacOS launch fix. 2016-10-09 13:15:19 +05:00
f793b2f467 Updated macOS build script and some README update. 2016-10-09 03:29:36 +05:00
1278b71798 Bump to 0.1.0-beta1. 2016-10-09 01:32:17 +05:00
662f12aa4b Fixed launching URTrator if server name have no markup. 2016-10-09 01:31:53 +05:00
64b87d3a8b Completely fixed favorited servers. You may want to re-edit them. 2016-10-09 01:29:46 +05:00
e12bcdd386 Fixed favorite server addition and saving. 2016-10-09 01:23:38 +05:00
1b3b7bccf8 macOS building script added. 2016-10-09 01:02:21 +05:00
3a2a826d5b Added artwork. 2016-10-09 00:40:36 +05:00
46 changed files with 3509 additions and 249 deletions

3
.gitignore vendored
View File

@@ -1,3 +1,6 @@
# We don't need binaries.
urtrator
*tar*
# macOS things
.DS_Store

View File

@@ -2,6 +2,8 @@
[![Join the chat at https://gitter.im/urtrator/Lobby](https://badges.gitter.im/urtrator/Lobby.svg)](https://gitter.im/urtrator/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Chat on Matrix: #gitter_urtrator=2Flobby:matrix.org (Gitter bridge).
![Main Window](/doc/screenshots/0.1-main_window.png)
URTrator is a desktop application that should (eventually) replace
@@ -25,6 +27,7 @@ the game.
* Favorites servers.
* Updating single server.
* Showing information about servers (like in UrT Connector).
* Clipboard monitoring.
Planning:
@@ -35,11 +38,15 @@ Planning:
* All kinds of notifications.
* Extended profile editor, so every profile could have own configuration
files, etc.
* Clipboard monitoring.
* ...maybe more :)
# Installation
## Precautions
Due to Go's GC bugs, it is required to use devel version of Go
compiler!
## Release
You don't need to install anything, thanks to Go's.
@@ -47,6 +54,12 @@ URTrator executable contains everything we need. Just download
approriate binary and launch it! :) The only thing is to make
sure you have GTK2 and sqlite3 installed.
## Distro-and-OS specific instructions
* [MacOS](/doc/installation/macos/)
* Windows (to be written)
* Nixes: read below.
## Development version
URTrator written in Go and GTK2, so you should have them installed.

BIN
artwork/urtconnector.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
artwork/urtrator.icns Normal file

Binary file not shown.

BIN
artwork/urtrator.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

617
artwork/urtrator.svg Executable file
View File

@@ -0,0 +1,617 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="logo.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
inkscape:export-filename="/home/vlad/prog/urtconnector/artwork/logo.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient3244">
<stop
style="stop-color:#939393;stop-opacity:1"
offset="0"
id="stop3246" />
<stop
id="stop3252"
offset="0.50935251"
style="stop-color:#c9c9c9;stop-opacity:1" />
<stop
style="stop-color:#939393;stop-opacity:1"
offset="1"
id="stop3248" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3282">
<stop
style="stop-color:#163f80;stop-opacity:1"
offset="0"
id="stop3284" />
<stop
style="stop-color:#00163b;stop-opacity:1"
offset="1"
id="stop3286" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3420">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3422" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3424" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3408">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3410" />
<stop
id="stop3416"
offset="0.40972927"
style="stop-color:#000000;stop-opacity:0.57254902;" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3412" />
</linearGradient>
<linearGradient
id="linearGradient3392">
<stop
style="stop-color:#000000;stop-opacity:0.36407766;"
offset="0"
id="stop3394" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3396" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3382">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3384" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3386" />
</linearGradient>
<linearGradient
id="linearGradient3365"
inkscape:collect="always">
<stop
id="stop3367"
offset="0"
style="stop-color:#000000;stop-opacity:0.6091954" />
<stop
id="stop3369"
offset="1"
style="stop-color:#000000;stop-opacity:0" />
</linearGradient>
<linearGradient
id="linearGradient3353">
<stop
id="stop3355"
offset="0"
style="stop-color:#0029f8;stop-opacity:1;" />
<stop
id="stop3357"
offset="1"
style="stop-color:#48abff;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient3337">
<stop
style="stop-color:#000000;stop-opacity:0.35632184"
offset="0"
id="stop3339" />
<stop
style="stop-color:#000000;stop-opacity:0"
offset="1"
id="stop3341" />
</linearGradient>
<linearGradient
id="linearGradient3325">
<stop
id="stop3327"
offset="0"
style="stop-color:#593000;stop-opacity:1;" />
<stop
style="stop-color:#d57500;stop-opacity:1;"
offset="0.52852255"
id="stop3329" />
<stop
id="stop3333"
offset="0.57115513"
style="stop-color:#ffa940;stop-opacity:1;" />
<stop
id="stop3331"
offset="1"
style="stop-color:#ffd9ab;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient2513">
<stop
id="stop2515"
offset="0"
style="stop-color:#8d4d00;stop-opacity:1;" />
<stop
style="stop-color:#e47e00;stop-opacity:1;"
offset="1"
id="stop2517" />
<stop
id="stop2519"
offset="1"
style="stop-color:#ffffff;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3159">
<stop
style="stop-color:#cb7000;stop-opacity:1;"
offset="0"
id="stop3161" />
<stop
id="stop3187"
offset="0.6008783"
style="stop-color:#ffc57e;stop-opacity:1;" />
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop3163" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3337"
id="radialGradient3343"
cx="65.35714"
cy="114.78571"
fx="65.35714"
fy="114.78571"
r="62.142857"
gradientTransform="matrix(1,0,0,0.1551724,0,96.974138)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3353"
id="radialGradient3711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.1551724,0,96.974138)"
cx="65.35714"
cy="114.78571"
fx="65.35714"
fy="114.78571"
r="62.142857" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3282"
id="linearGradient3729"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.3645946,0,0,0.3648162,14.541456,29.799899)"
x1="141.76604"
y1="18.596226"
x2="142.1283"
y2="110.36981" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3244"
id="linearGradient3731"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.3598962,0,0,0.3657662,44.109572,29.783379)"
x1="36.950943"
y1="74.626411"
x2="57.479244"
y2="82.59623" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3244"
id="linearGradient3733"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.3598962,0,0,0.3657662,44.109572,29.783379)"
x1="53.97736"
y1="26.686792"
x2="74.643394"
y2="34.656605" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3244"
id="linearGradient3735"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.311106,0.1838886,-0.1809374,0.3161802,72.258982,23.810768)"
x1="36.950943"
y1="74.626411"
x2="57.479244"
y2="82.59623" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3244"
id="linearGradient3737"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.311106,0.1838886,-0.1809374,0.3161802,72.258982,23.810768)"
x1="53.97736"
y1="26.686792"
x2="74.643394"
y2="34.656605" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3244"
id="linearGradient3739"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.3187969,-0.1697384,0.1670143,0.3239966,22.654672,47.924186)"
x1="36.950943"
y1="74.626411"
x2="57.479244"
y2="82.59623" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3244"
id="linearGradient3741"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.3187969,-0.1697384,0.1670143,0.3239966,22.654672,47.924186)"
x1="53.97736"
y1="26.686792"
x2="74.643394"
y2="34.656605" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3353"
id="radialGradient3825"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.1551724,0,96.974138)"
cx="65.35714"
cy="114.78571"
fx="65.35714"
fy="114.78571"
r="62.142857" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3408"
id="linearGradient2476"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1522091,0,0,1.1915991,-5.9678035,-14.018701)"
x1="97.479721"
y1="63.350235"
x2="87.567596"
y2="56.910515" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3420"
id="linearGradient2480"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1522091,0,0,1.1915991,-7.6138165,-15.082628)"
x1="60.356613"
y1="31.78297"
x2="75.256363"
y2="54.258865" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3382"
id="linearGradient2497"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1522091,0,0,1.9518275,30.695264,-25.118641)"
x1="23.612316"
y1="61.140526"
x2="24.163845"
y2="66.533455" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3382"
id="linearGradient2500"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1522091,0,0,1.1915991,-5.9678035,-14.018701)"
x1="23.612316"
y1="61.140526"
x2="24.492611"
y2="68.540787" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3365"
id="radialGradient2503"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.9700094e-2,-0.2574946,0.1164369,7.5765948e-2,15.737884,82.380596)"
cx="65.35714"
cy="114.78571"
fx="65.35714"
fy="114.78571"
r="62.142857" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3365"
id="radialGradient2506"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(7.6016056e-2,-0.2486139,0.1043479,9.2710136e-2,28.152763,94.009003)"
cx="65.35714"
cy="114.78571"
fx="65.35714"
fy="114.78571"
r="62.142857" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3325"
id="linearGradient2509"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1522091,0,0,1.1915991,-5.9678035,-14.018701)"
x1="41.755394"
y1="89.881668"
x2="33.497143"
y2="80.550133" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2513"
id="linearGradient2512"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1522091,0,0,1.1915991,-5.9678035,-14.018701)"
x1="60"
y1="98"
x2="44.36623"
y2="91.940338" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2513"
id="linearGradient2515"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1522091,0,0,1.1915991,-5.9678035,-14.018701)"
x1="30.618973"
y1="77.520943"
x2="22.482548"
y2="58.090366" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2513"
id="linearGradient2518"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.2752829,0.3048915,-0.2659294,0.2568015,83.841093,-117.26953)"
x1="349.8988"
y1="341.99713"
x2="192.65581"
y2="332.66278" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="69.212961"
inkscape:cy="67.642159"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="741"
inkscape:window-x="-4"
inkscape:window-y="-4"
showguides="true"
inkscape:guide-bbox="true">
<inkscape:grid
type="xygrid"
id="grid2383"
visible="true"
enabled="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
style="display:inline">
<path
sodipodi:type="arc"
style="opacity:1;fill:url(#radialGradient3343);fill-opacity:1;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path3335"
sodipodi:cx="65.35714"
sodipodi:cy="114.78571"
sodipodi:rx="62.142857"
sodipodi:ry="9.6428576"
d="M 127.5,114.78571 A 62.142857,9.6428576 0 1 1 3.214283,114.78571 A 62.142857,9.6428576 0 1 1 127.5,114.78571 z"
transform="translate(-1.3060194,2.6453827)" />
<path
sodipodi:type="arc"
style="fill:url(#radialGradient3825);fill-opacity:1;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path3349"
sodipodi:cx="65.35714"
sodipodi:cy="114.78571"
sodipodi:rx="62.142857"
sodipodi:ry="9.6428576"
d="M 127.5,114.78571 A 62.142857,9.6428576 0 1 1 3.214283,114.78571 A 62.142857,9.6428576 0 1 1 127.5,114.78571 z"
transform="matrix(0.665465,-0.6397098,1.4719873,1.6750617,-170.41896,-67.520784)" />
<path
style="fill:#fd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 27.310752,76.301137 L 20.226798,86.576911 L 24.790207,87.031158 L 16.65334,98.884033 L 20.08029,99.392718 L 8.0841981,117.64078 L 27.440356,104.70716 L 27.880541,108.15353 L 38.77894,99.816955 L 39.315995,103.62093 L 48.425858,97.181362 L 27.310752,76.301137 z"
id="path3345"
sodipodi:nodetypes="cccccccccccc" />
<path
sodipodi:nodetypes="cccccccccccc"
id="path3347"
d="M 31.874594,75.25333 L 25.725007,83.755921 L 29.638682,84.161712 L 22.574732,93.969499 L 25.51262,94.413575 L 15.093067,109.51631 L 31.793784,98.87862 L 32.14829,101.74756 L 41.558676,94.881135 L 41.993905,98.048091 L 49.856362,92.748368 L 31.874594,75.25333 z"
style="fill:#fdee00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:url(#linearGradient2518);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.33248031000000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 125.72125,2.0908808 C 97.063155,1.9735321 64.225955,12.545775 47.382924,28.810693 C 26.329134,49.141838 25.771245,65.983715 29.799627,83.305617 L 40.810933,95.501276 C 57.225757,100.82139 77.721658,97.332118 94.56469,81.067205 C 110.5348,63.899516 125.6079,30.491796 125.72125,2.0908808 L 125.72125,2.0908808 z"
id="path2385"
sodipodi:nodetypes="ccccccc" />
<path
style="fill:url(#linearGradient2515);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 34.192761,57.851258 C 20.922743,56.117338 12.870738,58.308074 5.5542872,61.052045 C 14.847587,65.473356 23.901389,70.160042 29.424115,78.759363 C 32.129944,73.654864 34.955774,68.750837 34.192761,57.851258 z"
id="path3291"
sodipodi:nodetypes="cccc" />
<path
style="fill:url(#linearGradient2512);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 45.151372,96.178204 C 52.127761,103.19273 57.189208,111.88298 60.599683,122.01797 C 64.115569,114.96166 66.649136,104.05808 65.647273,92.688932 C 58.012273,91.637316 51.140557,92.690937 45.151372,96.178204 z"
id="path3293"
sodipodi:nodetypes="cccc" />
<path
style="fill:url(#linearGradient2509);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 32.555743,81.910374 C 37.816463,77.742691 42.831623,76.309745 49.920018,75.270095 C 48.367823,82.207012 45.9227,88.220474 42.237977,92.951957 L 25.592739,97.557253 L 32.555743,81.910374 z"
id="path3295"
sodipodi:nodetypes="ccccc" />
<path
style="fill:url(#radialGradient2506);fill-opacity:1;stroke:none;stroke-width:1.30032527;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 49.896088,75.390554 C 53.636142,77.989394 57.196016,86.05308 52.383274,93.41107 C 50.576849,93.234107 47.102291,95.447807 45.029491,96.185093 C 43.413502,95.363897 41.957172,93.617107 42.226222,92.995319 C 42.68573,91.933377 43.246383,92.013904 45.16111,88.508858 C 48.785332,81.874475 49.542448,76.317631 49.896088,75.390554 z"
id="path3361"
sodipodi:nodetypes="cccssc" />
<path
sodipodi:nodetypes="ccccc"
id="path3374"
d="M 34.349316,60.665771 C 38.419322,62.665225 43.327507,70.078366 39.617648,78.090425 C 37.805752,78.191151 34.685201,80.910996 32.740335,81.95662 C 31.024842,81.391098 29.298783,79.340325 29.476141,78.684277 C 33.023412,72.258565 34.257398,67.993041 34.349316,60.665771 z"
style="fill:url(#radialGradient2503);fill-opacity:1;stroke:none;stroke-width:1.30032527;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:url(#linearGradient2500);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:0.81386861"
d="M 9.4950888,61.622502 C 12.960656,60.343036 14.627666,60.004835 20.200883,59.319836 C 24.908394,58.784462 27.371969,58.867798 32.426038,59.467647 C 32.690813,62.160971 33.064851,63.049589 32.572967,66.770556 C 27.035357,64.13242 25.903084,63.770487 18.802098,65.562544 C 18.13913,65.729855 10.167739,61.437609 9.4950888,61.622502 z"
id="path3380"
sodipodi:nodetypes="ccccsc" />
<path
sodipodi:nodetypes="cccccc"
id="path3428"
d="M 47.571914,96.689492 C 51.546692,94.345128 52.910325,94.152704 55.937496,93.532221 C 59.081007,93.175431 60.994868,93.33704 64.484937,93.809822 C 64.419205,96.903826 64.381932,98.978312 64.109636,102.35392 C 60.365882,101.97929 56.249908,102.24631 53.505206,103.71505 C 53.297525,103.55617 49.042817,97.771639 47.571914,96.689492 z"
style="fill:url(#linearGradient2497);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:0.63868613" />
<g
id="g3624"
transform="matrix(0.8575649,0.8858367,-0.856554,0.8868821,63.797695,-55.172839)">
<rect
transform="matrix(0.3598962,0,0,0.3657662,44.109572,29.783379)"
style="opacity:0.33716479;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect3296"
width="93.705658"
height="92.739624"
x="18.113203"
y="20.045282"
ry="3.9671445" />
<rect
ry="1.4510475"
y="36.14357"
x="49.498505"
height="33.921024"
width="33.724308"
id="rect3280"
style="fill:url(#linearGradient3729);fill-opacity:1;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
style="opacity:0.5;fill:#000000;fill-opacity:1;stroke:none"
id="g3418"
transform="matrix(0.3598962,0,0,0.3657662,44.560382,30.324351)">
<path
sodipodi:nodetypes="ccccc"
id="path3420"
d="M 34.777359,78.490566 L 37.675472,70.762265 L 58.928302,78.732075 L 56.271698,86.218868 L 34.777359,78.490566 z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
id="path3422"
d="M 38.641509,68.10566 L 54.098113,25.116981 L 75.592453,33.328302 L 59.894339,76.075472 L 38.641509,68.10566 z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<path
sodipodi:nodetypes="ccccc"
id="path2470"
d="M 56.62581,58.492577 L 57.66883,55.665825 L 65.317642,58.580913 L 64.361541,61.319329 L 56.62581,58.492577 z"
style="fill:url(#linearGradient3731);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.37332731;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
id="path2472"
d="M 58.016503,54.694129 L 63.579276,38.970322 L 71.315006,41.973746 L 65.665315,57.609217 L 58.016503,54.694129 z"
style="fill:url(#linearGradient3733);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.37332731;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<use
height="128"
width="128"
transform="matrix(0.8705535,0.4920736,-0.4920736,0.8705535,49.328822,-23.963109)"
id="use3492"
xlink:href="#g3418"
y="0"
x="0" />
<path
style="fill:url(#linearGradient3735);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.37332731;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 68.876544,55.023093 L 71.176503,53.112487 L 76.346348,59.540536 L 74.165222,61.419193 L 68.876544,55.023093 z"
id="path3564"
sodipodi:nodetypes="ccccc" />
<path
style="fill:url(#linearGradient3737);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.37332731;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 71.957722,52.450164 L 84.544626,41.700287 L 89.745908,48.249108 L 77.127567,58.878214 L 71.957722,52.450164 z"
id="path3566"
sodipodi:nodetypes="ccccc" />
<use
height="128"
width="128"
transform="matrix(0.886662,-0.4624181,0.4624181,0.886662,-31.554372,42.115996)"
id="use3526"
xlink:href="#g3418"
y="0"
x="0" />
<path
style="fill:url(#linearGradient3739);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.37332731;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 46.850635,67.45181 L 46.483807,64.455947 L 54.590216,63.430718 L 54.993701,66.307341 L 46.850635,67.45181 z"
id="path3554"
sodipodi:nodetypes="ccccc" />
<path
style="fill:url(#linearGradient3741);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.37332731;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 46.348086,63.431243 L 44.095879,46.879477 L 52.319616,45.891503 L 54.454495,62.406014 L 46.348086,63.431243 z"
id="path3556"
sodipodi:nodetypes="ccccc" />
</g>
<path
style="opacity:0.8467433;fill:url(#linearGradient2480);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.413903,55.139286 C 37.526255,46.035914 42.633004,37.169864 51.745436,29.259803 C 73.490531,11.792061 97.061462,7.5421026 120.70693,3.8317059 C 104.71178,32.48334 77.587866,58.9921 54.218738,67.025792 C 49.635316,58.883563 41.045423,54.612685 33.413903,55.139286 z"
id="path3418"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:0.16091955;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 123.66233,4.2937854 C 122.33989,21.617872 118.90191,41.348784 102.42103,66.5851 C 91.02444,83.090705 79.918828,89.592222 68.522239,93.066432 C 107.03772,66.876049 115.09449,37.009943 123.66233,4.2937854 z"
id="path3402"
sodipodi:nodetypes="cccc" />
<path
sodipodi:nodetypes="cccc"
id="path3406"
d="M 123.66233,4.2937854 C 122.66959,21.021181 121.04676,40.062448 103.43945,67.337411 C 92.311988,85.234673 80.021007,90.120581 68.522239,93.066432 C 100.31763,64.193362 111.16363,34.736077 123.66233,4.2937854 z"
style="opacity:0.18390802;fill:url(#linearGradient2476);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="icon" />
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -63,6 +63,9 @@ func (c *Cache) FlushServers(data map[string]string) {
new_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig
new_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo
new_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate
new_servers[mapping_item_name].Favorite = s.Server.Favorite
new_servers[mapping_item_name].ProfileToUse = s.Server.ProfileToUse
new_servers[mapping_item_name].Password = s.Server.Password
} else {
cached_servers[mapping_item_name].Ip = s.Server.Ip
cached_servers[mapping_item_name].Port = s.Server.Port
@@ -76,6 +79,9 @@ func (c *Cache) FlushServers(data map[string]string) {
cached_servers[mapping_item_name].ExtendedConfig = s.Server.ExtendedConfig
cached_servers[mapping_item_name].PlayersInfo = s.Server.PlayersInfo
cached_servers[mapping_item_name].IsPrivate = s.Server.IsPrivate
cached_servers[mapping_item_name].Favorite = s.Server.Favorite
cached_servers[mapping_item_name].ProfileToUse = s.Server.ProfileToUse
cached_servers[mapping_item_name].Password = s.Server.Password
}
}
@@ -84,12 +90,12 @@ func (c *Cache) FlushServers(data map[string]string) {
fmt.Println("Adding new servers...")
if len(new_servers) > 0 {
for _, srv := range new_servers {
tx.NamedExec("INSERT INTO servers (ip, port, name, ping, players, maxplayers, gamemode, map, version, extended_config, players_info, is_private) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private)", srv)
tx.NamedExec("INSERT INTO servers (ip, port, name, ping, players, maxplayers, gamemode, map, version, extended_config, players_info, is_private, favorite, profile_to_use) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private, :favorite, :profile_to_use)", srv)
}
}
fmt.Println("Updating cached servers...")
for _, srv := range cached_servers {
_, err := tx.NamedExec("UPDATE servers SET name=:name, players=:players, maxplayers=:maxplayers, gamemode=:gamemode, map=:map, ping=:ping, version=:version, extended_config=:extended_config, players_info=:players_info, is_private=:is_private WHERE ip=:ip AND port=:port", &srv)
_, err := tx.NamedExec("UPDATE servers SET name=:name, players=:players, maxplayers=:maxplayers, gamemode=:gamemode, map=:map, ping=:ping, version=:version, extended_config=:extended_config, favorite=:favorite, password=:password, players_info=:players_info, is_private=:is_private, profile_to_use=:profile_to_use WHERE ip=:ip AND port=:port", &srv)
if err != nil {
fmt.Println(err.Error())
}

View File

@@ -0,0 +1,114 @@
// URTator - Urban Terror server browser and game launcher, written in
// Go.
//
// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n)
// All rights reserved.
//
// Licensed under Terms and Conditions of GNU General Public License
// version 3 or any higher.
// ToDo: put full text of license here.
package clipboardwatcher
import (
// stdlib
"errors"
"fmt"
"strings"
// other
"github.com/mattn/go-gtk/gdk"
"github.com/mattn/go-gtk/gtk"
)
type ClipboardWatcher struct {
// Clipboard.
clipboard *gtk.Clipboard
// PRIMARY clipboard.
prim_clipboard *gtk.Clipboard
// Flags.
// We have just copy connect string to clipboard.
// Used to ignore clipboard data in check*Input()
just_set bool
}
func (cw *ClipboardWatcher) checkInput() {
if !cw.just_set {
text := cw.clipboard.WaitForText()
cw.parseData(text)
} else {
cw.just_set = false
}
}
func (cw *ClipboardWatcher) checkPrimaryInput() {
if !cw.just_set {
text := cw.prim_clipboard.WaitForText()
cw.parseData(text)
} else {
cw.just_set = false
}
}
func (cw *ClipboardWatcher) CopyServerData(server_address string) error {
server, ok := Cache.Servers[server_address]
if !ok {
// ToDo: show message box?
return errors.New("Server wasn't selected")
}
// Composing connection string.
var connect_string string = ""
connect_string += "/connect " + server.Server.Ip + ":" + server.Server.Port
if len(server.Server.Password) >= 1 {
connect_string += ";password " + server.Server.Password
}
fmt.Println("Connect string: ", connect_string)
cw.just_set = true
cw.clipboard.SetText(connect_string)
return nil
}
func (cw *ClipboardWatcher) Initialize() {
fmt.Println("Initializing clipboard watcher...")
cw.just_set = false
cw.clipboard = gtk.NewClipboardGetForDisplay(gdk.DisplayGetDefault(), gdk.SELECTION_CLIPBOARD)
cw.clipboard.Connect("owner-change", cw.checkInput)
cw.prim_clipboard = gtk.NewClipboardGetForDisplay(gdk.DisplayGetDefault(), gdk.SELECTION_PRIMARY)
cw.prim_clipboard.Connect("owner-change", cw.checkPrimaryInput)
}
func (cw *ClipboardWatcher) parseData(data string) {
// We should check only first string.
data = strings.Split(data, "\n")[0]
// Checking if we have connection string here.
if strings.Contains(data, "ct ") {
fmt.Println("Connection string detected!")
var server string = ""
var password string = ""
conn_string := strings.Split(data, ";")
if len(conn_string) > 0 {
srv_string := strings.Split(data, ";")[0]
srv_splitted := strings.Split(srv_string, "ct ")
if len(srv_splitted) > 1 {
server_raw := strings.Split(srv_splitted[1], " ")[0]
// Get rid of spaces.
server = strings.TrimSpace(server_raw)
}
}
if len(conn_string) > 1 && strings.Contains(data, "password") {
pw_string := strings.Split(data, ";")[1]
pw_splitted := strings.Split(pw_string, "password ")
if len(pw_splitted) > 1 {
password_raw := strings.Split(pw_splitted[1], " ")[0]
// Get rid of spaces.
password = strings.TrimSpace(password_raw)
}
}
Eventer.LaunchEvent("setQuickConnectDetails", map[string]string{"server": server, "password": password})
}
}

View File

@@ -0,0 +1,28 @@
// URTator - Urban Terror server browser and game launcher, written in
// Go.
//
// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n)
// All rights reserved.
//
// Licensed under Terms and Conditions of GNU General Public License
// version 3 or any higher.
// ToDo: put full text of license here.
package clipboardwatcher
import(
// local
"github.com/pztrn/urtrator/cache"
"github.com/pztrn/urtrator/eventer"
)
var (
Cache *cache.Cache
Eventer *eventer.Eventer
)
func New(c *cache.Cache, e *eventer.Eventer) *ClipboardWatcher {
Cache = c
Eventer = e
cw := ClipboardWatcher{}
return &cw
}

View File

@@ -21,8 +21,28 @@ type Colorizer struct {
colors map[string]string
}
func (c *Colorizer) ClearFromMarkup(data string) string {
var result string = ""
data = html.EscapeString(data)
data_splitted := strings.Split(data, "&gt;")
if len(data_splitted) > 1 {
for item := range data_splitted {
if len(data_splitted[item]) > 0 {
result += strings.Split(data_splitted[item], "&lt;")[0]
}
}
} else {
result = data_splitted[0]
}
return result
}
func (c *Colorizer) Fix(data string) string {
result := ""
var result string = ""
data = html.EscapeString(data)

View File

@@ -10,5 +10,5 @@
package common
const (
URTRATOR_VERSION = "0.1-beta"
URTRATOR_VERSION = "0.1.0"
)

View File

@@ -0,0 +1,16 @@
// URTator - Urban Terror server browser and game launcher, written in
// Go.
//
// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n)
// All rights reserved.
//
// Licensed under Terms and Conditions of GNU General Public License
// version 3 or any higher.
// ToDo: put full text of license here.
package common
var SERVER_OFFLINE = `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`
var SERVER_ONLINE = `iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB9kECQAMG1e9iO0AAAkGSURBVFjDjVdrjFXVFf7W3ufec++dFwwzRAaKlMIoiIPDy2fJoJYmFWuThir9YfqD2EfS9GH636Q//GesiYltSNsfTWhSo1YpSis4GhMEgSm0YgtKrTyFYYS5c89j773W6o9z7jCIVm+ycx4593zfXutb31qHVBVf5De8lQAAUVwchRXCgLGAscW9kBfvGtv2xd4JAPR5BIa3EqIqYc5S7WWDTVFEWwAMqqJPWTvJ0hQRxgEcC0G3W8GOi8dpIjj9QkQ+k8AM4CVUpV9FiO9dvng43HT9ukZf13w04m5UbQ2OMyT5JMabp/HOf/cnR0+MRQH5q+r0JxeP03ufR+RTCQxvJcxbiVgJT4DM9zasvi++Y8k3bc30oG5mo0oNAIDjBF4yeM2g5JFpEwSDve//mV87uDOHyu9J8fOzh5F/FolrCKx6hNA/iLlUo10D8wYGv337Dxtfagyhv7oUsemEQsDqEcQV4JLBSQovLeScIpGPAaNounE899YzyZkzZ47B6dcvHMP5Q7/R/0+g3Hm/kjny1Vs29m1Y9lA0EN+M3nghYtMBQSiB8xI8hZMUjhPknMBJC3lI4LQJUUalEuP1d58Pbxz863iey1DzfVz4ZCTMTHC7DhU19Mpdt2zs27Dsu9HC2lrMrs5HzXYgMhVYimAogiELQwaGLAgGVF4TDIwhqFp4driUnMcdSzdFd63c2BeBXrHrUGlX0zUEoiqhz+Gp6+bOX7Zh2UPRdZVlqJo6iCxEBUE8WBmqDFUBFJgOngIAAUoQIVB5izlgonUa65d/K7quf2BZ4wyespVPITC8ldCzRAeJzMPfufNH9Vl2QQEOgiojiEPQHCwOrAGqDJkmo1AVqEhBDAIVhYhCoMglx0RyGg/e/YM61DxsZ+vgzCiY9u6jGj1575oH4lnxAGLqBKAQCFiKvF+11IM1gJUhGiAlIQFDVCAqBTkRqDDGk1OIbBUb77w/tkJPzoyCGd5amEyVavfcuvg+W5PeAlwFIgFBZ4ouv5aMeLAEsHqwcHkeIMJg8WBmqDBOXjqKO5fdZy1q91Tr2tuOggEANti0fNGqoAJUTR2iClZGEA/POYJk8JxPl93VZDxYcwQOYPZgDmB28OIRShKBPVI3iUk3jqHB4ZDl2DQdgSgmRBFtWb5wbaNKnRBViASwOATJ4SWHa4Nye+UI0l4ZHBca8dI+eoTgweyLeyWZS+lZrBgcbljQlnYaopLI4JzGAJQBASPAFSoGw5iivABAy/wW+b9iRkHyghRncJzDc5EezxlC8PDBQTTgcnoB87pvgggG2yqIhBUq1FevdkFVEMRNa8CQBYkBEUG1kKUqg5WvECij4ThDzhk8O/iQwYUMeSjOWQp9JNJER08POEefrWhJIACq2lG1NXjvQcghwrAmKg2mqG8QSrXLDNE5+JKE5xSOS2cMGVxI4TmDkwwhFFXi1aFe7QQ77aDSgSJjASJq5T7rthoXjE0Eo4W7AYS2tcjMFIgvBFamwZUE8pAh57SIiG/BeQelgMCMiq0gzVpQpRbZMgJkCUQYT9xkd930gCnAiIU1tsx9AS/QaQ2IhrL8iirxmsFxBh9y5KGFXFLkvoXM51D1YC7+E0VdmGxdAinGjZkhQiUcG588s3jBrA74wCAyILawZHCldWhpMKU5qS9J5HChqAwnGbKQwIcW0pCAxRW6Yg8RRldnH86Pn4MwjrVfHLFTcMD2d08fWD8w+yuNPCQgimCJ4EFoP6jTzlhYcGAH1jICnMNLity3w5/AsyvMCAHChUHNqS/E3954NckT3V7tmmHFVrDjXyfHogrVEcTBhSmkroXMt5BxCxlPIfNTyFwTmWsh801kYQqpaxb3y+fT0ELmp+A5BzMjSAAHBnNANWqgtzaAgwfGotxjx7QRjW1TjB+jCcfp7rfe38GNuAepTwtgXwAnrlWA+ASpv4zENZH6qXI1kbgpJH4KmWshsEfwpSVLgKiHQLBy3t3Ys28nZ1m2Z+4immjPBYUVe0Vw+tPX/v6SS10TjUoXXEiR+Vaxs7wASd1lpG4KqZtCkjfRcpNo5cW19/m09wtC2TUDgjAWzroJEgjP/2mHl6Ty6KFfK13VDce2KXY/iuPeyfZn33wm6671wVIEL66oaU6QuCs7TX0RAedzhHau1UNESnCeBm9UOzHYfxt+94dtTr19MT639MNiePjEQAKA3KEFvzhz7qP/jP7jBZnbtQiWKoXiuehugbnokBwKMA0loC/8Ae0WXThfo9qJNQvux67Rl/SDd85fqDdXPM3cEY+MjFwZhGZOJ5NHl7jYVb7/Zr77RWH0bBh6gD5qfoDzzZMQCVf3fg0QFAITSNmCS0IiuH72CtzQfzt2vf6S7nxhTxZfvvG3kAj1emyazSZ9KoHu7pybp3rPoNn42Wgy+vixE//se3DjI9HivpX44OIReJ9NG9F0z28PIuUcUIs6MLTgHigTnnj6cf7w3xPN2qVlz5LGp2BMS9X6g4sXyzVTMRHR6tWrIwA9udhFUexWRCtO/Ng0WkNfW/8Nu/7mTTTpLmCidRaXs/NIXBM5J4iMRcXW0VPvQ3/jevQ25mPPW3/R5/64U8h1nognl7wMse+R0XdDCMdn1Wrn9+7dmw+tWSeH3953JQJDa9bpwQP7edHIyFRHq3VKQ8T52I2/RO/Hq16+vHvL7j17vrzihmEdWn5LdP3sVeiod6FWbSDNW2ilTZwbP41do6+Fg/vHKE9wOm4u3WVD93EhPUtGPySik9JoTCwYGHDAFYOdjsDKtbcCAI4c2G+WLFlSifv7O8i52ZZojhL1apwtRM9Hd1B38zZRP1dYGsFLlWAdqUnERRfR7BmL8/5DQO2cFbokFhfZ00VEMmHzvNnb25uPjo7y0Jp1CgCH39537ZfRyrW34siB/TQyMmKbzWbVuXpsDDcQcwepNoRNTa3EACqGyapVElUGIq8IntjklSolcLYFpEmSNLIoupS/s3lzwGOP6dCadXr47X2f/3FKRASANm/eTEePHrW1Wi26HEVRPUmsr9dNNYose29EhGwUSRwCZ1lVajXH3vsw2dvLi4AwOjoqAFQ/A+h/LbYPin8XPaUAAAAASUVORK5CYII=`
var SERVER_PRIVATE = `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`
var SERVER_PUBLIC = `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
`

22
common/toolbar_icons.go Normal file
View File

@@ -0,0 +1,22 @@
// URTator - Urban Terror server browser and game launcher, written in
// Go.
//
// Copyright (c) 2016, Stanslav N. a.k.a pztrn (or p0z1tr0n)
// All rights reserved.
//
// Licensed under Terms and Conditions of GNU General Public License
// version 3 or any higher.
// ToDo: put full text of license here.
package common
var ADD_TO_FAVORITES = `iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK6SURBVFiFxZexaxRBGMXft7t6B4pR8CSKovbBQsTOwkrRMoVgm/wDVgpiZSUW+Qe0F9HCMkHsAjYiSMAUijZyIYdgipCbnW++Z3F7l93bu0v2NJuBZZZlZ+bHmzdvZoQkDrNEhzo6gKTKzyJyAkAT48ENgCO5dSAAAJoPX15ZI6w1EhBR59nCl7kqHVYFiIKF1v1bj5DETQAAAYAGH3bwauV5CxWntSoAjIYoSvDz9ypEBIAAIM7NXIXRqnY3BYARgQpjgEByYAqz6itqCgUImsKoEOYAzMOmWNLTKZABINOAAAJ9XQpYT26Goe9apwc8zLTwPdg/KpCFTANAPBGAhJpHGAYIux4QkdlJXSAXVnkFmotLl9cAjgyZfonj2AXVRgjFKVBTJHHsFpcutSe1B6Tz4sGPQVjlASKjteZvLuBI0sg+sfdI7h1oOL8N1UyBzIUu3cbdG/capMFoGNRmMAaYGdQc3n9cLoRVwQNmRIQY678+IJIIIjLyATCo+2Xjzzr6OyvJkc/JY+dLPikCkNCgCCGAwtGDC3YDKM/AfkWAoyFUy1lRAAhmPYONARgMnocoMGSDj4HQ4BGsuFRLCgTtAZhYWYHhwScpgCkUMCO66TYunr6GvvnYNx85eFdz2Nz6VlDh1PELiCRGyYQ0mAUYDanvTvSAkei8W30zcRkmSeJuX79TWoY0YvnTilPVxpimmWjSQS8LSgDu9eP2HPbYz+efnml7TaGqBQW8pkjTtPH2yebZSe2zwV0JYD/HKBGZtWwuhxXwufklubFXXyWA/RYzwqsrK+BdfbvhKAV6Dq9pN/Q+80AuDVNN6zsROU3hNRRyIPVpfSci5z3SEAo51PW1KWDouh00j86ABJiFTTft1uIBo6Hz+fvXMReTYsjsp0iVy6mIzKB3avpvV7NKAAdRDv12/Bc1PDWiO2VdhgAAAABJRU5ErkJggg==`
var COPY_CREDENTIALS = `iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAB11BMVEUAAAD///////+AgICAj4CJiYDDw8OQk42PkYyNkIqFh4KHioWHiYWJi4WJi4eLjYfDw8PFxcPFxcXHx8XHx8fJycfJycnp6enr6+nr6+vt7evt7e3v7+3v7+/x8e/x8fHz8/P19fX39/f5+fn7+/v9/f3///+IiYSQkY2QkY2GioWLjoiZm5aFioSGioSIi4eIi4aHioWIioWIi4aLjomGioSHiYSHioWIioSIioWIi4WJi4aJjIiJjYeLjomMjoqMjouMkImMkIqNkIuSlpCTlpGVlpWVmJOYm5eYnJeanJqbm5ubnpqdnZ2enp6fn5+kpKSmpqamqaWoqKioqaipqamwsa+xsbGzs7O0tLS5ubm6urq9vr2+vr7BwcHCwsLDw8LDw8PExMPExMTFxcTFxcXGxsXGxsbGx8XGx8bHx8bHx8fIyMfIyMjNzc3R0dHm5ubn5+fo6OXo6Ofo6Ojp6ejp6enp6ujq6unq6urr6+rr6+vs7Ovs7Ozt7evt7ezt7e3u7u3u7u7v7+3v7+7v7+/w8O/w8PDx8fDx8fHy8vLz8/P09PL09PT19fX29vX29vb39/X39/f4+Pf4+Pj5+fn6+vr7+/r7+/v8/Pz9/f3+/v7///9tYCWGAAAANXRSTlMAAQIMEBoiXF1eYmZ/f39/f39/f39/f39/f39/f39/f39/f39/f3+ct77C29zo7fD4+v7+/rdyDXMAAAABYktHRJxxvMInAAACOklEQVRIx51VQW7bMBAc7i5jt0AudRK/off+qO/qN/qWIO61SFEgAewmliWLnB5IS5SlKnF1kUDO7M7MEhRw4eOwNDezz2M9XDAs1rMVH0cE4DCDX54vyKUeLibY7C4vI/BCSZzk2L+qcd4Dc7Tr63PAqvgOu/uuQ5729dfZEL51HVw3oN8z+Ls5D3ifh/cPzr0NjSUhe5gRRo7nwPnykUMPb8ARzjzQ9ZTH8dTJNcoOWKTlqYwjENiZsK5CgbwdqyGYYrIEi4eyri/wikgBiVhKIhwKE48D8UAgbMWCQLhFqZ2FGoIgGDI+S2I3l8JDjp4EQTlBsgceSooHEKEIAhKIxFlKuQyKOSRESN3h7niiWNpzgwuLffSZQIIpJiu6nd5xlaInQDACdETIKRjAjOtfvoieSqaesScUxx0RiL/6OHEyx5s0Tzs77gACWg6iTtrEL9CbTlsiKfpb5rNzUkM4/9FbR4gZLgIQpKXoJXlWRHjzXlWypB7vUJbuzIr33quayx0+EICDc3BdNr0awi+8iZqqEDAcn8qrikkNQeTokxr1KrIPgKEqZ1wzluWTGjM1UYmbzcT/gRyqsaWJft9i6UHnmjEhJPxAjemXK1b7pvm5me5QqhG9EhU+B7b1rqrGhMhejfempipOXxiPzZ/nDceENquRRVIjqm3dNq5pttv7MGU6FGrMVFjVVYjt/ql6aKf+ouGGEeKcOFOnTo6Hev9S7193D6+T1/znT6P7HYi6r34E/OfzFzi+itJ7Ai74AAAAAElFTkSuQmCC`
var EDIT_FAVORITE = `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`
var REFRESH_ALL_SERVERS = `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`
var REFRESH_ONE_SERVER = `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`
var REMOVE_FAVORITE = `iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFFSURBVFiF7ZYxbsMwDEU/1Qbp1E6ekjno0Gv0ELllpiw9RYAORYCeIFMHA7Ec8neQZUtuk06GO8gA8anpP5IybSGJOR83q3sBKAAFoAD8B4D7mIjII4AlgLuJPQ1AQ/IrAwDw8LbZvAtZTelOkdPr8fgSzymAo2r1vN3CLZcQkT4AADF3w9T6zxiZhxloBqiCXU4zmPf42O0qJKNPAWCqIID6cIA4F0JkUJEBJMYIgomSDOadLlYrmGrWkQyAZlDvoW2bA4yM065kAEAGMAZxTRM6cw3AVKHe4xIB0jGkOjZPIBh1DEBCmuZ2B0wVl/M5dCAx/a3y3l5kqP5KJ2Lu/gKgGdq6xmK9zgx+1NqZSDTqVNJLCATtzkaireubIzA1O33u95O/hgi7IBQRKxCRJ4RFNPV2zBaRlJ/SAlAACkABmBvgG+Wf86x1nhNMAAAAAElFTkSuQmCC`

View File

@@ -16,6 +16,7 @@ import (
// local
"github.com/pztrn/urtrator/cache"
"github.com/pztrn/urtrator/clipboardwatcher"
"github.com/pztrn/urtrator/colorizer"
"github.com/pztrn/urtrator/configuration"
"github.com/pztrn/urtrator/database"
@@ -30,6 +31,8 @@ import (
type Context struct {
// Caching.
Cache *cache.Cache
// Clipboard watcher.
Clipboard *clipboardwatcher.ClipboardWatcher
// Colors parser and prettifier.
Colorizer *colorizer.Colorizer
// Configuration.
@@ -65,6 +68,11 @@ func (ctx *Context) initializeCache() {
ctx.Cache.Initialize()
}
func (ctx *Context) InitializeClipboardWatcher() {
ctx.Clipboard = clipboardwatcher.New(ctx.Cache, ctx.Eventer)
ctx.Clipboard.Initialize()
}
func (ctx *Context) initializeColorizer() {
ctx.Colorizer = colorizer.New()
ctx.Colorizer.Initialize()

View File

@@ -0,0 +1,45 @@
# MacOS installation
For proper application bundle building you have to:
* Install Homebrew (http://brew.sh)
* Install Golang:
```
brew install go
```
* Install GTK+2:
```
brew install gtk+ --with-quartz-relocation
```
*Note: default GTK+2 build from Brew might not work for you!*
* Reinstall gdk-pixbuf with additional option:
```
brew install --with-relocations
```
*Note: default build might not work for you!*
* Install dylibbundler:
```
brew install dylibbundler
```
* Execute ``make-app.sh`` script from current directory. If everything
went fine - you will see URTrator.app right in this directory.
# Some descriptions
## Resources
This directory will be copied inside bundle. It contains resources needed
for proper working or/and launching.
Of course, it *might* be able to work without this directory, but it will
be superugly.

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

View File

@@ -0,0 +1,498 @@
# Author: perfectska04 (Victor C.)
# Theme: Clearlooks-Colors for Ubuntu Hardy/Gnome 2.22 or equivalent.
# Description: Clearlooks-Colors is 100% free and open source.
# NOTE: Uncommenting means to delete the "#" at the beginning of a line. Commenting means to add a "#" at the beginning of a line. The "#" tells the theme wether to ignore the specified line or not.
# These are the defined colors for the theme, you can change them in GNOME's appearance preferences.
gtk_color_scheme = "fg_color:#101010\nbg_color:#EBEBEB\nbase_color:#fff\ntext_color:#1A1A1A\nselected_bg_color:#729FCF\nselected_fg_color:#1A1A1A\ntooltip_bg_color:#F5F5B5\ntooltip_fg_color:#000"
#########
# ICONS
#########
gtk-icon-sizes = "gtk-button=16,16" # This makes button icons smaller.
#gtk-icon-sizes = "gtk-large-toolbar=16,16:gtk-small-toolbar=16,16:panel-menu=16,16:gtk-button=16,16" # This enables "compact-mode".
#gtk-button-images = 0 # Enables or disables icons on buttons (OS X-like).
#gtk-menu-popup-delay = 1 # Makes menus pop up faster! Set to 1 instead of 0 to avoid Banshee 1 bug.
##########
# PANELS
##########
include "./panel.rc" # This includes the file that handles panel theming. Gradient panel backgrounds are enabled by default for this setting. Please edit panel.rc if you don't want gradient backgrounds in your panels, or plan to use transparent/custom panels.
# The following lines make panel-menu-applet and gimmie applet's text bold.
style "bold-panel-menu"
{
font_name = "Bold"
}
widget "*Panel*slab-main-menu-panel-button*" style "bold-panel-menu"
widget "*Panel*MenuBar*" style "bold-panel-menu"
widget "*gimmie*" style "bold-panel-menu"
##########################
# GENERAL THEME SETTINGS
##########################
style "clearlooks-default"
{
GtkButton ::child-displacement-x = 0 # Pressed button icon displacement.
GtkButton ::child-displacement-y = 1 # Pressed button icon displacement.
GtkButton ::default-border = { 0, 0, 0, 0 }
GtkCheckButton ::indicator-size = 14 # Size for check buttons.
GtkRadioButton ::indicator-size = 14 # Size for radio buttons.
GtkPaned ::handle-size = 6 # Width of handles.
GtkRange ::trough-border = 0
GtkRange ::slider-width = 15
GtkRange ::stepper-size = 15
GtkScale ::slider-length = 24 # Length of sliders.
GtkScale ::trough-side-details = 1
GtkScrollbar ::min-slider-length = 30 # Min. length of scrollbars.
GtkMenuBar ::internal-padding = 0
GtkExpander ::expander-size = 16
GtkToolbar ::internal-padding = 1 # Toolbar padding.
GtkTreeView ::expander-size = 14
GtkTreeView ::vertical-separator = 0
GtkMenu ::horizontal-padding = 0
GtkMenu ::vertical-padding = 0
WnckTasklist ::fade-overlay-rect = 0
# GtkButton ::focus-padding = 0 # This can give you a more compact appearance.
GtkScrolledWindow ::scrollbar-spacing = 2 # This sets the spacing between scrollbars.
GtkTreeView::odd_row_color = mix(0.98, shade (0.93,@base_color), @selected_bg_color) # This sets the color for odd row items.
GtkEntry::honors-transparent-bg-hint = 1
# Uncomment one or both of the following for flat/unified menus or toolbars:
# GtkToolbar ::shadow-type = GTK_SHADOW_NONE # Makes toolbars flat and unified.
# GtkMenuBar ::shadow-type = GTK_SHADOW_NONE # Makes menus flat and unified.
xthickness = 1
ythickness = 1
fg[NORMAL] = @fg_color
fg[PRELIGHT] = @fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @fg_color
fg[INSENSITIVE] = darker (@bg_color)
bg[NORMAL] = @bg_color
bg[PRELIGHT] = shade (1.02, @bg_color)
bg[SELECTED] = @selected_bg_color # Color for selected items.
bg[INSENSITIVE] = @bg_color
bg[ACTIVE] = shade (0.90, @bg_color)
base[NORMAL] = @base_color
base[PRELIGHT] = shade (0.95, @bg_color)
base[ACTIVE] = shade (0.90, @bg_color)
base[SELECTED] = shade (1.25, @selected_bg_color) # Color for selected base items.
base[INSENSITIVE] = @bg_color
text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[ACTIVE] = @selected_fg_color
text[SELECTED] = @selected_fg_color
text[INSENSITIVE] = darker (@bg_color)
engine "clearlooks"
{
reliefstyle = 1 # 0 makes buttons/widgets less raised.
menubarstyle = 2 # Gradient menubar, use tweak in line 66 for flat menubars.
toolbarstyle = 0 # 0 makes bad toolbars flat.
animation = TRUE # FALSE disables progressbar animations.
style = GUMMY # Could also be set to GLOSSY.
radius = 2.0 # Roundness of widgets.
hint = "use-hints" # Set a hint to disable backward compatibility fallbacks.
}
}
#################
# THEME MODULES
#################
style "evolution-hack" = "clearlooks-default" # Hacks for Evolution Mail.
{
bg[NORMAL] = shade (1.04, @bg_color) # Color for evo treeview headers.
bg[PRELIGHT] = shade (1.08, @bg_color) # Color for evo treeview header prelight.
bg[ACTIVE] = shade (0.90, @bg_color) # Color for unfocused evo selected items.
bg[SELECTED] = shade (1.25, @selected_bg_color) # Color for evo selected items.
fg[ACTIVE] = @selected_fg_color # Color for evo active text.
fg[SELECTED] = @selected_fg_color # Color for evo selected text.
}
style "clearlooks-wide"
{
xthickness = 2 # Can't change, or clowns will eat you.
ythickness = 2 # Can't change, or clowns will eat you.
}
style "clearlooks-wider"
{
xthickness = 3 # Can't change, or clowns will eat you.
ythickness = 3 # Can't change, or clowns will eat you.
}
style "clearlooks-button" = "clearlooks-wider"
{
bg[NORMAL] = shade (1.04, @bg_color) # Color for buttons.
bg[PRELIGHT] = shade (1.08, @bg_color) # Color for button-prelight.
bg[ACTIVE] = shade (0.85, @bg_color) # Color for pressed-buttons.
}
style "clearlooks-notebook-bg"
{
bg[NORMAL] = shade (1.04, @bg_color) # Tab background.
bg[ACTIVE] = shade (0.94, @bg_color) # Unfocused tab background.
}
style "clearlooks-notebook" = "clearlooks-notebook-bg"
{
xthickness = 3 # Width of tabs and notebook borders.
ythickness = 3 # Height of tabs and notebook borders.
}
style "clearlooks-menu" = "clearlooks-wider"
{
bg[NORMAL] = shade (1.05, @bg_color) # Color of menu background.
engine "clearlooks"
{
radius = 1.0 # Roundness of menu items.
}
}
style "clearlooks-menu-item" = "clearlooks-wider"
{
fg[PRELIGHT] = @selected_fg_color # Color of selected menu item text.
bg[SELECTED] = shade (1.25, @selected_bg_color) # Color of menu items.
bg[PRELIGHT] = shade (1.25, @selected_bg_color) # Color of menu items.
}
style "clearlooks-separator-menu-item"
{
xthickness = 1
ythickness = 2
# Code for pixmap menu separators.
engine "pixmap"
{
image
{
function = HLINE
recolorable = TRUE
file = "Menu-Menubar/menu-line.png"
border = { 1, 1, 1, 1 }
stretch = TRUE
}
}
}
style "clearlooks-menubar"
{
engine "clearlooks"
{
hint = "menubar"
}
}
style "clearlooks-treeview"
{
bg[SELECTED] = shade (1.25, @selected_bg_color) # Color workaround for Banshee 1.0.
engine "clearlooks"
{
hint = "treeview"
radius = 0.0 # This makes treeview progressbars square.
}
}
style "clearlooks-treeview-header" = "clearlooks-default"
{
xthickness = 2
ythickness = 1
bg[NORMAL] = shade (1.04, @bg_color) # Color for treeview headers.
bg[PRELIGHT] = shade (1.08, @bg_color) # Color for treeview header prelight.
bg[ACTIVE] = shade (0.85, @bg_color) # Color for pressed-treeview.
engine "clearlooks" {
hint = "treeview-header"
}
}
style "clearlooks-frame-title"
{
fg[NORMAL] = lighter (@fg_color)
}
style "clearlooks-tooltips" = "clearlooks-wider"
{
bg[NORMAL] = @tooltip_bg_color
fg[NORMAL] = @tooltip_fg_color
}
style "metacity-frame" = "clearlooks-default"
{
# bg[SELECTED] = @selected_bg_color # Color for metacity borders.
}
style "clearlooks-progressbar"
{
xthickness = 1
ythickness = 1
fg[PRELIGHT] = @base_color # Progressbar prelighted text.
engine "clearlooks"
{
radius = 1.0 # Roundness of progressbars.
hint = "progressbar"
}
}
style "clearlooks-statusbar"
{
engine "clearlooks"
{
hint = "statusbar"
}
}
style "clearlooks-comboboxentry"
{
engine "clearlooks"
{
hint = "comboboxentry"
}
}
style "clearlooks-spinbutton"
{
bg[NORMAL] = shade (1.04, @bg_color) # Color for spinbuttons.
bg[PRELIGHT] = shade (1.08, @bg_color) # Color for spinbutton prelight.
bg[ACTIVE] = shade (0.85, @bg_color) # Color for pressed-spinbuttons.
engine "clearlooks"
{
hint = "spinbutton"
}
}
style "clearlooks-scale" = "clearlooks-button"
{
bg[NORMAL] = shade (1.04, @bg_color) # Color for sliders.
bg[PRELIGHT] = shade (1.08, @bg_color) # Color for slider prelight.
bg[ACTIVE] = shade (0.85, @bg_color) # Color for pressed-sliders.
engine "clearlooks"
{
hint = "scale"
}
}
style "clearlooks-hscale" = "clearlooks-scale"
{
engine "clearlooks"
{
hint = "hscale"
}
}
style "clearlooks-vscale" = "clearlooks-scale"
{
engine "clearlooks"
{
hint = "vscale"
}
}
style "clearlooks-nautilus-location" # Workaround for nautilus' messages.
{
bg[NORMAL] = shade (1.25, @selected_bg_color)
}
style "clearlooks-radiocheck" = "clearlooks-default"
{
# text[NORMAL] = shade (0.9, @selected_bg_color) # Color for checks/radio items.
# bg[SELECTED] = lighter (@selected_bg_color) # Color for prelight of check/radio buttons.
}
##############
# SCROLLBARS
##############
style "clearlooks-scrollbar"
{
bg[NORMAL] = shade (1.04, @bg_color) # Color for non-colored scrollbars.
bg[PRELIGHT] = shade (1.08, @bg_color) # Color for scrollbar prelight? (probably obsolete)
bg[ACTIVE] = shade (0.85, @bg_color) # Color for pressed scrollbar buttons.
# bg[SELECTED] = @selected_bg_color # You can change the color of colorized scrollbars here.
engine "clearlooks"
{
# colorize_scrollbar = TRUE # Uncommenting this gives you colorful scrollbars.
radius = 1.0 # Roundness of scrollbars.
hint = "scrollbar"
}
}
style "clearlooks-hscrollbar" = "clearlooks-scrollbar"
{
engine "clearlooks"
{
hint = "hscrollbar"
}
}
style "clearlooks-vscrollbar" = "clearlooks-scrollbar"
{
engine "clearlooks"
{
hint = "vscrollbar"
}
}
############
# TOOLBARS
############
#Gradient toolbars are enabled for this theme.
style "clearlooks-toolbar" = "clearlooks-default"
{
bg[NORMAL] = shade (0.965, @bg_color) # Darkens gradient toolbars to match with unified metacity theme.
engine "clearlooks"
{
toolbarstyle = 1 # This forces gradient toolbars.
}
}
style "clearlooks-evo-new-button-workaround"
{
bg[NORMAL] = shade (0.965, @bg_color)
engine "clearlooks"
{
toolbarstyle = 0
}
}
widget_class "EShellWindow.GtkVBox.BonoboDock.BonoboDockBand.BonoboDockItem*" style "clearlooks-evo-new-button-workaround"
class "GtkHandleBox" style "clearlooks-toolbar"
#########################################
# Matches
#########################################
# Clearlooks default style is applied to every widget.
class "GtkWidget" style "clearlooks-default"
# Increase the x/ythickness in some widgets.
class "GtkToolbar" style "clearlooks-toolbar"
class "GtkFrame" style "clearlooks-wide"
class "GtkEntry" style "clearlooks-wider"
class "MetaFrames" style "metacity-frame"
class "GtkSeparator" style "clearlooks-wide"
class "GtkWindow" style "metacity-frame"
class "GtkCalendar" style "clearlooks-wide"
class "GtkSpinButton" style "clearlooks-spinbutton"
class "GtkScale" style "clearlooks-scale"
class "GtkVScale" style "clearlooks-vscale"
class "GtkHScale" style "clearlooks-hscale"
class "GtkScrollbar" style "clearlooks-scrollbar"
class "GtkVScrollbar" style "clearlooks-vscrollbar"
class "GtkHScrollbar" style "clearlooks-hscrollbar"
class "GtkRadio*" style "clearlooks-radiocheck"
class "GtkCheck*" style "clearlooks-radiocheck"
# General matching following, the order is choosen so that the right styles override each other eg. progressbar needs to be more important then the menu match.
# This is not perfect, it could be done better (That is modify *every* widget in the notebook, and change those back that we really don't want changed)
widget_class "*<GtkNotebook>*<GtkEventBox>" style "clearlooks-notebook-bg"
widget_class "*<GtkNotebook>*<GtkDrawingArea>" style "clearlooks-notebook-bg"
widget_class "*<GtkNotebook>*<GtkLayout>" style "clearlooks-notebook-bg"
widget_class "*.GtkNotebook.*.GtkViewport" style "clearlooks-notebook"
widget_class "*<GtkButton>" style "clearlooks-button"
widget_class "*<GtkNotebook>" style "clearlooks-notebook"
widget_class "*<GtkStatusbar>*" style "clearlooks-statusbar"
widget_class "*<GtkComboBoxEntry>*" style "clearlooks-comboboxentry"
widget_class "*<GtkCombo>*" style "clearlooks-comboboxentry"
widget_class "*<GtkMenuBar>*" style "clearlooks-menubar"
widget_class "*<GtkMenu>*" style "clearlooks-menu"
widget_class "*<GtkMenuItem>*" style "clearlooks-menu-item"
widget_class "*<GtkSeparatorMenuItem>*" style "clearlooks-separator-menu-item"
widget_class "*.<GtkFrame>.<GtkLabel>" style "clearlooks-frame-title"
widget_class "*.<GtkTreeView>*" style "clearlooks-treeview"
widget_class "*<GtkProgressBar>" style "clearlooks-progressbar"
# Treeview header
widget_class "*.<GtkTreeView>.<GtkButton>" style "clearlooks-treeview-header"
widget_class "*.<GtkCTree>.<GtkButton>" style "clearlooks-treeview-header"
widget_class "*.<GtkList>.<GtkButton>" style "clearlooks-treeview-header"
widget_class "*.<GtkCList>.<GtkButton>" style "clearlooks-treeview-header"
# Workarounds for Evolution
widget_class "*.ETable.ECanvas" style "clearlooks-treeview-header"
widget_class "*.ETree.ECanvas" style "clearlooks-treeview-header"
widget_class "*GtkCTree*" style "evolution-hack"
widget_class "*GtkList*" style "evolution-hack"
widget_class "*GtkCList*" style "evolution-hack"
widget_class "*.ETree.*" style "evolution-hack"
widget_class "*EInfoLabel*" style "evolution-hack"
# The window of the tooltip is called "gtk-tooltip"
################################
# FIXME:
# This will not work if one embeds eg. a button into the tooltip.
# As far as I can tell right now we will need to rework the theme
# quite a bit to get this working correctly.
# (It will involve setting different priorities, etc.)
################################
widget "gtk-tooltip*" style "clearlooks-tooltips"
###################################################
# SPECIAL CASES AND WORKAROUNDS
###################################################
# Special case the nautilus-extra-view-widget
# ToDo: A more generic approach for all applications that have a widget like this.
widget "*.nautilus-extra-view-widget" style : highest "clearlooks-nautilus-location"
# Work around for http://bugzilla.gnome.org/show_bug.cgi?id=382646
# Note that the work around assumes that the combobox is _not_ in appears-as-list mode.
# This style does not affect GtkComboBoxEntry, it does have an effect on comboboxes in appears-as-list mode though.
style "clearlooks-text-is-fg-color-workaround"
{
text[NORMAL] = @fg_color
text[PRELIGHT] = @fg_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @fg_color
text[INSENSITIVE] = darker (@bg_color)
}
widget_class "*.<GtkComboBox>.<GtkCellView>" style "clearlooks-text-is-fg-color-workaround"
style "clearlooks-menuitem-text-is-fg-color-workaround"
{
text[NORMAL] = @fg_color
text[PRELIGHT] = @selected_fg_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @fg_color
text[INSENSITIVE] = darker (@bg_color)
}
widget "*.gtk-combobox-popup-menu.*" style "clearlooks-menuitem-text-is-fg-color-workaround"
# Work around the usage of GtkLabel inside GtkListItems to display text.
# This breaks because the label is shown on a background that is based on the base color set.
style "clearlooks-fg-is-text-color-workaround"
{
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[ACTIVE] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[INSENSITIVE] = darker (@bg_color)
}
widget_class "*<GtkListItem>*" style "clearlooks-fg-is-text-color-workaround"
# The same problem also exists for GtkCList and GtkCTree.
# Only match GtkCList and not the parent widgets, because that would also change the headers.
widget_class "*<GtkCList>" style "clearlooks-fg-is-text-color-workaround"
widget_class "*<EelEditableLabel>" style "clearlooks-fg-is-text-color-workaround"
# The answer to the ultimate question of life, the universe, and everything is 42.

View File

@@ -0,0 +1,53 @@
################################################
# PANELS
################################################
# Note: Uncommenting means to delete the "#" at the beginning of a line. Commenting out means to add a "#" at the beginning of a line. The "#" tells the theme wether to ignore the line or not.
style "theme-panel"
{
# The following two lines add gradient panel backgrounds. You may choose only one! Delete or comment out both to have regular, flat gnome-panels.
bg_pixmap[NORMAL] = "/Panels/panel-bg.png" # Light gradient panel.
#bg_pixmap[NORMAL] = "/Panels/panel-bg-dark.png" # Dark gradient panel.
# Uncomment the following lines when using dark panels! Note: Menus will remain the same.
# bg[SELECTED] = "#525252" # Makes selected items dark.
# bg[NORMAL] = "#3c3c3c" # Makes panel background dark.
# bg[PRELIGHT] = "#424242" # Makes panel button prelight dark.
# bg[ACTIVE] = "#333333" # Makes active buttons dark.
# bg[INSENSITIVE] = "#3C3C3C"
# fg[NORMAL] = "#D4D4D4" # Makes panel text light.
# fg[PRELIGHT] = lighter (@selected_bg_color) # Makes prelighted text colored.
# fg[SELECTED] = lighter (@selected_bg_color) # Makes prelighted text colored.
# fg[ACTIVE] = lighter (@selected_bg_color) # Makes active text colored.
# fg[INSENSITIVE] = "#666666" # Color for insensitive text.
# text[NORMAL] = @text_color
# text[PRELIGHT] = lighter (@selected_bg_color) # Makes prelighted text colored.
# text[SELECTED] = lighter (@selected_bg_color) # Makes prelighted text colored.
# text[ACTIVE] = lighter (@selected_bg_color) # Makes active text colored.
# text[INSENSITIVE] = "#666666"
}
# Panel settings. Do not change.
widget "*PanelWidget*" style "theme-panel"
widget "*PanelApplet*" style "theme-panel"
widget "*fast-user-switch*" style "theme-panel"
widget "*CPUFreq*Applet*" style "theme-panel"
widget "*indicator-applet*" style "theme-panel"
class "PanelApp*" style "theme-panel"
class "PanelToplevel*" style "theme-panel"
widget_class "*PanelToplevel*" style "theme-panel"
widget_class "*Mail*" style "theme-panel"
#class "*Panel*" style "theme-panel" # Disabled to fix bug.
widget_class "*notif*" style "theme-panel"
widget_class "*Notif*" style "theme-panel"
widget_class "*Tray*" style "theme-panel"
widget_class "*tray*" style "theme-panel"
widget_class "*Applet*Tomboy*" style "theme-panel"
widget_class "*Applet*Netstatus*" style "theme-panel"
# XFCE panel theming.
widget "*Xfce*Panel*" style "theme-panel"
class "*Xfce*Panel*" style "theme-panel"

View File

@@ -0,0 +1,6 @@
[X-GNOME-Metatheme]
Name=Clearlooks Brave
Encoding=UTF-8
GtkTheme=Clearlooks Brave
MetacityTheme=Clearlooks-Colors Metacity
IconTheme=gnome-brave

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

View File

@@ -0,0 +1,799 @@
#OS X El Capitan v0.6
gtk-color-scheme = "bg_color:#e4e4e4\nfg_color:#4c4c4c\nbase_color:#fff\ntext_color:#4c4c4c\nselected_bg_color:#116cd6\nselected_fg_color:#ffffff\ntooltip_bg_color:#fff\ntooltip_fg_color:#4c4c4c\ntitlebar_bg_color:#e4e4e4\ntitlebar_fg_color:#4c4c4c\nmenubar_bg_color:#e4e4e4\nmenubar_fg_color:#4c4c4c\ntoolbar_bg_color:#e4e4e4\ntoolbar_fg_color:#4c4c4c\nmenu_bg_color:#F5F5F5\nmenu_fg_color:#4c4c4c\npanel_bg_color:#F5F5F5\npanel_fg_color:#4c4c4c\nlink_color:#D1EDFE"
# Default Style
style "murrine-default" {
GtkArrow::arrow-scaling= 0.6
GtkButton::child-displacement-x = 0
GtkButton::child-displacement-y = 0
GtkButton::default-border = { 0, 0, 0, 0 }
GtkButtonBox::child-min-height = 26
GtkCheckButton::indicator-size = 16
# The following line hints to gecko (and possibly other appliations)
# that the entry should be drawn transparently on the canvas.
# Without this, gecko will fill in the background of the entry.
GtkEntry::honors-transparent-bg-hint = 1
GtkEntry::state-hint = 0
GtkExpander::expander-size = 16
GtkImage::x-ayatana-indicator-dynamic = 1
GtkMenu::horizontal-padding = 0
GtkMenu::vertical-padding = 0
GtkMenuBar::internal-padding = 0
GtkMenuBar::window-dragging = 1
GtkMenuItem::arrow-scaling= 0.5
GtkPaned::handle-size = 1
GtkProgressBar::min-horizontal-bar-height = 4
GtkProgressBar::min-vertical-bar-width = 4
GtkRange::trough-border = 0
GtkRange::slider-width = 12
GtkRange::stepper-size = 12
GtkRange::stepper_spacing = 0
GtkRange::trough-under-steppers = 1
GtkScale::slider-length = 16
GtkScale::slider-width = 16
GtkScale::trough-side-details = 1
GtkScrollbar::activate-slider = 1
GtkScrollbar::has-backward-stepper = 0
GtkScrollbar::has-forward-stepper = 0
GtkScrollbar::has-secondary-backward-stepper = 0
GtkScrollbar::has-secondary-forward-stepper = 0
GtkScrollbar::min-slider-length = 80
GtkScrollbar::slider-width = 6
GtkScrollbar::trough-border = 3
GtkScrolledWindow::scrollbar-spacing = 0
GtkScrolledWindow::scrollbars-within-bevel = 1
GtkSeparatorMenuItem::horizontal-padding = 0
GtkToolbar::internal-padding = 0
GtkTreeView::expander-size = 11
GtkTreeView::vertical-separator = 0
GtkWidget::focus-line-width = 1
# The following line prevents the Firefox tabs
# from jumping a few pixels when you create a new tab
GtkWidget::focus-padding = 0
GtkWidget::wide-separators = 1
GtkWidget::separator-width = 1
GtkWidget::separator-height = 1
GtkWindow::resize-grip-height = 0
GtkWindow::resize-grip-width = 0
WnckTasklist::fade-overlay-rect = 0
GnomeHRef::link_color = @link_color
GtkHTML::link-color = @link_color
GtkIMHtmlr::hyperlink-color = @link_color
GtkIMHtml::hyperlink-color = @link_color
GtkWidget::link-color = @link_color
GtkWidget::visited-link-color = @text_color
GtkToolbar::shadow-type = GTK_SHADOW_NONE # Makes toolbars flat and unified
GtkMenuBar::shadow-type = GTK_SHADOW_NONE # Makes menubars flat and unified
xthickness = 1
ythickness = 1
fg[NORMAL] = @fg_color
fg[PRELIGHT] = @fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @fg_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @fg_color)
bg[NORMAL] = @bg_color
bg[PRELIGHT] = shade (1.02, @bg_color)
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = shade (0.9, @bg_color)
bg[INSENSITIVE] = @bg_color
base[NORMAL] = @base_color
base[PRELIGHT] = shade (0.95, @base_color)
base[SELECTED] = @selected_bg_color
base[ACTIVE] = @selected_bg_color
base[INSENSITIVE] = shade (0.85, @base_color)
text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @selected_fg_color
text[INSENSITIVE] = mix (0.5, @base_color, @text_color)
engine "murrine" {
animation = TRUE
arrowstyle = 1 # 0 = normal arrows, 1 = filled arrows
border_shades = { 1.0, 1.0 } # gradient to draw on border
colorize_scrollbar = FALSE
comboboxstyle = 0 # 0 = normal combobox, 1 = colorized combobox below arrow
contrast = 0.8 # overal contrast with borders
default_button_color = @selected_bg_color
focusstyle = 3 # 0 = none, 1 = grey dotted, 2 = colored with fill, 3 = colored glow
glazestyle = 0 # 0 = flat highlight, 1 = curved highlight, 2 = concave, 3 = top curved highlight, 4 = beryl highlight
glowstyle = 0 # 0 = glow on top, 1 = glow on bottom, 2 = glow on top and bottom, 3 = glow on middle vertically, 4 = glow on middle horizontally, 5 = glow on all sides
glow_shade = 1.0 # amount of glow
gradient_shades = { 1.0, 1.0, 1.0, 1.0 } # gradient to draw on widgets
highlight_shade = 1.0 # amount of highlight
lightborder_shade = 1.0 # amount of inset light border
lightborderstyle = 1 # 0 = lightborder on top side, 1 = lightborder on all sides
listviewheaderstyle = 0 # 0 = flat, 1 = glassy, 2 = raised
listviewstyle = 0 # 0 = none, 1 = dotted, 2 = line
menubaritemstyle = 0 # 0 = menuitem look, 1 = button look
menubarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient, 3 = striped
menuitemstyle = 0 # 0 = flat, 1 = glassy, 2 = striped
menustyle = 0 # 0 = none, 1 = vertical striped
progressbarstyle = 0 # 0 = none, 1 = diagonal striped, 2 = vertical striped
reliefstyle = 0 # 0 = flat, 1 = inset, 2 = shadow, 3 = shadow with gradient, 4 = stronger shadow with gradient
roundness = 1 # roundness of widgets
scrollbarstyle = 0 # 0 = none, 1 = circles, 2 = handles, 3 = diagonal stripes, 4 = diagonal stripes and handles, 5 = horizontal stripes, 6 = horizontal stripes and handles
sliderstyle = 0 # 0 = none, 1 = handles
stepperstyle = 1 # 0 = standard, 1 = integrated stepper handles
toolbarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient
}
}
style "murrine-wide" {
xthickness = 2
ythickness = 2
}
style "murrine-wider" {
xthickness = 3
ythickness = 3
}
style "murrine-thin" {
xthickness = 0
ythickness = 0
}
# Notebook
style "murrine-notebook-bg" {
bg[NORMAL] = @bg_color
bg[ACTIVE] = shade (0.9, @bg_color)
}
style "murrine-notebook" = "murrine-notebook-bg" {
xthickness = 2
ythickness = 2
engine "murrine" {
roundness = 6
gradient_shades = {1.1,1.0,1.0,0.9}
}
}
# Various Standard Widgets
style "murrine-button" = "murrine-wider" {
bg[NORMAL] = shade (1.1, @bg_color)
bg[PRELIGHT] = @bg_color
bg[ACTIVE] = @selected_bg_color
bg[INSENSITIVE] = shade (0.85, @bg_color)
engine "murrine" {
contrast = .8
lightborder_shade = 1.9
roundness = 4
border_shades = {0.95, 0.8}
shadow_shades = {1.0, 0.1}
gradient_shades = {1.1,1.0,1.0,0.9}
}
}
style "murrine-scrollbar" {
bg[NORMAL] = mix (0.21, @fg_color, @bg_color)
bg[PRELIGHT] = mix (0.31, @fg_color, @bg_color)
bg[ACTIVE] = shade (0.8, @bg_color)
engine "murrine" {
roundness = 6
contrast = 0.0
border_shades = { 1.0, 1.0 }
trough_shades = { 1.0, 1.0 }
trough_border_shades = { 1.0, 1.0 }
}
}
style "murrine-overlay-scrollbar" {
bg[ACTIVE] = shade (0.8, @bg_color)
bg[INSENSITIVE] = shade (0.97, @bg_color)
base[SELECTED] = shade (0.6, @base_color)
base[INSENSITIVE] = shade (0.85, @base_color)
}
style "murrine-scale" = "murrine-thin" {
bg[NORMAL] = @bg_color
bg[ACTIVE] = @bg_color
bg[SELECTED] = @selected_bg_color
bg[INSENSITIVE] = shade (0.95, @bg_color)
engine "murrine" {
roundness = 6
gradient_shades = { 1.08, 1.08, 1.08, 1.08 }
border_shades = { 1.0, 1.0 }
trough_shades = { 1.08, 1.08 }
trough_border_shades = { 0.8, 0.8 }
}
}
style "murrine-progressbar" = "murrine-thin" {
bg[NORMAL] = @bg_color
bg[ACTIVE] = shade (1.08, @bg_color)
fg[PRELIGHT] = @selected_fg_color
engine "murrine" {
roundness = 8
border_shades = { 1.2, 1.2 }
trough_border_shades = { 0.8, 0.8 }
}
}
style "murrine-treeview-header" = "murrine-button" {
engine "murrine" {
roundness = 0
}
}
style "murrine-treeview" {
engine "murrine" {
roundness = 0
}
}
style "murrine-frame-title" {
fg[NORMAL] = lighter (@fg_color)
}
style "murrine-tooltips" {
xthickness = 5
ythickness = 5
bg[NORMAL] = @tooltip_bg_color
bg[SELECTED] = @tooltip_bg_color
fg[NORMAL] = @tooltip_fg_color
engine "murrine" {
textstyle = 0
roundness = 2
rgba = FALSE
}
}
style "murrine-spinbutton" = "murrine-button" {
engine "murrine" {
}
}
style "murrine-radiocheck" = "murrine-default" {
bg[NORMAL] = @base_color
bg[SELECTED] = @selected_bg_color
text[NORMAL] = @base_color
text[PRELIGHT] = @base_color
engine "murrine" {
reliefstyle = 0
gradient_shades = {1.2, 1.0, 1.0, 0.9}
shadow_shades = {0.6, 0.5}
textstyle = 0
}
}
style "murrine-entry" = "murrine-wider" {
engine "murrine" {
roundness = 6
border_shades = { 1.15, 1.15 }
}
}
style "metacity-frame" = "murrine-default" {
bg[SELECTED] = @selected_bg_color
}
style "murrine-statusbar" { }
style "murrine-comboboxentry" = "murrine-entry" { }
style "murrine-hscale" = "murrine-scale" { }
style "murrine-vscale" = "murrine-scale" { }
style "murrine-hscrollbar" = "murrine-scrollbar" { }
style "murrine-vscrollbar" = "murrine-scrollbar" { }
# Menus
style "murrine-menu" = "murrine-thin" {
bg[NORMAL] = @menu_bg_color
bg[PRELIGHT] = @selected_bg_color
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = @menu_bg_color
bg[INSENSITIVE] = @menu_bg_color
fg[NORMAL] = @menu_fg_color
fg[PRELIGHT] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @selected_fg_color
fg[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color)
text[NORMAL] = @menu_fg_color
text[PRELIGHT] = @selected_fg_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @selected_fg_color
text[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color)
engine "murrine" {
roundness = 0
}
}
style "murrine-menu-item" = "murrine-wider" {
bg[PRELIGHT] = @selected_bg_color
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = @selected_bg_color
fg[NORMAL] = @menu_fg_color # Fix for XFCE menu text
fg[PRELIGHT] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @selected_fg_color
fg[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color)
engine "murrine" {
textstyle = 0
border_shades = { 1.2, 1.2 }
}
}
style "murrine-separator-menu-item" = "murrine-thin" { }
style "murrine-menubar" {
bg[NORMAL] = @menubar_bg_color
bg[PRELIGHT] = mix (0.21, @menubar_fg_color, @menubar_bg_color)
bg[SELECTED] = mix (0.21, @menubar_fg_color, @menubar_bg_color)
bg[ACTIVE] = shade (0.9, @menubar_bg_color)
bg[INSENSITIVE] = @menubar_bg_color
fg[NORMAL] = @menubar_fg_color
fg[PRELIGHT] = shade (1.08, @menubar_fg_color)
fg[SELECTED] = shade (1.08, @menubar_fg_color)
fg[ACTIVE] = @menubar_fg_color
fg[INSENSITIVE] = mix (0.5, @menubar_bg_color, @menubar_fg_color)
engine "murrine" {
roundness = 0
}
}
style "murrine-menubaritem" {
bg[NORMAL] = @menubar_bg_color
bg[PRELIGHT] = mix (0.21, @menubar_fg_color, @menubar_bg_color)
bg[SELECTED] = mix (0.21, @menubar_fg_color, @menubar_bg_color)
bg[ACTIVE] = shade (0.9, @menubar_bg_color)
bg[INSENSITIVE] = @menubar_bg_color
fg[NORMAL] = @menubar_fg_color
fg[PRELIGHT] = shade (1.08, @menubar_fg_color)
fg[SELECTED] = shade (1.08, @menubar_fg_color)
fg[ACTIVE] = @menubar_fg_color
fg[INSENSITIVE] = mix (0.5, @menubar_bg_color, @menubar_fg_color)
engine "murrine" {
roundness = 0
}
}
# Toolbars
style "murrine-toolbar" = "murrine-thin" {
bg[NORMAL] = @bg_color
bg[PRELIGHT] = shade (1.02, @bg_color)
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = shade (0.9, @bg_color)
bg[INSENSITIVE] = @bg_color
fg[NORMAL] = @fg_color
fg[PRELIGHT] = @fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @fg_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @fg_color)
engine "murrine" {
}
}
style "murrine-toolbutton" = "murrine-button" {
bg[NORMAL] = shade (1.08, @bg_color)
bg[PRELIGHT] = shade (1.10, @bg_color)
bg[SELECTED] = @bg_color
bg[ACTIVE] = shade (0.95, @bg_color)
bg[INSENSITIVE] = shade (0.85, @bg_color)
fg[NORMAL] = @fg_color
fg[PRELIGHT] = @fg_color
fg[SELECTED] = @fg_color
fg[ACTIVE] = @fg_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @fg_color)
engine "murrine" {
roundness = 6
}
}
class "GtkToolbar" style "murrine-toolbar"
class "GtkHandleBox" style "murrine-toolbar"
widget_class "*Toolbar*.*Separator*" style "murrine-toolbar"
# Panels
style "murrine-panel" = "murrine-thin" {
xthickness = 2
bg[NORMAL] = @panel_bg_color
bg[PRELIGHT] = mix (0.21, @panel_fg_color, @panel_bg_color)
bg[SELECTED] = mix (0.21, @panel_fg_color, @panel_bg_color)
bg[ACTIVE] = shade (0.8, @panel_bg_color)
bg[INSENSITIVE] = @panel_bg_color
fg[NORMAL] = @panel_fg_color
fg[PRELIGHT] = shade (1.08, @panel_fg_color)
fg[SELECTED] = shade (1.08, @panel_fg_color)
fg[ACTIVE] = @panel_fg_color
fg[INSENSITIVE] = mix (0.5, @panel_bg_color, @panel_fg_color)
base[NORMAL] = @panel_bg_color
base[PRELIGHT] = mix (0.21, @panel_fg_color, @panel_bg_color)
base[SELECTED] = mix (0.21, @panel_fg_color, @panel_bg_color)
base[ACTIVE] = shade (0.9, @panel_bg_color)
base[INSENSITIVE] = @panel_bg_color
text[NORMAL] = @panel_fg_color
text[PRELIGHT] = shade (1.08, @panel_fg_color)
text[SELECTED] = shade (1.08, @panel_fg_color)
text[ACTIVE] = @panel_fg_color
text[INSENSITIVE] = mix (0.5, @panel_bg_color, @panel_fg_color)
engine "murrine" {
roundness = 0
contrast = 0.0
}
}
widget "*PanelWidget*" style "murrine-panel"
widget "*PanelApplet*" style "murrine-panel"
widget "*fast-user-switch*" style "murrine-panel"
widget "*CPUFreq*Applet*" style "murrine-panel"
widget "*indicator-applet*" style "murrine-panel"
class "PanelApp*" style "murrine-panel"
class "PanelToplevel*" style "murrine-panel"
widget_class "*PanelToplevel*" style "murrine-panel"
widget_class "*notif*" style "murrine-panel"
widget_class "*Notif*" style "murrine-panel"
widget_class "*Tray*" style "murrine-panel"
widget_class "*tray*" style "murrine-panel"
widget_class "*computertemp*" style "murrine-panel"
widget_class "*Applet*Tomboy*" style "murrine-panel"
widget_class "*Applet*Netstatus*" style "murrine-panel"
widget "*gdm-user-switch-menubar*" style "murrine-panel"
style "bold-panel-item" {
font_name = "Bold"
engine "murrine" {
roundness = 0
}
}
widget "*Panel*MenuBar*" style "bold-panel-item"
widget "*gimmie*" style "bold-panel-item"
# widget_class "*Mail*" style "murrine-panel" # Disabled to fix Evolution bug
# class "*Panel*" style "murrine-panel" # Disabled to fix bug
# XFCE Styles
style "workspace-switcher" = "murrine-panel" {
bg[SELECTED] = @selected_bg_color
}
style "xfce-header" {
bg[NORMAL] = shade (0.9, @bg_color)
base[NORMAL] = shade (1.18, @bg_color)
}
style "xfdesktop-windowlist" {
bg[NORMAL] = @base_color
fg[INSENSITIVE] = shade (0.95, @base_color)
text[INSENSITIVE] = shade (0.95, @base_color)
}
style "xfdesktop-icon-view" {
XfdesktopIconView::label-alpha = 0
XfdesktopIconView::selected-label-alpha = 60
XfdesktopIconVIew::ellipsize-icon-labels = 1
base[NORMAL] = @selected_bg_color
base[SELECTED] = @selected_bg_color
base[ACTIVE] = @selected_bg_color
fg[NORMAL] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @selected_fg_color
engine "murrine" {
textstyle = 5
text_shade = 0.05
}
}
style "xfwm-tabwin" {
Xfwm4TabwinWidget::border-width = 0
Xfwm4TabwinWidget::icon-size = 64
bg[NORMAL] = @menu_bg_color
fg[NORMAL] = @menu_fg_color
engine "murrine" {
focusstyle = 0
}
}
style "xfsm-logout" {
bg[NORMAL] = @menu_bg_color
bg[ACTIVE] = @menu_bg_color
bg[PRELIGHT] = shade (1.1, @menu_bg_color)
bg[SELECTED] = shade (0.5, @menu_bg_color)
bg[INSENSITIVE] = shade (1.3, @menu_bg_color)
fg[NORMAL] = @menu_fg_color
fg[PRELIGHT] = @menu_fg_color
text[NORMAL] = @menu_fg_color
engine "murrine" {
}
}
style "xfsm-logout-button" {
bg[NORMAL] = shade (1.2, @menu_bg_color)
bg[PRELIGHT] = shade (1.4, @menu_bg_color)
engine "murrine" {
}
}
widget "*WnckPager*" style "workspace-switcher"
widget "*Xfce*Panel*" style "murrine-panel"
class "*Xfce*Panel*" style "murrine-panel"
# Thunar Styles
style "sidepane" {
base[NORMAL] = @bg_color
base[INSENSITIVE] = mix (0.4, shade (1.35, @selected_bg_color), shade (0.9, @base_color))
bg[NORMAL] = @bg_color
text[NORMAL] = mix (0.9, @fg_color, @bg_color)
}
widget_class "*ThunarShortcutsView*" style "sidepane"
widget_class "*ThunarTreeView*" style "sidepane"
widget_class "*ThunarLocationEntry*" style "murrine-entry"
# Gtk2 Open-File Dialog
widget_class "*GtkFileChooserWidget.GtkFileChooserDefault.GtkVBox.GtkHPaned.GtkVBox.GtkScrolledWindow.GtkTreeView*" style "sidepane"
widget_class "*GtkFileChooserWidget.GtkFileChooserDefault.GtkVBox.GtkHPaned.GtkVBox.GtkScrolledWindow.<GtkTreeView>.<GtkButton>" style "murrine-treeview-header"
# Google Chrome/Chromium Styles (requires 9.0.597 or newer)
style "chromium-toolbar-button" {
engine "murrine" {
roundness = 4
textstyle = 0
}
}
style "chrome-gtk-frame" {
ChromeGtkFrame::frame-color = @titlebar_bg_color
ChromeGtkFrame::inactive-frame-color = @titlebar_bg_color
ChromeGtkFrame::frame-gradient-size = 0
ChromeGtkFrame::frame-gradient-color = @titlebar_bg_color
ChromeGtkFrame::incognito-frame-color = @titlebar_bg_color
ChromeGtkFrame::incognito-inactive-frame-color = @titlebar_bg_color
ChromeGtkFrame::incognito-frame-gradient-size = 0
ChromeGtkFrame::incognito-frame-gradient-color = @titlebar_bg_color
ChromeGtkFrame::scrollbar-trough-color = @bg_color
ChromeGtkFrame::scrollbar-slider-normal-color = mix (0.21, @fg_color, @bg_color)
ChromeGtkFrame::scrollbar-slider-prelight-color = mix (0.31, @fg_color, @bg_color)
}
class "ChromeGtkFrame" style "chrome-gtk-frame"
widget_class "*Chrom*Button*" style "chromium-toolbar-button"
# General Styles
class "GtkWidget" style "murrine-default"
class "GtkFrame" style "murrine-wide"
class "MetaFrames" style "metacity-frame"
class "GtkWindow" style "metacity-frame"
class "GtkSeparator" style "murrine-wide"
class "GtkCalendar" style "murrine-wide"
class "GtkSpinButton" style "murrine-spinbutton"
class "GtkScale" style "murrine-scale"
class "GtkVScale" style "murrine-vscale"
class "GtkHScale" style "murrine-hscale"
class "GtkScrollbar" style "murrine-scrollbar"
class "GtkVScrollbar" style "murrine-vscrollbar"
class "GtkHScrollbar" style "murrine-hscrollbar"
class "GtkRadio*" style "murrine-radiocheck"
class "GtkCheck*" style "murrine-radiocheck"
class "GtkEntry" style "murrine-entry"
widget_class "*<GtkNotebook>" style "murrine-notebook"
widget_class "*<GtkNotebook>*<GtkEventBox>" style "murrine-notebook-bg"
widget_class "*<GtkNotebook>*<GtkDrawingArea>" style "murrine-notebook-bg"
widget_class "*<GtkNotebook>*<GtkLayout>" style "murrine-notebook-bg"
widget_class "*.GtkNotebook.*.GtkViewport" style "murrine-notebook"
widget_class "*<GtkButton>" style "murrine-button"
widget_class "*<GtkStatusbar>*" style "murrine-statusbar"
widget_class "*<GtkProgress>" style "murrine-progressbar"
widget_class "*<GtkProgressBar>" style "murrine-progressbar"
widget_class "*<GtkComboBoxEntry>*" style "murrine-comboboxentry"
widget_class "*<GtkCombo>*" style "murrine-comboboxentry"
widget_class "*<GtkMenu>*" style "murrine-menu"
widget_class "*<GtkMenuItem>*" style "murrine-menu-item"
widget_class "*<GtkSeparatorMenuItem>*" style "murrine-separator-menu-item"
widget_class "*Menu*.*Sepa*" style "murrine-separator-menu-item"
widget_class "*<GtkMenuBar>*" style "murrine-menubar"
widget_class "*<GtkMenuBar>*<GtkMenuItem>*" style "murrine-menubaritem"
widget_class "*GtkToolButton*" style "murrine-toolbutton"
widget_class "*GtkToggleToolButton*" style "murrine-toolbutton"
widget_class "*GtkMenuToolButton*" style "murrine-toolbutton"
widget_class "*GtkToolbar*Button" style "murrine-toolbutton"
widget_class "*.<GtkFrame>.<GtkLabel>" style "murrine-frame-title"
widget_class "*.<GtkTreeView>*" style "murrine-treeview"
widget_class "*.<GtkTreeView>.<GtkButton>" style "murrine-treeview-header"
widget_class "*.<GtkCTree>.<GtkButton>" style "murrine-treeview-header"
widget_class "*.<GtkList>.<GtkButton>" style "murrine-treeview-header"
widget_class "*.<GtkCList>.<GtkButton>" style "murrine-treeview-header"
widget "gtk-tooltip*" style "murrine-tooltips"
widget_class "*<GtkScrolledWindow>*<OsScrollbar>" style "murrine-overlay-scrollbar"
# Workarounds and Non-Standard Styling
style "text-is-fg-color-workaround" {
text[NORMAL] = @text_color
text[PRELIGHT] = @fg_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @fg_color
text[INSENSITIVE] = mix (0.5, @bg_color, @fg_color)
}
widget_class "*.<GtkComboBox>.<GtkCellView>" style "text-is-fg-color-workaround"
style "fg-is-text-color-workaround" {
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[ACTIVE] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[INSENSITIVE] = darker (@fg_color)
}
widget_class "*<GtkListItem>*" style "fg-is-text-color-workaround"
widget_class "*<GtkCList>" style "fg-is-text-color-workaround"
widget_class "*<EelEditableLabel>" style "fg-is-text-color-workaround"
style "murrine-evo-new-button-workaround" {
engine "murrine" {
toolbarstyle = 0
}
}
widget_class "EShellWindow.GtkVBox.BonoboDock.BonoboDockBand.BonoboDockItem*" style "murrine-evo-new-button-workaround"
style "inkscape-toolbar-fix" {
engine "murrine" {
gradient_shades = { 1.0, 1.0, 1.0, 1.0 }
highlight_shade = 1.0
}
}
#widget "*GtkHandleBox*" style "inkscape-toolbar-fix"
#widget "*HandleBox*CommandsToolbar*" style "inkscape-toolbar-fix"
#widget "*HandleBox*SnapToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*SelectToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*NodeToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*TweakToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*ZoomToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*StarToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*RectToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*3DBoxToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*ArcToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*SpiralToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*PencilToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*PenToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*CalligraphyToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*EraserToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*LPEToolToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*DropperToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*ConnectorToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*PaintbucketToolbar*" style "inkscape-toolbar-fix"
# Performance Fixes
style "performance-fix" {
engine "murrine" {
textstyle = 0
}
}
widget_class "*gtkmm__GtkWindow*" style "performance-fix" # Inkscape
widget_class "*GimpDisplayShell*" style "performance-fix" # Gimp
widget_class "*GimpToolbox*" style "performance-fix"
widget_class "*GimpMenuDock*" style "performance-fix"
widget "*OOoFixed*" style "performance-fix" # Openoffice/Libreoffice
widget_class "*MozContainer*" style "performance-fix" # Firefox (Not sure if this one does anything though.)
widget_class "*XfceHeading*" style "xfce-header"
widget_class "*XfceDesktop*" style "xfdesktop-windowlist"
widget_class "*XfdesktopIconView*" style "xfdesktop-icon-view"
widget "xfwm4-tabwin*" style "xfwm-tabwin"
widget_class "*XfsmLogoutDialog*" style "xfsm-logout"
widget_class "*XfsmLogoutDialog*GtkButton" style "xfsm-logout-button"
widget "*Panel*" style "panel"
widget "*PanelWidget*" style "panel"
widget "*PanelApplet*" style "panel"
widget "*fast-user-switch*" style "panel" # workaround for Fast User Switch applet
widget "*CPUFreqApplet*" style "panel" # workaround for CpuFreq Applet
class "PanelApp*" style "panel"
class "PanelToplevel*" style "panel"
#widget_class "*Mail*" style "panel"
widget_class "*notif*" style "panel"
#widget_class "*?anel*utton" style "panel_task_button" # causing problems to monodevelop
widget "*task*" style "panel_task_button"
widget "*.tasklist-button" style "panel_task_button"
widget "*PanelApplet*TaskTitle*" style "panel_task_button"
widget_class "*Xfce*Panel*" style "XFCE"
class "GtkScrollbar" style "murrine-scrollbar"

View File

@@ -0,0 +1,11 @@
[Desktop Entry]
Type=X-GNOME-Metatheme
Name=OS X El Capitan
Comment=A theme by Christian Medel (Elbullazul) simulating OS X 10.11 El Capitan
Comment=v0.5
Encoding=UTF-8
[X-GNOME-Metatheme]
GtkTheme=OS X El Capitan
MetacityTheme=OS X El Capitan
ButtonLayout=:minimize,maximize,close

View File

@@ -0,0 +1,2 @@
include "ClearlooksBrave/gtk-2.0/gtkrc"
include "gtkrc-keybindings"

View File

@@ -0,0 +1,157 @@
gtk-enable-mnemonics = 0
binding "gtk-mac-alt-arrows"
{
bind "<alt>Right" { "move-cursor" (words, 1, 0) }
bind "<alt>KP_Right" { "move-cursor" (words, 1, 0) }
bind "<alt>Left" { "move-cursor" (words, -1, 0) }
bind "<alt>KP_Left" { "move-cursor" (words, -1, 0) }
bind "<shift><alt>Right" { "move-cursor" (words, 1, 1) }
bind "<shift><alt>KP_Right" { "move-cursor" (words, 1, 1) }
bind "<shift><alt>Left" { "move-cursor" (words, -1, 1) }
bind "<shift><alt>KP_Left" { "move-cursor" (words, -1, 1) }
}
class "GtkTextView" binding "gtk-mac-alt-arrows"
class "GtkLabel" binding "gtk-mac-alt-arrows"
class "GtkEntry" binding "gtk-mac-alt-arrows"
binding "gtk-mac-alt-delete"
{
bind "<alt>Delete" { "delete-from-cursor" (word-ends, 1) }
bind "<alt>KP_Delete" { "delete-from-cursor" (word-ends, 1) }
bind "<alt>BackSpace" { "delete-from-cursor" (word-ends, -1) }
}
class "GtkTextView" binding "gtk-mac-alt-delete"
class "GtkEntry" binding "gtk-mac-alt-delete"
binding "gtk-mac-cmd-c"
{
bind "<meta>x" { "cut-clipboard" () }
bind "<meta>c" { "copy-clipboard" () }
bind "<meta>v" { "paste-clipboard" () }
unbind "<ctrl>x"
unbind "<ctrl>c"
unbind "<ctrl>v"
}
class "GtkTextView" binding "gtk-mac-cmd-c"
class "GtkEntry" binding "gtk-mac-cmd-c"
binding "gtk-mac-text-view"
{
bind "<shift><meta>a" { "select-all" (0) }
bind "<meta>a" { "select-all" (1) }
unbind "<shift><ctrl>a"
unbind "<ctrl>a"
}
class "GtkTextView" binding "gtk-mac-text-view"
binding "gtk-mac-label"
{
bind "<meta>a" {
"move-cursor" (paragraph-ends, -1, 0)
"move-cursor" (paragraph-ends, 1, 1)
}
bind "<shift><meta>a" { "move-cursor" (paragraph-ends, 0, 0) }
bind "<meta>c" { "copy-clipboard" () }
unbind "<ctrl>a"
unbind "<shift><ctrl>a"
unbind "<ctrl>c"
}
class "GtkLabel" binding "gtk-mac-label"
binding "gtk-mac-entry"
{
bind "<meta>a" {
"move-cursor" (buffer-ends, -1, 0)
"move-cursor" (buffer-ends, 1, 1)
}
bind "<shift><meta>a" { "move-cursor" (visual-positions, 0, 0) }
unbind "<ctrl>a"
unbind "<shift><ctrl>a"
}
class "GtkEntry" binding "gtk-mac-entry"
binding "gtk-mac-cmd-arrows"
{
bind "<meta>Left" { "move-cursor" (paragraph-ends, -1, 0) }
bind "<meta>KP_Left" { "move-cursor" (paragraph-ends, -1, 0) }
bind "<shift><meta>Left" { "move-cursor" (paragraph-ends, -1, 1) }
bind "<shift><meta>KP_Left" { "move-cursor" (paragraph-ends, -1, 1) }
bind "<meta>Right" { "move-cursor" (paragraph-ends, 1, 0) }
bind "<meta>KP_Right" { "move-cursor" (paragraph-ends, 1, 0) }
bind "<shift><meta>Right" { "move-cursor" (paragraph-ends, 1, 1) }
bind "<shift><meta>KP_Right" { "move-cursor" (paragraph-ends, 1, 1) }
}
class "GtkTextView" binding "gtk-mac-cmd-arrows"
class "GtkLabel" binding "gtk-mac-cmd-arrows"
class "GtkEntry" binding "gtk-mac-cmd-arrows"
binding "gtk-mac-emacs-like"
{
bind "<ctrl>a" { "move-cursor" (paragraph-ends, -1, 0) }
bind "<shift><ctrl>a" { "move-cursor" (paragraph-ends, -1, 1) }
bind "<ctrl>e" { "move-cursor" (paragraph-ends, 1, 0) }
bind "<shift><ctrl>e" { "move-cursor" (paragraph-ends, 1, 1) }
bind "<ctrl>b" { "move-cursor" (logical-positions, -1, 0) }
bind "<shift><ctrl>b" { "move-cursor" (logical-positions, -1, 1) }
bind "<ctrl>f" { "move-cursor" (logical-positions, 1, 0) }
bind "<shift><ctrl>f" { "move-cursor" (logical-positions, 1, 1) }
}
class "GtkTextView" binding "gtk-mac-emacs-like"
class "GtkLabel" binding "gtk-mac-emacs-like"
class "GtkEntry" binding "gtk-mac-emacs-like"
binding "gtk-mac-file-chooser"
{
bind "<meta>v" { "location-popup-on-paste" () }
unbind "<ctrl>v"
bind "<meta><shift>G" { "location-popup" () }
bind "<meta><shift>H" { "home-folder" () }
bind "<meta>Up" { "up-folder" () }
}
class "GtkFileChooserDefault" binding "gtk-mac-file-chooser"
binding "gtk-mac-tree-view"
{
bind "<meta>a" { "select-all" () }
bind "<shift><meta>a" { "unselect-all" () }
bind "<meta>f" { "start-interactive-search" () }
bind "<meta>F" { "start-interactive-search" () }
unbind "<ctrl>a"
unbind "<shift><ctrl>a"
unbind "<ctrl>f"
unbind "<ctrl>F"
}
class "GtkTreeView" binding "gtk-mac-tree-view"
binding "gtk-mac-icon-view"
{
bind "<meta>a" { "select-all" () }
bind "<shift><meta>a" { "unselect-all" () }
unbind "<ctrl>a"
unbind "<shift><ctrl>a"
}
class "GtkIconView" binding "gtk-mac-icon-view"

View File

@@ -0,0 +1,155 @@
#!/bin/bash
#####################################################################
# HELPER FUNCTIONS
#####################################################################
# Libraries work.
change_framework_library_load_path() {
local bin_to_fix=$1
local path=$2
# First iteration - main libraries.
echo "Copying libraries..."
dylibbundler -of -b -x ${bin_to_fix} -d ./URTrator.app/Contents/Framework/ -p ${path}
# Fix shit for dylibbundler. By this moment we should have everything
# we needed in Framework directory.
for lib in $(ls ./URTrator.app/Contents/Framework); do
libname=$(echo ${lib} | awk -F"/" {' print $NF '})
DEPS=$(otool -L ./URTrator.app/Contents/Framework/${lib} | grep "/usr/local")
for dep in ${DEPS[@]}; do
dep_name=$(echo ${dep} | awk -F"/" {' print $NF '})
install_name_tool -change ${dep} ${path}/${dep_name} ./URTrator.app/Contents/Framework/${libname}
done
done
}
# More permissive UMASK.
umask 002
# Do some checks.
# Do we have brew installed?
brew config | grep HOMEBREW_VERSION &>/dev/null
if [ $? -ne 0 ]; then
echo "Please, install brew (http://brew.sh)"
exit 1
fi
# Do we have Go installed?
# ToDo: more proper check.
if [ -z ${GOPATH} ]; then
echo "Please, install Go >= 1.7 for continue and configure your shell. See Go installation docs for more information."
exit 1
fi
# Do we have GTK+ installed?
GTK_STATUS=$(brew info gtk+ | grep Cellar)
if [ $? -ne 0 ]; then
echo "Please, install GTK+ (brew install gtk+ gtksourceview)"
exit 1
fi
# Okay, let's compile.
echo "Getting URTrator (and dependencies) sources"
go get -u -v -d github.com/pztrn/urtrator
if [ $? -ne 0 ]; then
echo "Failed to get URTrator sources"
exit 1
fi
echo "Building URTrator..."
go install -v github.com/pztrn/urtrator
if [ $? -ne 0 ]; then
echo "Failed to build URTrator! Please, create a new bug report at https://github.com/pztrn/urtrator and attach FULL console output!"
exit 1
fi
echo "Creating app bundle..."
mkdir -p URTrator.app/Contents/{MacOS,Framework,Resources}
# Copying URTrator binary
cp $GOPATH/bin/urtrator URTrator.app/Contents/MacOS/
# Copying main resources.
cp $GOPATH/src/github.com/pztrn/urtrator/artwork/urtrator.icns ./URTrator.app/Contents/Resources/
cp -R ./Resources/themes ./URTrator.app/Contents/Resources/
#####################################################################
# APP BUNDLE INFO.PLIST
#####################################################################
INFOPLIST='<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleGetInfoString</key>
<string>URTrator</string>
<key>CFBundleExecutable</key>
<string>urtrator.sh</string>
<key>CFBundleIdentifier</key>
<string>name.pztrn.urtrator</string>
<key>CFBundleName</key>
<string>URTrator</string>
<key>CFBundleIconFile</key>
<string>urtrator.icns</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>IFMajorVersion</key>
<integer>0</integer>
<key>IFMinorVersion</key>
<integer>1</integer>
</dict>
</plist>'
echo -e ${INFOPLIST} > URTrator.app/Contents/Info.plist
echo -e '#!/bin/bash\ncd "${0%/*}"\nexport GTK_PATH="../lib/gtk-2.0/"\nexport GTK_MODULES="../lib/gtk-2.0/"\nexport GDK_PIXBUF_MODULE_FILE="../lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"\nexport GDK_PIXBUF_MODULEDIR="../lib/gdk-pixbuf-2.0/2.10.0/loaders/"\nexport GTK_EXE_PREFIX="../lib"\n./urtrator' > ./URTrator.app/Contents/MacOS/urtrator.sh
chmod +x ./URTrator.app/Contents/MacOS/urtrator.sh
#####################################################################
# Copying helper binaries.
cp /usr/local/Cellar/gdk-pixbuf/2.36.0_2/bin/gdk-pixbuf-query-loaders ./URTrator.app/Contents/MacOS/
# Copy GTK engines as needed for default theme.
cp /usr/local/lib/gtk-2.0/2.10.0/engines/* ./URTrator.app/Contents/Framework/
cp /usr/local/Cellar/gdk-pixbuf/2.36.0_2/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.so ./URTrator.app/Contents/Framework/
chmod -R 0644 ./URTrator.app/Contents/Framework/*
chmod -R 0755 ./URTrator.app/Contents/MacOS/*
# Libraries works.
change_framework_library_load_path "./URTrator.app/Contents/MacOS/urtrator" "@executable_path/../Framework"
change_framework_library_load_path "./URTrator.app/Contents/MacOS/gdk-pixbuf-query-loaders" "@executable_path/../Framework"
#####################################################################
# Directory structure for GTK things. We will symlink neccessary
# libraries from /Framework here.
echo "Creating libraries structure with symlinks"
# GTK engines
mkdir -p ./URTrator.app/Contents/lib/gtk-2.0/2.10.0/engines/
cd ./URTrator.app/Contents/lib/gtk-2.0/2.10.0/engines/
ln -s ../../../../Framework/libclearlooks.so libclearlooks.so
ln -s ../../../../Framework/libmurrine.so libmurrine.so
ln -s ../../../../Framework/libpixmap.so libpixmap.so
# Pixbuf loaders
cd ../../../../
mkdir -p lib/gdk-pixbuf-2.0/2.10.0/loaders/
cd lib/gdk-pixbuf-2.0/2.10.0/loaders/
for file in $(ls ../../../../Framework | grep libpixbufloader); do
ln -s ../../../../Framework/${file} ${file}
done
# Fix pixbuf loaders to load things from "../Framework".
for file in $(ls . | grep libpixbufloader); do
DEPS=$(otool -L ${file} | grep "executable_path")
for dep in ${DEPS[@]}; do
dep_name=$(echo ${dep} | awk -F"/" {' print $NF '})
install_name_tool -change ${dep} ../Framework/${dep_name} ${file}
done
done
cd ..
ln -s ../../../Framework .
cd ../../../MacOS
GDK_PIXBUF_MODULE_FILE="../lib/gdk-pixbuf-2.0/loaders.cache" GDK_PIXBUF_MODULEDIR="../lib/gdk-pixbuf-2.0/2.10.0/loaders/" GTK_EXE_PREFIX="../lib" GTK_PATH="../Framework" ./gdk-pixbuf-query-loaders > ../lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
echo "Finishing..."
echo "URTrator is ready! Copy URTrator.app bundle to Applications and launch it!"

View File

@@ -0,0 +1,3 @@
# Windows installation
*TBW*

View File

@@ -0,0 +1,115 @@
#!/bin/bash
# URTrator Windows build scripts.
# Requirements: installed and properly configured Go and MSYS2
#####################################################################
# VARIABLES
#####################################################################
# Path of script.
SCRIPT_PATH=$(dirname "`readlink -f "${BASH_SOURCE}"`")
# Go binary path.
GO=$(which go | awk {' print $1 '})
#####################################################################
# Checks if Go installed and properly configured.
check_golang() {
if [ ${#GO} -eq 0 ]; then
echo "! Can't find Go binary. Please, install Go and configure your environment."
fi
}
# Check if we are in valid MSYS2 environment.
check_msys() {
echo "* Checking for MSYS..."
if [ -z MSYSTEM ]; then
echo "! Probably, not MSYS2 environment. Building can continue only with MSYS2!"
exit 1
fi
if [ "${MSYSTEM}" == "MSYS" ]; then
echo "! Invalid MSYS2 environment. You're launched MSYS console, but building can continue in MINGW64 console only."
exit 1
fi
}
# Check if we have neccessary MSYS packages installed.
check_msys_packages() {
echo "* Installing neccessary MSYS2 packages..."
pacman -S ${MINGW_PACKAGE_PREFIX}-tools-git ${MINGW_PACKAGE_PREFIX}-gtk2 ${MINGW_PACKAGE_PREFIX}-pkg-config ${MINGW_PACKAGE_PREFIX}-gtk-engines ${MINGW_PACKAGE_PREFIX}-gtk-engine-murrine ${MINGW_PACKAGE_PREFIX}-gcc --noconfirm --needed
}
# Build URTrator
urtrator_build() {
echo "* Starting URTrator building..."
# Create temporary Go root.
if [ -d "${SCRIPT_PATH}/GOROOT" ]; then
rm -rf "${SCRIPT_PATH}/GOROOT"
fi
mkdir -p "${SCRIPT_PATH}/GOROOT"
# Exporting Go variables.
export GOPATH="${SCRIPT_PATH}/GOROOT"
echo "* Obtaining URTrator and dependencies sources..."
go get -u -d -v github.com/pztrn/urtrator
echo "* Building URTrator"
go install -v github.com/pztrn/urtrator
}
# Prepare urtrator distribution.
urtrator_dist() {
echo "* Preparing URTrator distribution..."
echo "* Creating distribution directory..."
if [ -d "${SCRIPT_PATH}/dist" ]; then
rm -rf "${SCRIPT_PATH}/dist"
fi
mkdir "${SCRIPT_PATH}/dist"
echo "* Copying URTrator binary..."
cp "${GOPATH}/bin/urtrator.exe" "${SCRIPT_PATH}/dist/"
echo "* Getting list of library dependencies..."
DEPS=$(ldd dist/urtrator.exe | grep -v "Windows" | awk {' print $1 '})
echo "* Copying dependencies..."
for dep in ${DEPS[@]}; do
cp /mingw64/bin/${dep} "${SCRIPT_PATH}/dist"
done
echo "* Installing GTK+2 theme engines..."
mkdir -p "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libmurrine.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libredmond95.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libthinice.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libmist.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libindustrial.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libhcengine.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libglide.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libcrux-engine.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libclearlooks.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
cp /mingw64/lib/gtk-2.0/2.10.0/engines/libwimp.dll "${SCRIPT_PATH}/dist/lib/gtk-2.0/2.10.0/engines/"
echo "* Checking that we haven't forget any of dependencies..."
LIBS=$(ls "${SCRIPT_PATH}/dist" | grep ".dll")
for lib in ${LIBS[@]}; do
LIBDEPS=$(ldd "${SCRIPT_PATH}/dist/${lib}" | grep -v "Windows" | awk {' print $1 '})
for libdep in ${LIBDEPS[@]}; do
if [ ! -f "${SCRIPT_PATH}/dist/${lib}" ]; then
cp /mingw64/bin/${libdep} "${SCRIPT_PATH}/dist"
fi
done
done
echo "* Installing default theme..."
mkdir -p "${SCRIPT_PATH}/dist/themes"
cp -R /mingw64/share/themes/ "${SCRIPT_PATH}/dist/"
}
echo "Launched in ${SCRIPT_PATH}"
check_msys
check_golang
check_msys_packages
urtrator_build
urtrator_dist
echo "*** URTrator done."

View File

@@ -13,6 +13,10 @@ import (
crand "crypto/rand"
"errors"
"fmt"
//"reflect"
// github
"github.com/mattn/go-gtk/glib"
)
type Eventer struct {
@@ -44,11 +48,19 @@ func (e *Eventer) LaunchEvent(event string, data map[string]string) error {
if !ok {
return errors.New("Event " + event + " not found!")
}
fmt.Println("Launching event " + event)
for _, val := range e.events[event] {
val(data)
}
fmt.Println("Launching event " + event)
glib.IdleAdd(func() bool {
e.reallyLaunchEvent(event, data)
return false
})
return nil
}
func (e *Eventer) reallyLaunchEvent(event string, data map[string]string) {
fmt.Println("Really launching event " + event + "...")
for _, val := range e.events[event] {
val(data)
}
}

View File

@@ -15,6 +15,8 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
@@ -33,6 +35,9 @@ type Launcher struct {
func (l *Launcher) CheckForLaunchedUrbanTerror() error {
if l.launched {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Game is launched.\n\nCannot quit, because game is launched.\nQuit Urban Terror to exit URTrator!"
m := gtk.NewMessageDialog(nil, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
@@ -41,6 +46,7 @@ func (l *Launcher) CheckForLaunchedUrbanTerror() error {
m.Run()
return errors.New("User didn't select valid profile, mismatch with server's version.")
}
}
return nil
}
@@ -88,8 +94,7 @@ func (l *Launcher) Launch(server_profile *datamodels.Server, user_profile *datam
launch_params = append(launch_params, additional_parameters[i])
}
}
if user_profile.Second_x_session == "1" {
fmt.Println(launch_params)
if runtime.GOOS == "linux" && user_profile.Second_x_session == "1" {
launch_params = append([]string{launch_bin}, launch_params...)
display := l.findFreeDisplay()
launch_bin, err = exec.LookPath("xinit")
@@ -98,10 +103,24 @@ func (l *Launcher) Launch(server_profile *datamodels.Server, user_profile *datam
}
launch_params = append(launch_params, "--", ":" + display)
}
fmt.Println(launch_params)
if runtime.GOOS == "darwin" {
// On macOS we should not start binary, but application bundle.
// So we will obtain app bundle path.
bundle_path := strings.Split(launch_bin, "/Contents")[0]
// and create special launch string, which involves open.
launch_bin = "/usr/bin/open"
launch_params = append([]string{launch_bin, "-W", "-a", bundle_path, "--args"}, launch_params...)
}
fmt.Println(launch_bin, launch_params)
go func() {
go func() {
cmd := exec.Command(launch_bin, launch_params...)
// This workaround is required on Windows, otherwise ioq3
// will not find game data.
if runtime.GOOS == "windows" {
dir := filepath.Dir(launch_bin)
cmd.Dir = dir
}
out, err1 := cmd.Output()
if err1 != nil {
fmt.Println("Launch error: " + err1.Error())

View File

@@ -14,7 +14,7 @@ import (
"errors"
"fmt"
"net"
//"runtime"
"runtime"
"strconv"
"strings"
"sync"
@@ -34,7 +34,8 @@ type Pooler struct {
func (p *Pooler) Initialize() {
fmt.Println("Initializing requester goroutine pooler...")
// ToDo: figure out how to make this work nice.
p.maxrequests = 100
p.maxrequests = 200
_ = runtime.GOMAXPROCS(runtime.NumCPU() * 4)
p.pp = "\377\377\377\377"
fmt.Println("Pooler initialized")
}
@@ -237,7 +238,9 @@ func (p *Pooler) UpdateSpecificServer(server *datamodels.Server) error {
if len(players) == 1 && len(players[0]) > 255 {
server.Players = "0"
} else {
server.Players = strconv.Itoa(len(players))
// Looks like we have last element to be empty, due to
// strings.Split() call before.
server.Players = strconv.Itoa(len(players) - 1)
}
server.PlayersInfo = strings.Join(received_lines[2:], "\\")
}

View File

@@ -12,6 +12,7 @@ package requester
import (
// stdlib
"bytes"
"errors"
"fmt"
"net"
"strconv"
@@ -46,11 +47,13 @@ func (r *Requester) Initialize() {
// Gets all available servers from master server.
// This isn't in pooler, because it have no need to be pooled.
func (r *Requester) getServers() {
func (r *Requester) getServers() error {
// IP addresses we will compose to return.
conn, err1 := net.Dial("udp", r.master_server + ":" + r.master_server_port)
if err1 != nil {
fmt.Println("Error dialing to master server!")
Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "Failed to connect to master server!"})
return errors.New("Failed to connect to master server!")
}
defer conn.Close()
@@ -118,6 +121,8 @@ func (r *Requester) getServers() {
Cache.Servers[addr].Server.Port = port
}
}
return nil
}
// Updates information about all available servers from master server and

View File

@@ -14,6 +14,7 @@ import (
"encoding/base64"
"errors"
"fmt"
"runtime"
"strings"
// Local
@@ -152,7 +153,7 @@ func (f *FavoriteDialog) initializeWindow() {
srv_addr_hbox.PackStart(f.server_address, true, true, 5)
srv_addr_update_btn := gtk.NewButton()
srv_addr_update_btn.SetTooltipText("Update server information")
srv_addr_update_btn_image := gtk.NewImageFromStock(gtk.STOCK_REDO, 24)
srv_addr_update_btn_image := gtk.NewImageFromStock(gtk.STOCK_REDO, gtk.ICON_SIZE_SMALL_TOOLBAR)
srv_addr_update_btn.SetImage(srv_addr_update_btn_image)
srv_addr_update_btn.Clicked(f.updateServerInfo)
srv_addr_hbox.PackStart(srv_addr_update_btn, false, true, 5)
@@ -205,12 +206,16 @@ func (f *FavoriteDialog) saveFavorite() error {
//ctx.Requester.Pooler.UpdateSpecificServer(f.server)
if len(f.server_address.GetText()) == 0 {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Server address is empty.\n\nServers without address cannot be added."
m := gtk.NewMessageDialog(f.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
})
m.Run()
}
return errors.New("No server address specified")
}
@@ -224,12 +229,16 @@ func (f *FavoriteDialog) saveFavorite() error {
f.server.Port = port
if len(f.profile.GetActiveText()) == 0 {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Profile wasn't selected.\n\nPlease, select valid profile for this server.\nIf you haven't add profiles yet - you can do it\nin options on \"Urban Terror\" tab."
m := gtk.NewMessageDialog(f.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
})
m.Run()
}
return errors.New("No game profile specified")
}
@@ -245,6 +254,7 @@ func (f *FavoriteDialog) saveFavorite() error {
ctx.Cache.Servers[key].Server.ExtendedConfig = f.server.ExtendedConfig
ctx.Cache.Servers[key].Server.PlayersInfo = f.server.PlayersInfo
ctx.Eventer.LaunchEvent("flushServers", map[string]string{})
ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
f.window.Destroy()

View File

@@ -12,6 +12,8 @@ package ui
import (
// stdlib
"fmt"
"runtime"
"sort"
"strconv"
"strings"
@@ -29,6 +31,8 @@ type MainWindow struct {
// Gamemodes.
gamemodes map[string]string
text string
// Widgets.
// The window itself.
window *gtk.Window
@@ -56,8 +60,12 @@ type MainWindow struct {
profiles *gtk.ComboBoxText
// Checkbox for hiding/showing offline servers in 'Servers' tab list.
all_servers_hide_offline *gtk.CheckButton
// Checkbox for hiding/showing passworded servers in 'Servers' tab list.
all_servers_hide_private *gtk.CheckButton
// Checkbox for hiding/showing offline servers in 'Favorites' tab list.
fav_servers_hide_offline *gtk.CheckButton
// Checkbox for hiding/showing passworded servers in 'Favorites' tab list.
fav_servers_hide_private *gtk.CheckButton
// Game launch button.
launch_button *gtk.Button
// Server's information.
@@ -87,8 +95,6 @@ type MainWindow struct {
// Dialogs.
options_dialog *OptionsDialog
// Favorite server editing.
favorite_dialog *FavoriteDialog
// Other
// Old profiles count.
@@ -120,14 +126,20 @@ type MainWindow struct {
// For online server.
server_online_pic *gdkpixbuf.Pixbuf
// For private (passworded) server.
server_passworded_pic *gdkpixbuf.Pixbuf
server_private_pic *gdkpixbuf.Pixbuf
// For public server
server_public_pic *gdkpixbuf.Pixbuf
// Flags.
// Application is initialized?
initialized bool
// Window is hidden?
hidden bool
// Use other's tab information?
// Used when user changed active tab, to show information about
// server which is selected on activated tab.
use_other_servers_tab bool
}
func (m *MainWindow) addToFavorites() {
@@ -135,10 +147,13 @@ func (m *MainWindow) addToFavorites() {
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
server_address := m.getIpFromServersList(current_tab)
server_address := ""
if !strings.Contains(current_tab, "Favorites") {
server_address = m.getIpFromServersList(current_tab)
}
// Getting server from database.
m.favorite_dialog = &FavoriteDialog{}
fd := &FavoriteDialog{}
if len(server_address) > 0 {
servers := []datamodels.Server{}
address := strings.Split(server_address, ":")[0]
@@ -147,26 +162,32 @@ func (m *MainWindow) addToFavorites() {
if err1 != nil {
fmt.Println(err1.Error())
}
m.favorite_dialog.InitializeUpdate(&servers[0])
fd.InitializeUpdate(&servers[0])
} else {
m.favorite_dialog.InitializeNew()
fd.InitializeNew()
}
}
// Executes when delimiter for two panes is moved, to calculate VALID
// position.
func (m *MainWindow) checkMainPanePosition() {
glib.IdleAdd(func() bool {
m.pane_negative_position = m.window_width - m.hpane.GetPosition()
return false
})
}
// Executes when main window is moved or resized.
// Also calculating pane delimiter position and set it to avoid
// widgets hell :).
func (m *MainWindow) checkPositionAndSize() {
glib.IdleAdd(func() bool {
m.window.GetPosition(&m.window_pos_x, &m.window_pos_y)
m.window.GetSize(&m.window_width, &m.window_height)
m.hpane.SetPosition(m.window_width - m.pane_negative_position)
return false
})
}
// Executes on URTrator shutdown.
@@ -190,9 +211,21 @@ func (m *MainWindow) Close() {
ctx.Cfg.Cfg["/mainwindow/fav_servers/" + fav_servers_columns[i].GetTitle() + "_width"] = strconv.Itoa(fav_servers_columns[i].GetWidth())
}
// Additional actions should be taken on Windows.
if runtime.GOOS == "windows" {
m.closeWin()
}
ctx.Close()
}
func (m *MainWindow) copyServerCredentialsToClipboard() {
fmt.Println("Copying server's credentials to clipboard...")
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
server_address := m.getIpFromServersList(current_tab)
ctx.Clipboard.CopyServerData(server_address)
}
// Deleting server from favorites.
func (m *MainWindow) deleteFromFavorites() {
fmt.Println("Removing server from favorites...")
@@ -212,12 +245,18 @@ func (m *MainWindow) deleteFromFavorites() {
}
if not_favorited {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Cannot delete server from favorites.\n\nServer isn't favorited."
d := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, mbox_string)
d.Response(func() {
d.Destroy()
})
d.Run()
} else {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Server isn't favorited</span></markup>"})
}
}
ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
@@ -228,6 +267,9 @@ func (m *MainWindow) deleteFromFavorites() {
func (m *MainWindow) dropDatabasesData() {
fmt.Println("Dropping database data...")
var will_continue bool = false
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "You are about to drop whole database data.\n\nAfter clicking \"YES\" ALL data in database (servers, profiles, settings, etc.)\nwill be lost FOREVER. Are you sure?"
d := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, mbox_string)
d.Connect("response", func(resp *glib.CallbackContext) {
@@ -236,11 +278,12 @@ func (m *MainWindow) dropDatabasesData() {
} else {
will_continue = true
}
})
d.Response(func() {
d.Destroy()
})
d.Run()
} else {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Remove ~/.config/urtrator/database.sqlite3 manually!</span></markup>"})
}
if will_continue {
ctx.Database.Db.MustExec("DELETE FROM servers")
@@ -261,7 +304,8 @@ func (m *MainWindow) editFavorite() {
if len(server_address) > 0 {
srv := ctx.Cache.Servers[server_address].Server
m.favorite_dialog.InitializeUpdate(srv)
fd := FavoriteDialog{}
fd.InitializeUpdate(srv)
}
}
@@ -277,6 +321,18 @@ func (m *MainWindow) hideOfflineAllServers() {
ctx.Eventer.LaunchEvent("loadAllServers", map[string]string{})
}
// Executes when "Hide passworded servers" checkbox changed it's state on
// "Servers" tab.
func (m *MainWindow) hidePrivateAllServers() {
fmt.Println("(Un)Hiding private servers in 'Servers' tab...")
if m.all_servers_hide_private.GetActive() {
ctx.Cfg.Cfg["/serverslist/all_servers/hide_private"] = "1"
} else {
ctx.Cfg.Cfg["/serverslist/all_servers/hide_private"] = "0"
}
ctx.Eventer.LaunchEvent("loadAllServers", map[string]string{})
}
// Executes when "Hide offline servers" checkbox changed it's state on
// "Favorites" tab.
func (m *MainWindow) hideOfflineFavoriteServers() {
@@ -289,9 +345,20 @@ func (m *MainWindow) hideOfflineFavoriteServers() {
ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
}
// Executes when "Hide passworded servers" checkbox changed it's state on
// "Favorites" tab.
func (m *MainWindow) hidePrivateFavoriteServers() {
fmt.Println("(Un)Hiding private servers in 'Favorite' tab...")
if m.all_servers_hide_private.GetActive() {
ctx.Cfg.Cfg["/serverslist/favorite/hide_private"] = "1"
} else {
ctx.Cfg.Cfg["/serverslist/favorite/hide_private"] = "0"
}
ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
}
func (m *MainWindow) loadAllServers(data map[string]string) {
fmt.Println("Loading all servers...")
// ToDo: do it without clearing.
for _, server := range ctx.Cache.Servers {
iter := new(gtk.TreeIter)
ping, _ := strconv.Atoi(server.Server.Ping)
@@ -304,7 +371,15 @@ func (m *MainWindow) loadAllServers(data map[string]string) {
}
if m.all_servers_hide_offline.GetActive() && (server.Server.Players == "" && server.Server.Maxplayers == "" || ping > 9000) {
if server.AllServersIterInList {
if server.AllServersIterInList && server.AllServersIterSet {
m.all_servers_store.Remove(iter)
server.AllServersIterInList = false
}
continue
}
if m.all_servers_hide_private.GetActive() && server.Server.IsPrivate == "1" {
if server.AllServersIterInList && server.AllServersIterSet {
m.all_servers_store.Remove(iter)
server.AllServersIterInList = false
}
@@ -326,7 +401,7 @@ func (m *MainWindow) loadAllServers(data map[string]string) {
m.all_servers_store.SetValue(iter, 0, m.server_online_pic.GPixbuf)
}
if server.Server.IsPrivate == "1" {
m.all_servers_store.SetValue(iter, 1, m.server_passworded_pic.GPixbuf)
m.all_servers_store.SetValue(iter, 1, m.server_private_pic.GPixbuf)
} else {
m.all_servers_store.SetValue(iter, 1, m.server_public_pic.GPixbuf)
}
@@ -363,6 +438,14 @@ func (m *MainWindow) loadFavoriteServers(data map[string]string) {
continue
}
if m.fav_servers_hide_private.GetActive() && server.Server.IsPrivate == "1" {
if server.FavServersIterInList && server.FavServersIterSet {
m.fav_servers_store.Remove(iter)
server.FavServersIterInList = false
}
continue
}
// If server on favorites widget, but not favorited (e.g. just
// removed from favorites) - remove it from list.
if server.Server.Favorite != "1" && server.FavServersIterSet && server.FavServersIterInList {
@@ -391,7 +474,7 @@ func (m *MainWindow) loadFavoriteServers(data map[string]string) {
m.fav_servers_store.SetValue(iter, 0, m.server_online_pic.GPixbuf)
}
if server.Server.IsPrivate == "1" {
m.fav_servers_store.SetValue(iter, 1, m.server_passworded_pic.GPixbuf)
m.fav_servers_store.SetValue(iter, 1, m.server_private_pic.GPixbuf)
} else {
m.fav_servers_store.SetValue(iter, 1, m.server_public_pic.GPixbuf)
}
@@ -421,10 +504,46 @@ func (m *MainWindow) loadProfiles(data map[string]string) {
m.old_profiles_count = len(ctx.Cache.Profiles)
fmt.Println("Added " + strconv.Itoa(m.old_profiles_count) + " profiles")
m.profiles.SetActive(0)
}
func (m *MainWindow) tabChanged() {
if !m.initialized {
return
}
fmt.Println("Active tab changed...")
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
fmt.Println(current_tab)
m.use_other_servers_tab = true
if strings.Contains(current_tab, "Servers") {
m.fav_servers.Emit("cursor-changed")
} else if strings.Contains(current_tab, "Favorites") {
m.all_servers.Emit("cursor-changed")
}
m.use_other_servers_tab = false
}
func (m *MainWindow) serversUpdateCompleted(data map[string]string) {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "Servers updated."})
// Trigger "selection-changed" events on currently active tab's
// servers list.
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
if strings.Contains(current_tab, "Servers") {
m.all_servers.Emit("cursor-changed")
} else if strings.Contains(current_tab, "Favorites") {
m.fav_servers.Emit("cursor-changed")
}
}
func (m *MainWindow) setQuickConnectDetails(data map[string]string) {
fmt.Println("Setting quick connect data...")
m.qc_server_address.SetText(data["server"])
m.qc_password.SetText(data["password"])
}
func (m *MainWindow) setToolbarLabelText(data map[string]string) {
@@ -449,14 +568,17 @@ func (m *MainWindow) showHide() {
}
}
func (m *MainWindow) showServerInformation() {
fmt.Println("Showing server's information...")
}
func (m *MainWindow) showShortServerInformation() {
fmt.Println("Server selection changed, updating server's information widget...")
m.server_info_store.Clear()
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
if m.use_other_servers_tab {
if strings.Contains(current_tab, "Servers") {
current_tab = "Favorites"
} else if strings.Contains(current_tab, "Favorites") {
current_tab = "Servers"
}
}
srv_address := m.getIpFromServersList(current_tab)
// Getting server information from cache.
@@ -529,12 +651,22 @@ func (m *MainWindow) showShortServerInformation() {
m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, "<markup><span font_weight=\"bold\">PLAYERS</span></markup>")
for _, value := range parsed_players_info {
// Sorting keys of map.
players_map_keys := make([]string, 0, len(parsed_players_info))
for k := range parsed_players_info {
// ToDo: figure out how to do this properly without
// append().
players_map_keys = append(players_map_keys, k)
}
sort.Strings(players_map_keys)
for k := range players_map_keys {
iter = new(gtk.TreeIter)
nick := ctx.Colorizer.Fix(value["nick"])
nick := ctx.Colorizer.Fix(parsed_players_info[players_map_keys[k]]["nick"])
m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, nick)
m.server_info_store.SetValue(iter, 1, "(frags: " + value["frags"] + " | ping: " + value["ping"] + ")")
m.server_info_store.SetValue(iter, 1, "(frags: " + parsed_players_info[players_map_keys[k]]["frags"] + " | ping: " + parsed_players_info[players_map_keys[k]]["ping"] + ")")
}
// Just a separator.
@@ -546,11 +678,19 @@ func (m *MainWindow) showShortServerInformation() {
m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, "<markup><span font_weight=\"bold\">OTHER PARAMETERS</span></markup>")
for key, value := range parsed_general_data {
// Sort it!
general_data_keys := make([]string, 0, len(parsed_general_data))
for k := range parsed_general_data {
general_data_keys = append(general_data_keys, k)
}
sort.Strings(general_data_keys)
for k := range general_data_keys {
iter = new(gtk.TreeIter)
m.server_info_store.Append(iter)
m.server_info_store.SetValue(iter, 0, key)
m.server_info_store.SetValue(iter, 1, value)
m.server_info_store.SetValue(iter, 0, general_data_keys[k])
m.server_info_store.SetValue(iter, 1, parsed_general_data[general_data_keys[k]])
}
}
}
@@ -567,6 +707,7 @@ func (m *MainWindow) unlockInterface() {
}
func (m *MainWindow) updateOneServer() {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Updating selected server...</span></markup>"})
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
srv_address := m.getIpFromServersList(current_tab)

View File

@@ -18,9 +18,11 @@ import (
// Main window initialization.
func (m *MainWindow) Initialize() {
gtk.Init(nil)
m.initializeStorages()
ctx.InitializeClipboardWatcher()
m.window = gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
m.window.SetTitle("URTrator")
@@ -36,6 +38,14 @@ func (m *MainWindow) Initialize() {
m.window.Connect("configure-event", m.checkPositionAndSize)
// Additional OS-specific initialization.
if runtime.GOOS == "windows" {
m.initializeWin()
}
if runtime.GOOS == "darwin" {
m.initializeMac()
}
// Restoring window position.
var win_pos_x_str string = "0"
var win_pos_y_str string = "0"
@@ -76,7 +86,11 @@ func (m *MainWindow) Initialize() {
m.options_dialog = &OptionsDialog{}
// Main menu.
if runtime.GOOS == "darwin" {
m.initializeMacMenu()
} else {
m.InitializeMainMenu()
}
// Toolbar.
m.InitializeToolbar()
@@ -116,7 +130,7 @@ func (m *MainWindow) Initialize() {
m.vbox.PackStart(profile_and_launch_hbox, false, true, 5)
// Separator
sep := gtk.NewHSeparator()
sep := gtk.NewHBox(false, 0)
profile_and_launch_hbox.PackStart(sep, true, true, 5)
// Profile selection.
@@ -135,11 +149,12 @@ func (m *MainWindow) Initialize() {
m.launch_button = gtk.NewButtonWithLabel("Launch!")
m.launch_button.SetTooltipText("Launch Urban Terror")
m.launch_button.Clicked(m.launchGame)
launch_button_image := gtk.NewImageFromStock(gtk.STOCK_APPLY, 24)
launch_button_image := gtk.NewImageFromPixbuf(logo.ScaleSimple(24, 24, gdkpixbuf.INTERP_HYPER))
m.launch_button.SetImage(launch_button_image)
profile_and_launch_hbox.PackStart(m.launch_button, false, true, 5)
m.window.Add(m.vbox)
m.window.ShowAll()
// Launch events.
@@ -150,6 +165,9 @@ func (m *MainWindow) Initialize() {
ctx.Eventer.LaunchEvent("loadFavoriteServers", map[string]string{})
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "URTrator is ready."})
// Set flag that shows to other parts that we're initialized.
m.initialized = true
gtk.Main()
}
@@ -160,6 +178,7 @@ func (m *MainWindow) initializeEvents() {
ctx.Eventer.AddEventHandler("loadFavoriteServers", m.loadFavoriteServers)
ctx.Eventer.AddEventHandler("loadProfilesIntoMainWindow", m.loadProfiles)
ctx.Eventer.AddEventHandler("serversUpdateCompleted", m.serversUpdateCompleted)
ctx.Eventer.AddEventHandler("setQuickConnectDetails", m.setQuickConnectDetails)
ctx.Eventer.AddEventHandler("setToolbarLabelText", m.setToolbarLabelText)
}
@@ -234,11 +253,6 @@ func (m *MainWindow) initializeSidebar() {
si_scroll.Add(m.server_info)
// Button to view additional server info.
additional_srv_info_button := gtk.NewButtonWithLabel("Additional information")
additional_srv_info_button.Clicked(m.showServerInformation)
si_vbox.PackStart(additional_srv_info_button, false, true, 5)
// Quick connect frame.
quick_connect_frame := gtk.NewFrame("Quick connect")
sidebar_vbox.PackStart(quick_connect_frame, false, true, 5)
@@ -280,6 +294,9 @@ func (m *MainWindow) initializeSidebar() {
// Initializes internal storages.
func (m *MainWindow) initializeStorages() {
// Application isn't initialized.
m.initialized = false
m.use_other_servers_tab = false
// Gamemodes.
m.gamemodes = make(map[string]string)
m.gamemodes = map[string]string{
@@ -338,19 +355,37 @@ func (m *MainWindow) initializeStorages() {
// Pixbufs.
// Offline server.
m.server_offline_pic = gtk.NewImage().RenderIcon(gtk.STOCK_NO, gtk.ICON_SIZE_SMALL_TOOLBAR, "")
srv_offline_bytes, _ := base64.StdEncoding.DecodeString(common.SERVER_OFFLINE)
srv_offline_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
srv_offline_pixbuf.SetSize(24, 24)
srv_offline_pixbuf.Write(srv_offline_bytes)
m.server_offline_pic = srv_offline_pixbuf.GetPixbuf()
// Online server.
m.server_online_pic = gtk.NewImage().RenderIcon(gtk.STOCK_OK, gtk.ICON_SIZE_SMALL_TOOLBAR, "")
// Passworded server.
m.server_passworded_pic = gtk.NewImage().RenderIcon(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR, "")
srv_online_bytes, _ := base64.StdEncoding.DecodeString(common.SERVER_ONLINE)
srv_online_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
srv_online_pixbuf.SetSize(24, 24)
srv_online_pixbuf.Write(srv_online_bytes)
m.server_online_pic = srv_online_pixbuf.GetPixbuf()
// Private server.
srv_private_bytes, _ := base64.StdEncoding.DecodeString(common.SERVER_PRIVATE)
srv_private_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
srv_private_pixbuf.SetSize(24, 24)
srv_private_pixbuf.Write(srv_private_bytes)
m.server_private_pic = srv_private_pixbuf.GetPixbuf()
// Public server.
m.server_public_pic = gtk.NewImage().RenderIcon(gtk.STOCK_OK, gtk.ICON_SIZE_SMALL_TOOLBAR, "")
srv_public_bytes, _ := base64.StdEncoding.DecodeString(common.SERVER_PUBLIC)
srv_public_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
srv_public_pixbuf.SetSize(24, 24)
srv_public_pixbuf.Write(srv_public_bytes)
m.server_public_pic = srv_public_pixbuf.GetPixbuf()
fmt.Println(srv_public_pixbuf.GetFormat().GetName())
}
// Tabs widget initialization, including all child widgets.
func (m *MainWindow) InitializeTabs() {
// Create tabs widget.
m.tab_widget = gtk.NewNotebook()
m.tab_widget.Connect("switch-page", m.tabChanged)
tab_allsrv_hbox := gtk.NewHBox(false, 0)
swin1 := gtk.NewScrolledWindow(nil, nil)
@@ -406,9 +441,15 @@ func (m *MainWindow) InitializeTabs() {
// Sorting.
// By default we are sorting by server name.
// ToDo: remembering it to configuration storage.
m.all_servers_store_sortable.SetSortColumnId(m.column_pos["Servers"]["Name"], gtk.SORT_ASCENDING)
// Sorting functions.
// Race conditions and GC crazyness appears when activated, so for
// now commenting it out.
m.all_servers_store_sortable.SetSortFunc(m.column_pos["Servers"]["Name"], m.sortServersByName)
m.all_servers_store_sortable.SetSortFunc(m.column_pos["Servers"]["Players"], m.sortServersByPlayers)
m.all_servers_store_sortable.SetSortFunc(m.column_pos["Servers"]["Ping"], m.sortServersByPing)
// Selection changed signal, which will update server's short info pane.
m.all_servers.Connect("cursor-changed", m.showShortServerInformation)
@@ -421,8 +462,30 @@ func (m *MainWindow) InitializeTabs() {
m.all_servers_hide_offline.SetTooltipText("Hide offline servers on Servers tab")
tab_all_srv_ctl_vbox.PackStart(m.all_servers_hide_offline, false, true, 5)
m.all_servers_hide_offline.Clicked(m.hideOfflineAllServers)
if ctx.Cfg.Cfg["/serverslist/all_servers/hide_offline"] == "1" {
// Restore value of hide offline servers checkbox.
// Set to checked for new installations.
all_servers_hide_offline_cb_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/hide_offline"]
if !ok {
m.all_servers_hide_offline.SetActive(true)
} else {
if all_servers_hide_offline_cb_val == "1" {
m.all_servers_hide_offline.SetActive(true)
}
}
// Checkbox for hiding passworded servers.
m.all_servers_hide_private = gtk.NewCheckButtonWithLabel("Hide private servers")
m.all_servers_hide_private.SetTooltipText("Hide servers which requires password to enter")
tab_all_srv_ctl_vbox.PackStart(m.all_servers_hide_private, false, true, 5)
m.all_servers_hide_private.Clicked(m.hidePrivateAllServers)
// Restore checkbox value.
all_servers_hide_private_cb_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/hide_private"]
if !ok {
m.all_servers_hide_private.SetActive(true)
} else {
if all_servers_hide_private_cb_val == "1" {
m.all_servers_hide_private.SetActive(true)
}
}
// Final separator.
@@ -460,7 +523,11 @@ func (m *MainWindow) InitializeTabs() {
width_int, _ := strconv.Atoi(width)
col := gtk.NewTreeViewColumnWithAttributes(name, gtk.NewCellRendererText(), "markup", position_int)
// For some reason this cause panic on Windows, so disabling
// default sorting here.
if runtime.GOOS != "windows" {
col.SetSortColumnId(position_int)
}
col.SetReorderable(true)
col.SetResizable(true)
// GtkTreeViewColumn.SetFixedWidth() accepts only positive integers.
@@ -491,8 +558,30 @@ func (m *MainWindow) InitializeTabs() {
m.fav_servers_hide_offline.SetTooltipText("Hide offline servers on Favorites tab")
tab_fav_srv_ctl_vbox.PackStart(m.fav_servers_hide_offline, false, true, 5)
m.fav_servers_hide_offline.Clicked(m.hideOfflineFavoriteServers)
if ctx.Cfg.Cfg["/serverslist/favorite/hide_offline"] == "1" {
// Restore value of hide offline servers checkbox.
// Set to checked for new installations.
favorite_servers_hide_offline_cb_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/hide_offline"]
if !ok {
m.fav_servers_hide_offline.SetActive(true)
} else {
if favorite_servers_hide_offline_cb_val == "1" {
m.fav_servers_hide_offline.SetActive(true)
}
}
// Checkbox for hiding passworded servers.
m.fav_servers_hide_private = gtk.NewCheckButtonWithLabel("Hide private servers")
m.fav_servers_hide_private.SetTooltipText("Hide servers which requires password to enter")
tab_fav_srv_ctl_vbox.PackStart(m.fav_servers_hide_private, false, true, 5)
m.fav_servers_hide_private.Clicked(m.hidePrivateFavoriteServers)
// Restore checkbox value.
fav_servers_hide_private_cb_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/hide_private"]
if !ok {
m.fav_servers_hide_private.SetActive(true)
} else {
if fav_servers_hide_private_cb_val == "1" {
m.fav_servers_hide_private.SetActive(true)
}
}
// Final separator.
@@ -509,14 +598,22 @@ func (m *MainWindow) InitializeToolbar() {
m.vbox.PackStart(m.toolbar, false, false, 5)
// Update servers button.
button_update_all_servers := gtk.NewToolButtonFromStock(gtk.STOCK_REFRESH)
button_update_all_servers.SetLabel("Update all servers")
button_update_all_servers.SetTooltipText("Update all servers in all tabs")
button_update_all_servers_icon_bytes, _ := base64.StdEncoding.DecodeString(common.REFRESH_ALL_SERVERS)
button_update_all_servers_icon_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
button_update_all_servers_icon_pixbuf.SetSize(24, 24)
button_update_all_servers_icon_pixbuf.Write(button_update_all_servers_icon_bytes)
button_update_all_servers_icon := gtk.NewImageFromPixbuf(button_update_all_servers_icon_pixbuf.GetPixbuf())
button_update_all_servers := gtk.NewToolButton(button_update_all_servers_icon, "Update all servers")
button_update_all_servers.SetTooltipText("Update all servers in currently selected tab")
button_update_all_servers.OnClicked(m.UpdateServers)
m.toolbar.Insert(button_update_all_servers, 0)
button_update_one_server := gtk.NewToolButtonFromStock(gtk.STOCK_REDO)
button_update_one_server.SetLabel("Update selected server")
button_update_one_server_icon_bytes, _ := base64.StdEncoding.DecodeString(common.REFRESH_ONE_SERVER)
button_update_one_server_icon_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
button_update_one_server_icon_pixbuf.SetSize(24, 24)
button_update_one_server_icon_pixbuf.Write(button_update_one_server_icon_bytes)
button_update_one_server_icon := gtk.NewImageFromPixbuf(button_update_one_server_icon_pixbuf.GetPixbuf())
button_update_one_server := gtk.NewToolButton(button_update_one_server_icon, "Update selected server")
button_update_one_server.SetTooltipText("Update only selected server")
button_update_one_server.OnClicked(m.updateOneServer)
m.toolbar.Insert(button_update_one_server, 1)
@@ -526,34 +623,57 @@ func (m *MainWindow) InitializeToolbar() {
m.toolbar.Insert(separator, 2)
// Add server to favorites button.
fav_button := gtk.NewToolButtonFromStock(gtk.STOCK_ADD)
fav_button.SetLabel("Add to favorites")
fav_button_icon_bytes, _ := base64.StdEncoding.DecodeString(common.ADD_TO_FAVORITES)
fav_button_icon_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
fav_button_icon_pixbuf.SetSize(24, 24)
fav_button_icon_pixbuf.Write(fav_button_icon_bytes)
fav_button_icon := gtk.NewImageFromPixbuf(fav_button_icon_pixbuf.GetPixbuf())
fav_button := gtk.NewToolButton(fav_button_icon, "Add to favorites")
fav_button.SetTooltipText("Add selected server to favorites")
fav_button.OnClicked(m.addToFavorites)
m.toolbar.Insert(fav_button, 3)
fav_edit_button := gtk.NewToolButtonFromStock(gtk.STOCK_EDIT)
fav_edit_button.SetLabel("Edit favorite")
fav_edit_button_icon_bytes, _ := base64.StdEncoding.DecodeString(common.EDIT_FAVORITE)
fav_edit_button_icon_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
fav_edit_button_icon_pixbuf.SetSize(24, 24)
fav_edit_button_icon_pixbuf.Write(fav_edit_button_icon_bytes)
fav_edit_button_icon := gtk.NewImageFromPixbuf(fav_edit_button_icon_pixbuf.GetPixbuf())
fav_edit_button := gtk.NewToolButton(fav_edit_button_icon, "Edit favorite")
fav_edit_button.SetTooltipText("Edit selected favorite server")
fav_edit_button.OnClicked(m.editFavorite)
m.toolbar.Insert(fav_edit_button, 4)
// Remove server from favorites button.
fav_delete_button := gtk.NewToolButtonFromStock(gtk.STOCK_REMOVE)
fav_delete_button.SetLabel("Remove from favorites")
fav_delete_button_icon_bytes, _ := base64.StdEncoding.DecodeString(common.REMOVE_FAVORITE)
fav_delete_button_icon_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
fav_delete_button_icon_pixbuf.SetSize(24, 24)
fav_delete_button_icon_pixbuf.Write(fav_delete_button_icon_bytes)
fav_delete_button_icon := gtk.NewImageFromPixbuf(fav_delete_button_icon_pixbuf.GetPixbuf())
fav_delete_button := gtk.NewToolButton(fav_delete_button_icon, "Remove from favorites")
fav_delete_button.SetTooltipText("Remove selected server from favorites")
fav_delete_button.OnClicked(m.deleteFromFavorites)
m.toolbar.Insert(fav_delete_button, 5)
// Copy server address button.
copy_srv_addr_button_icon_bytes, _ := base64.StdEncoding.DecodeString(common.COPY_CREDENTIALS)
copy_srv_addr_button_icon_pixbuf, _ := gdkpixbuf.NewLoaderWithType("png")
copy_srv_addr_button_icon_pixbuf.SetSize(24, 24)
copy_srv_addr_button_icon_pixbuf.Write(copy_srv_addr_button_icon_bytes)
copy_srv_addr_button_icon := gtk.NewImageFromPixbuf(copy_srv_addr_button_icon_pixbuf.GetPixbuf())
copy_srv_addr_button := gtk.NewToolButton(copy_srv_addr_button_icon, "Copy server's creds")
copy_srv_addr_button.SetTooltipText("Copy server's credentials to clipboard for sharing")
copy_srv_addr_button.OnClicked(m.copyServerCredentialsToClipboard)
m.toolbar.Insert(copy_srv_addr_button, 6)
// Separator for toolbar's label and buttons.
toolbar_separator_toolitem := gtk.NewToolItem()
toolbar_separator_toolitem.SetExpand(true)
m.toolbar.Insert(toolbar_separator_toolitem, 6)
m.toolbar.Insert(toolbar_separator_toolitem, 7)
// Toolbar's label.
m.toolbar_label = gtk.NewLabel("URTrator is ready")
toolbar_label_toolitem := gtk.NewToolItem()
toolbar_label_toolitem.Add(m.toolbar_label)
m.toolbar.Insert(toolbar_label_toolitem, 7)
m.toolbar.Insert(toolbar_label_toolitem, 8)
}
// Tray icon initialization.

28
ui/mainwindow_init_mac.go Normal file
View File

@@ -0,0 +1,28 @@
package ui
import (
// stdlib
"os"
"path/filepath"
"runtime"
// other
"github.com/mattn/go-gtk/gtk"
)
func (m *MainWindow) initializeMac() {
if runtime.GOOS == "darwin" {
dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
gtk.RCParse(dir + "/../Resources/themes/gtkrc-keybindings")
// ToDo: theming support and theme seletion in settings.
gtk.RCParse(dir + "/../Resources/themes/ClearlooksBrave/gtk-2.0/gtkrc")
}
}
func (m *MainWindow) initializeMacMenu() {
// This is a placeholder, in future we will use native mac menu.
// For now it launches default menu initialization.
m.InitializeMainMenu()
}

24
ui/mainwindow_init_win.go Normal file
View File

@@ -0,0 +1,24 @@
package ui
import (
// stdlib
"os"
"path/filepath"
// other
"github.com/mattn/go-gtk/gtk"
"github.com/couchbase/goutils/platform"
)
func (m *MainWindow) closeWin() {
platform.HideConsole(false)
}
func (m *MainWindow) initializeWin() {
platform.HideConsole(true)
dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
// ToDo: theming support and theme seletion in settings.
gtk.RCParse(dir + "/themes/MS-Windows/gtk-2.0/gtkrc")
}

View File

@@ -4,6 +4,7 @@ import (
// stdlib
"errors"
"fmt"
"runtime"
"strings"
// Local
@@ -51,25 +52,46 @@ func (m *MainWindow) launchAsUsual() error {
model.GetValue(iter, m.column_pos["Favorites"]["IP"], srv_address_gval)
}
srv_address = srv_address_gval.GetString()
if len(srv_address) == 0 {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "No server selected.\n\nPlease, select a server to continue connecting."
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
messagebox.Response(func() {
messagebox.Destroy()
})
messagebox.Run()
} else {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Select a server we will connect to!</span></markup>"})
}
return errors.New("No server selected.")
}
server_profile := ctx.Cache.Servers[srv_address].Server
// Check for proper server name. If length == 0: server is offline,
// we should show notification to user.
if len(server_profile.Name) == 0 {
var will_continue bool = false
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server."
m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
m.Connect("response", func(resp *glib.CallbackContext) {
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
messagebox.Connect("response", func(resp *glib.CallbackContext) {
if resp.Args(0) == 4294967287 {
will_continue = false
} else {
will_continue = true
}
messagebox.Destroy()
})
m.Response(func() {
m.Destroy()
})
m.Run()
messagebox.Run()
} else {
// We're okay to connect to empty server, temporary.
will_continue = true
}
if !will_continue {
return errors.New("User declined to connect to offline server")
}
@@ -83,19 +105,41 @@ func (m *MainWindow) launchAsUsual() error {
// This check only relevant to "Servers" tab, favorite servers
// have profiles defined (see next).
if len(profile_name) == 0 {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Invalid game profile selected.\n\nPlease, select profile and retry."
m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
messagebox.Response(func() {
messagebox.Destroy()
})
m.Run()
messagebox.Run()
} else {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Invalid game profile selected.</span></markup>"})
}
return errors.New("User didn't select valid profile.")
}
user_profile = ctx.Cache.Profiles[profile_name].Profile
} else if strings.Contains(current_tab, "Favorites") {
// For favorite servers profile specified in favorite server
// information have higher priority, so we just override it :)
user_profile = ctx.Cache.Profiles[server_profile.ProfileToUse].Profile
user_profile_cached, ok := ctx.Cache.Profiles[server_profile.ProfileToUse]
if !ok {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Invalid game profile specified for favorite server.\n\nPlease, edit your favorite server, select valid profile and retry."
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
messagebox.Response(func() {
messagebox.Destroy()
})
messagebox.Run()
} else {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Invalid game profile specified in favorite entry.</span></markup>"})
}
return errors.New("User didn't select valid profile.")
}
user_profile = user_profile_cached.Profile
}
m.launchActually(server_profile, user_profile, "", "")
@@ -144,19 +188,25 @@ func (m *MainWindow) launchWithQuickConnect() error {
func (m *MainWindow) launchActually(server_profile *datamodels.Server, user_profile *datamodels.Profile, password string, nickname_to_use string) error {
if server_profile.Name == "" {
var will_continue bool = false
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Selected server is offline.\n\nWould you still want to launch Urban Terror?\nIt will just launch a game, without connecting to\nany server."
m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
m.Connect("response", func(resp *glib.CallbackContext) {
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, mbox_string)
messagebox.Connect("response", func(resp *glib.CallbackContext) {
if resp.Args(0) == 4294967287 {
will_continue = false
} else {
will_continue = true
}
messagebox.Destroy()
})
m.Response(func() {
m.Destroy()
})
m.Run()
messagebox.Run()
} else {
// We're ok here, temporary.
will_continue = true
}
if !will_continue {
return errors.New("User declined to connect to offline server")
}
@@ -164,12 +214,18 @@ func (m *MainWindow) launchActually(server_profile *datamodels.Server, user_prof
// Check if server is applicable for selected profile.
if server_profile.Version != user_profile.Version {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Invalid game profile selected.\n\nSelected profile have different game version than server.\nPlease, select valid profile and retry."
m := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
messagebox := gtk.NewMessageDialog(m.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
messagebox.Response(func() {
messagebox.Destroy()
})
m.Run()
messagebox.Run()
} else {
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Invalid game profile selected.</span></markup>"})
}
return errors.New("User didn't select valid profile, mismatch with server's version.")
}
@@ -179,9 +235,14 @@ func (m *MainWindow) launchActually(server_profile *datamodels.Server, user_prof
}
// Hey, we're ok here! :) Launch Urban Terror!
// Crear server name from "<markup></markup>" things.
srv_name_for_label := string([]byte(server_profile.Name)[8:len(server_profile.Name)-9])
fmt.Println(srv_name_for_label)
// Clear server name from "<markup></markup>" things.
srv_name_for_label := server_profile.Name
if strings.Contains(server_profile.Name, "markup") {
srv_name_for_label = string([]byte(server_profile.Name)[8:len(server_profile.Name)-9])
} else {
srv_name := ctx.Colorizer.Fix(server_profile.Name)
srv_name_for_label = string([]byte(srv_name)[8:len(srv_name)-9])
}
// Show great coloured label.
ctx.Eventer.LaunchEvent("setToolbarLabelText", map[string]string{"text": "<markup><span foreground=\"red\" font_weight=\"bold\">Urban Terror is launched with profile </span><span foreground=\"blue\">" + user_profile.Name + "</span> <span foreground=\"red\" font_weight=\"bold\">and connected to </span><span foreground=\"orange\" font_weight=\"bold\">" + srv_name_for_label + "</span></markup>"})
m.launch_button.SetSensitive(false)

View File

@@ -0,0 +1,96 @@
package ui
import (
// stdlib
"strconv"
"strings"
// other
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
)
func (m *MainWindow) sortServersByName(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter) int {
var name1_raw glib.GValue
var name2_raw glib.GValue
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
if current_tab == "Servers" {
model.GetValue(a, m.column_pos["Servers"]["Name"], &name1_raw)
model.GetValue(b, m.column_pos["Servers"]["Name"], &name2_raw)
} else if current_tab == "Favorites" {
model.GetValue(a, m.column_pos["Favorites"]["Name"], &name1_raw)
model.GetValue(b, m.column_pos["Favorites"]["Name"], &name2_raw)
} else {
return 0
}
name1 := strings.ToLower(ctx.Colorizer.ClearFromMarkup(name1_raw.GetString()))
name2 := strings.ToLower(ctx.Colorizer.ClearFromMarkup(name2_raw.GetString()))
if name1 < name2 {
return -1
} else {
return 1
}
return 0
}
func (m *MainWindow) sortServersByPlayers(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter) int {
var players1_raw glib.GValue
var players2_raw glib.GValue
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
if current_tab == "Servers" {
model.GetValue(a, m.column_pos["Servers"]["Players"], &players1_raw)
model.GetValue(b, m.column_pos["Servers"]["Players"], &players2_raw)
} else if current_tab == "Favorites" {
model.GetValue(a, m.column_pos["Favorites"]["Players"], &players1_raw)
model.GetValue(b, m.column_pos["Favorites"]["Players"], &players2_raw)
} else {
return 0
}
players1_online := strings.Split(players1_raw.GetString(), "/")[0]
players2_online := strings.Split(players2_raw.GetString(), "/")[0]
if len(players1_online) > 0 && len(players2_online) > 0 {
players1, _ := strconv.Atoi(players1_online)
players2, _ := strconv.Atoi(players2_online)
if players1 > players2 {
return -1
} else {
return 1
}
}
return -1
}
func (m *MainWindow) sortServersByPing(model *gtk.TreeModel, a *gtk.TreeIter, b *gtk.TreeIter) int {
var ping1_raw glib.GValue
var ping2_raw glib.GValue
current_tab := m.tab_widget.GetTabLabelText(m.tab_widget.GetNthPage(m.tab_widget.GetCurrentPage()))
if current_tab == "Servers" {
model.GetValue(a, m.column_pos["Servers"]["Ping"], &ping1_raw)
model.GetValue(b, m.column_pos["Servers"]["Ping"], &ping2_raw)
} else if current_tab == "Favorites" {
model.GetValue(a, m.column_pos["Favorites"]["Ping"], &ping1_raw)
model.GetValue(b, m.column_pos["Favorites"]["Ping"], &ping2_raw)
} else {
return 0
}
ping1, _ := strconv.Atoi(ping1_raw.GetString())
ping2, _ := strconv.Atoi(ping2_raw.GetString())
if ping1 < ping2 {
return 1
} else {
return -1
}
return -1
}

View File

@@ -12,6 +12,7 @@ package ui
import (
// stdlib
"fmt"
"runtime"
// Local
"github.com/pztrn/urtrator/datamodels"
@@ -66,12 +67,16 @@ func (o *OptionsDialog) closeOptionsDialogWithSaving() {
o.saveGeneral()
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Some options require application restart to be applied."
m := gtk.NewMessageDialog(o.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
})
m.Run()
}
o.window.Destroy()
}
@@ -128,18 +133,46 @@ func (o *OptionsDialog) fill() {
}
}
// Appearance tab initialization.
func (o *OptionsDialog) initializeAppearanceTab() {
appearance_vbox := gtk.NewVBox(false, 0)
l := gtk.NewLabel("There will be some appearance configuration options soon.")
appearance_vbox.PackStart(l, false, true, 5)
o.tab_widget.AppendPage(appearance_vbox, gtk.NewLabel("Appearance"))
}
func (o *OptionsDialog) initializeGeneralTab() {
general_vbox := gtk.NewVBox(false, 0)
general_table := gtk.NewTable(2, 2, false)
// Tray icon checkbox.
o.show_tray_icon = gtk.NewCheckButtonWithLabel("Show tray icon?")
show_tray_icon_label := gtk.NewLabel("Show icon in tray")
show_tray_icon_label.SetAlignment(0, 0)
general_table.Attach(show_tray_icon_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
o.show_tray_icon = gtk.NewCheckButtonWithLabel("")
o.show_tray_icon.SetTooltipText("Show icon in tray")
general_vbox.PackStart(o.show_tray_icon, false, true, 5)
general_table.Attach(o.show_tray_icon, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
// Autoupdate checkbox.
o.autoupdate = gtk.NewCheckButtonWithLabel("Automatically update URTrator?")
o.autoupdate.SetTooltipText("Should URTrator check for updates and update itself? Not working now.")
general_vbox.PackStart(o.autoupdate, false, true, 5)
autoupdate_tooltip := "Should URTrator check for updates and update itself? Not working now."
autoupdate_label := gtk.NewLabel("Automatically update URTrator?")
autoupdate_label.SetTooltipText(autoupdate_tooltip)
autoupdate_label.SetAlignment(0, 0)
general_table.Attach(autoupdate_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
o.autoupdate = gtk.NewCheckButtonWithLabel("")
o.autoupdate.SetTooltipText(autoupdate_tooltip)
general_table.Attach(o.autoupdate, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
// Vertical separator.
sep := gtk.NewVBox(false, 0)
general_vbox.PackStart(general_table, false, true, 0)
general_vbox.PackStart(sep, false, true, 0)
o.tab_widget.AppendPage(general_vbox, gtk.NewLabel("General"))
}
@@ -153,13 +186,15 @@ func (o *OptionsDialog) initializeStorages() {
func (o *OptionsDialog) initializeTabs() {
o.initializeStorages()
o.tab_widget = gtk.NewNotebook()
o.tab_widget.SetTabPos(gtk.POS_LEFT)
o.initializeGeneralTab()
o.initializeAppearanceTab()
o.initializeUrtTab()
// Buttons for saving and discarding changes.
buttons_hbox := gtk.NewHBox(false, 0)
sep := gtk.NewHSeparator()
sep := gtk.NewHBox(false, 0)
cancel_button := gtk.NewButtonWithLabel("Cancel")
cancel_button.Clicked(o.closeOptionsDialogByCancel)
@@ -178,7 +213,7 @@ func (o *OptionsDialog) initializeTabs() {
}
func (o *OptionsDialog) initializeUrtTab() {
urt_hbox := gtk.NewHBox(false, 0)
urt_hbox := gtk.NewHBox(false, 5)
// Profiles list.
o.profiles_list = gtk.NewTreeView()
@@ -188,17 +223,13 @@ func (o *OptionsDialog) initializeUrtTab() {
o.profiles_list.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Profile name", gtk.NewCellRendererText(), "text", 0))
o.profiles_list.AppendColumn(gtk.NewTreeViewColumnWithAttributes("Urban Terror version", gtk.NewCellRendererText(), "text", 1))
//crt := gtk.NewCellRendererToggle()
//second_x_column := gtk.NewTreeViewColumnWithAttributes("Second X session", crt, "bool", 2)
//o.profiles_list.AppendColumn(second_x_column)
// Profiles list buttons.
urt_profiles_buttons_vbox := gtk.NewVBox(false, 0)
button_add := gtk.NewButtonWithLabel("Add")
button_add.SetTooltipText("Add new profile")
button_add.Clicked(o.addProfile)
urt_profiles_buttons_vbox.PackStart(button_add, false, true, 5)
urt_profiles_buttons_vbox.PackStart(button_add, false, true, 0)
button_edit := gtk.NewButtonWithLabel("Edit")
button_edit.SetTooltipText("Edit selected profile. Do nothing if no profile was selected.")
@@ -206,13 +237,13 @@ func (o *OptionsDialog) initializeUrtTab() {
urt_profiles_buttons_vbox.PackStart(button_edit, false, true, 5)
// Spacer for profiles list buttons.
sep := gtk.NewVSeparator()
sep := gtk.NewVBox(false, 0)
urt_profiles_buttons_vbox.PackStart(sep, true, true, 5)
button_delete := gtk.NewButtonWithLabel("Delete")
button_delete.SetTooltipText("Delete selected profile. Do nothing if no profile was selected.")
button_delete.Clicked(o.deleteProfile)
urt_profiles_buttons_vbox.PackStart(button_delete, false, true, 5)
urt_profiles_buttons_vbox.PackStart(button_delete, false, true, 0)
urt_hbox.Add(urt_profiles_buttons_vbox)

View File

@@ -27,8 +27,8 @@ import (
type OptionsProfile struct {
// Window.
window *gtk.Window
// Main Vertical Box.
vbox *gtk.VBox
// Main table.
table *gtk.Table
// Profile name.
profile_name *gtk.Entry
// Binary path.
@@ -53,7 +53,7 @@ type OptionsProfile struct {
}
func (op *OptionsProfile) browseForBinary() {
op.f = gtk.NewFileChooserDialog("URTrator - Select Urban Terro binary", op.window, gtk.FILE_CHOOSER_ACTION_OPEN, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
op.f = gtk.NewFileChooserDialog("URTrator - Select Urban Terror binary", op.window, gtk.FILE_CHOOSER_ACTION_OPEN, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
op.f.Response(op.browseForBinaryHelper)
op.f.Run()
}
@@ -62,6 +62,7 @@ func (op *OptionsProfile) browseForBinaryHelper() {
filename := op.f.GetFilename()
op.binary_path.SetText(filename)
op.f.Destroy()
fmt.Println(filename)
// Check for valid filename.
// ToDo: add more OSes.
@@ -70,27 +71,56 @@ func (op *OptionsProfile) browseForBinaryHelper() {
if runtime.GOARCH == "amd64" {
if len(filename) > 0 && strings.Split(filename, ".")[1] != "x86_64" && strings.Split(filename, ".")[0] != "Quake3-UrT" {
fmt.Println("Invalid binary selected!")
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Invalid binary selected!\nAccording to your OS, it should be Quake3-UrT.x86_64."
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
})
m.Run()
} else {
//
}
op.binary_path.SetText("")
}
}
} else if runtime.GOOS == "darwin" {
// No separate arch thing here, macOS now 64bit only.
if len(filename) > 0 && strings.Split(filename, ".")[1] != "app" && strings.Split(filename, ".")[0] != "Quake3-UrT" {
// Official application: Quake3-UrT.app. Split by it and get second
// part of string.
if strings.Contains(filename, "Quake3-UrT.app") {
filename = strings.Split(filename, "Quake3-UrT.app")[1]
if len(filename) > 0 && !strings.Contains(strings.Split(filename, ".")[1], "x86_64") && !strings.Contains(strings.Split(filename, ".")[0], "Quake3-UrT") {
fmt.Println("Invalid binary selected!")
mbox_string := "Invalid binary selected!\nAccording to your OS, it should be Quake3-UrT.app."
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Invalid binary selected!\nAccording to your OS, it should be Quake3-UrT.app/Contents/MacOS/Quake3-UrT.x86_64."
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
})
m.Run()
} else {
//
}
op.binary_path.SetText("")
}
} else {
// Temporary disable all these modals on Linux.
// See https://github.com/mattn/go-gtk/issues/289.
if runtime.GOOS != "linux" {
mbox_string := "Invalid binary selected!\nAccording to your OS, it should be Quake3-UrT.app/Contents/MacOS/Quake3-UrT.x86_64.\n\nNote, that currently URTrator supports only official binary."
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
m.Response(func() {
m.Destroy()
})
m.Run()
} else {
//
}
}
}
}
@@ -118,90 +148,85 @@ func (op *OptionsProfile) Initialize(update bool) {
op.window.SetPosition(gtk.WIN_POS_CENTER)
op.window.SetIcon(logo)
op.vbox = gtk.NewVBox(false, 0)
op.table = gtk.NewTable(6, 2, false)
op.table.SetRowSpacings(2)
// Profile name.
profile_name_tooltip := "This how you will see profile on profiles lists."
pn_hbox := gtk.NewHBox(false, 0)
pn_label := gtk.NewLabel("Profile name:")
pn_label.SetTooltipText(profile_name_tooltip)
profile_name_sep := gtk.NewHSeparator()
profile_name_sep.SetTooltipText(profile_name_tooltip)
pn_label.SetAlignment(0, 0)
op.table.Attach(pn_label, 0, 1, 0, 1, gtk.FILL, gtk.SHRINK, 5, 5)
op.profile_name = gtk.NewEntry()
op.profile_name.SetTooltipText(profile_name_tooltip)
pn_hbox.PackStart(pn_label, false, true, 5)
pn_hbox.PackStart(profile_name_sep, true, true, 5)
pn_hbox.PackStart(op.profile_name, true, true, 5)
op.vbox.PackStart(pn_hbox, false, true, 5)
op.table.Attach(op.profile_name, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5)
// Urban Terror version.
urt_version_tooltip := "Urban Terror version for which this profile applies."
urt_version_hbox := gtk.NewHBox(false, 0)
urt_version_label := gtk.NewLabel("Urban Terror version:")
urt_version_label.SetTooltipText(urt_version_tooltip)
urt_version_sep := gtk.NewHSeparator()
urt_version_sep.SetTooltipText(urt_version_tooltip)
urt_version_label.SetAlignment(0, 0)
op.table.Attach(urt_version_label, 0, 1, 1, 2, gtk.FILL, gtk.SHRINK, 5, 5)
op.urt_version_combo = gtk.NewComboBoxText()
op.urt_version_combo.SetTooltipText(urt_version_tooltip)
op.urt_version_combo.AppendText("4.2.023")
op.urt_version_combo.AppendText("4.3.0")
op.urt_version_combo.AppendText("4.3.1")
op.urt_version_combo.SetActive(1)
urt_version_hbox.PackStart(urt_version_label, false, true, 5)
urt_version_hbox.PackStart(urt_version_sep, true, true, 5)
urt_version_hbox.PackStart(op.urt_version_combo, true, true, 5)
op.vbox.PackStart(urt_version_hbox, false, true, 5)
op.urt_version_combo.SetActive(2)
op.table.Attach(op.urt_version_combo, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
// Urban Terror binary path.
select_binary_tooltip := "Urban Terror binary. Some checks will be executed, so make sure you have selected right binary:\n\nQuake3-UrT.i386 for linux-x86\nQuake3-UrT.x86_64 for linux-amd64\nQuake3-UrT.app for macOS"
binpath_hbox := gtk.NewHBox(false, 0)
binpath_label := gtk.NewLabel("Urban Terror binary:")
binpath_label.SetTooltipText(select_binary_tooltip)
binpath_sep := gtk.NewHSeparator()
binpath_sep.SetTooltipText(select_binary_tooltip)
binpath_label.SetAlignment(0, 0)
op.table.Attach(binpath_label, 0, 1, 2, 3, gtk.FILL, gtk.SHRINK, 5, 5)
op.binary_path = gtk.NewEntry()
op.binary_path.SetTooltipText(select_binary_tooltip)
button_select_binary := gtk.NewButtonWithLabel("Browse")
button_select_binary.SetTooltipText(select_binary_tooltip)
button_select_binary.Clicked(op.browseForBinary)
binpath_hbox.PackStart(binpath_label, false, true, 5)
binpath_hbox.PackStart(binpath_sep, true, true, 5)
binpath_hbox.PackStart(op.binary_path, true, true, 5)
binpath_hbox.PackStart(button_select_binary, false, true, 5)
op.vbox.PackStart(binpath_hbox, false, true, 5)
op.table.Attach(binpath_hbox, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0)
// Should we use additional X session?
another_x_tooltip := "If this is checked, Urban Terror will be launched in another X session.\n\nThis could help if you're experiencing visual lag, glitches and FPS drops under compositing WMs, like Mutter and KWin."
op.another_x_session = gtk.NewCheckButtonWithLabel("Start Urban Terror in another X session?")
another_x_label := gtk.NewLabel("Start Urban Terror in another X session?")
another_x_label.SetTooltipText(another_x_tooltip)
another_x_label.SetAlignment(0, 0)
op.table.Attach(another_x_label, 0, 1, 3, 4, gtk.FILL, gtk.SHRINK, 5, 5)
op.another_x_session = gtk.NewCheckButtonWithLabel("")
op.another_x_session.SetTooltipText(another_x_tooltip)
op.vbox.PackStart(op.another_x_session, false, true, 5)
// macOS can't do that :).
if runtime.GOOS == "darwin" {
// macOS and Windows can't do that :).
if runtime.GOOS != "linux" {
op.another_x_session.SetSensitive(false)
}
op.table.Attach(op.another_x_session, 1, 2, 3, 4, gtk.FILL, gtk.FILL, 5, 5)
// Additional game parameters.
params_tooltip := "Additional parameters that will be passed to Urban Terror executable."
params_hbox := gtk.NewHBox(false, 0)
params_label := gtk.NewLabel("Additional parameters:")
params_label.SetTooltipText(params_tooltip)
params_sep := gtk.NewHSeparator()
params_sep.SetTooltipText(params_tooltip)
params_label.SetAlignment(0, 0)
op.table.Attach(params_label, 0, 1, 4, 5, gtk.FILL, gtk.SHRINK, 5, 5)
op.additional_parameters = gtk.NewEntry()
op.additional_parameters.SetTooltipText(params_tooltip)
params_hbox.PackStart(params_label, false, true, 5)
params_hbox.PackStart(params_sep, true, true, 5)
params_hbox.PackStart(op.additional_parameters, true, true, 5)
op.vbox.PackStart(params_hbox, false, true, 5)
op.table.Attach(op.additional_parameters, 1, 2, 4, 5, gtk.FILL, gtk.FILL, 5, 5)
// Vertical separator.
vert_sep := gtk.NewVSeparator()
op.vbox.PackStart(vert_sep, true, true, 5)
// Invisible thing.
inv_label := gtk.NewLabel("")
op.table.Attach(inv_label, 1, 2, 5, 6, gtk.EXPAND, gtk.FILL, 5, 5)
// The buttons.
buttons_box := gtk.NewHBox(false, 0)
buttons_sep := gtk.NewHSeparator()
buttons_sep := gtk.NewHBox(false, 0)
cancel_button := gtk.NewButtonWithLabel("Cancel")
cancel_button.SetTooltipText("Close without saving")
@@ -221,9 +246,14 @@ func (op *OptionsProfile) Initialize(update bool) {
add_button.Clicked(op.saveProfile)
buttons_box.PackStart(add_button, false, true, 5)
op.vbox.PackStart(buttons_box, false, true, 5)
vert_sep_box := gtk.NewVBox(false, 0)
op.window.Add(op.vbox)
vbox := gtk.NewVBox(false, 0)
vbox.PackStart(op.table, false, true, 5)
vbox.PackStart(vert_sep_box, true, true, 5)
vbox.PackStart(buttons_box, false, true, 5)
op.window.Add(vbox)
op.window.ShowAll()
}
@@ -232,26 +262,23 @@ func (op *OptionsProfile) InitializeUpdate(profile_name string) {
op.Initialize(true)
// Get profile data.
profile := []datamodels.Profile{}
err := ctx.Database.Db.Select(&profile, ctx.Database.Db.Rebind("SELECT * FROM urt_profiles WHERE name=?"), profile_name)
if err != nil {
fmt.Println(err.Error())
}
op.profile_name.SetText(profile[0].Name)
op.binary_path.SetText(profile[0].Binary)
op.additional_parameters.SetText(profile[0].Additional_params)
if profile[0].Second_x_session == "1" {
profile := ctx.Cache.Profiles[profile_name].Profile
op.profile_name.SetText(profile.Name)
op.binary_path.SetText(profile.Binary)
op.additional_parameters.SetText(profile.Additional_params)
if profile.Second_x_session == "1" {
op.another_x_session.SetActive(true)
}
if profile[0].Version == "4.3.0" {
if profile.Version == "4.3.0" {
op.urt_version_combo.SetActive(1)
} else if profile.Version == "4.3.1" {
op.urt_version_combo.SetActive(2)
} else {
op.urt_version_combo.SetActive(0)
}
op.old_profile = &profile[0]
op.old_profile = profile
}

View File

@@ -18,9 +18,6 @@ import (
// stdlib
"fmt"
"runtime"
// other
"github.com/couchbase/goutils/platform"
)
func main() {
@@ -29,11 +26,6 @@ func main() {
numCPUs := runtime.NumCPU()
runtime.GOMAXPROCS(numCPUs)
if runtime.GOOS == "windows" {
platform.HideConsole(true)
defer platform.HideConsole(false)
}
ctx := context.New()
ctx.Initialize()