Compare commits
69 Commits
v0.1.0-bet
...
0.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 32c6297765 | |||
| 190f76eb82 | |||
| 5c295f08ab | |||
| 061bfcaeb9 | |||
| 5ca8299714 | |||
| 9c8aa1cc34 | |||
| 5fcbd8536c | |||
| fb7a471aec | |||
| 8c9d948a52 | |||
| 8b44d194b5 | |||
| 3b0a93e63a | |||
| b85ba0470c | |||
| f127fdc9f4 | |||
| 5ef54d943e | |||
| 9e6cdfc869 | |||
| bfd3f884b3 | |||
| 7e6b698c1c | |||
| 4516abb916 | |||
| e731653652 | |||
| e16d6fa878 | |||
| 89298d894b | |||
| 88b9b31f6a | |||
| 1fe49871f1 | |||
| 4f5bf90dbe | |||
| 25bebf87df | |||
| c4ed421106 | |||
| 0c0fcd5b24 | |||
| 4d466a9d2b | |||
| 2cdee94efe | |||
| 2b1caac8f6 | |||
| 862b336556 | |||
| 90f888bdfb | |||
| a132ee0f7b | |||
| 8b06dff083 | |||
| ea8bdde224 | |||
| 6495e90737 | |||
| 3e89df1009 | |||
| c00ff2cea5 | |||
| 93d2bb7fc1 | |||
| 0392f510f5 | |||
| 57a5f7cb4c | |||
| 8a3f2a9a2e | |||
| 4e9a6ae970 | |||
| 7f80f99529 | |||
| b1d38bbdcf | |||
| e487b8521c | |||
| e12c76e424 | |||
| 640020d23f | |||
| a64c842e19 | |||
| 1330699f41 | |||
| a97b041679 | |||
| 68bd842c1f | |||
| 9be55c982e | |||
| 35097c3805 | |||
| 3537b05dce | |||
| 56c0d2787a | |||
| f8b29a03d3 | |||
| eaaa8b565f | |||
| e817a8fe64 | |||
| 1a15c6cd4d | |||
| 2746e0e315 | |||
| 2784586f8d | |||
| 25dfa5072b | |||
| df4d6a3cca | |||
| eaffb1f1ab | |||
| c5349ab336 | |||
| f283e93719 | |||
| bbe03c485e | |||
| f793b2f467 |
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
# We don't need binaries.
|
||||
urtrator
|
||||
*tar*
|
||||
|
||||
# macOS things
|
||||
.DS_Store
|
||||
|
||||
15
README.md
@@ -2,6 +2,8 @@
|
||||
|
||||
[](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).
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
6
cache/cache_servers.go
vendored
@@ -65,6 +65,7 @@ func (c *Cache) FlushServers(data map[string]string) {
|
||||
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
|
||||
@@ -80,6 +81,7 @@ func (c *Cache) FlushServers(data map[string]string) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,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, favorite) VALUES (:ip, :port, :name, :ping, :players, :maxplayers, :gamemode, :map, :version, :extended_config, :players_info, :is_private, :favorite)", 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, favorite=:favorite, password=:password, 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())
|
||||
}
|
||||
|
||||
114
clipboardwatcher/clipboardwatcher_object.go
Normal 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})
|
||||
}
|
||||
}
|
||||
28
clipboardwatcher/exported.go
Normal 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
|
||||
}
|
||||
@@ -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, ">")
|
||||
|
||||
if len(data_splitted) > 1 {
|
||||
for item := range data_splitted {
|
||||
if len(data_splitted[item]) > 0 {
|
||||
result += strings.Split(data_splitted[item], "<")[0]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = data_splitted[0]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (c *Colorizer) Fix(data string) string {
|
||||
result := ""
|
||||
var result string = ""
|
||||
|
||||
data = html.EscapeString(data)
|
||||
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
package common
|
||||
|
||||
const (
|
||||
URTRATOR_VERSION = "0.1-beta1"
|
||||
URTRATOR_VERSION = "0.1.0"
|
||||
)
|
||||
|
||||
16
common/server_list_icons.go
Normal 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 = `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`
|
||||
var SERVER_PRIVATE = `iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAZcSURBVFiFrZddbBxXFcd/587M7sza69hxbGM7Dk5paQGJJmrVghQKEvBSPqS2Emp4aFQJBVECAhIpBakFEfpSgYTUKrQWeUHigT4gpL5UCFEIDXHUNib0i1pJS+I4btLWsdfr2fm69/Cwu66j+iNOONLR7O4c3fOb/zl77h1RVa7RpOXa8msyf4Px3uGnn3zAM+Y+z/dvEJGhIi8CYNo593raiP/W09P/1J49e5KrXVCuUgE5fPiJu4ZHtv5uaHBoYNu20fKmri58PwCBPM9ZWKhxfPx4MjV1tpakjW8f+OHDf/q/ARw58vRnw0rlr/d/45uhMYbCFqhzFLbAqUMQECFpNLgwc55jx16I52u1Bw8e+Mkz1w0wPj4eTZ554z937fr8yPDwiHjGY3r6PK++/koyNT1VaOHM0NZBPjqyvdI/MAACMxemOXr0H3NJORs9uPfg/Frrr9sDp145+f1bP71joLd3izTimNfeeLV46aUXp9I0e0pt8WfPk/rkm4tfOn9u+sHR0dFbd+zcUe7r72N0dFt45sxbDwM/vh4ACfzSF4eGhssA56bOMj4+PuuK+h0H9v/0vWVxp8fGxo6cPfv2yb6B/k8ODQ6aLf394bmzU59b7wHNOvf9clj+RBRFqCqTk5OLWZ7u339lcgD27t2bC+ZHMxdmGgCBH+BUb7xeAAP0l8shABcvXRSj7vhqwV1dmydmZ2dLCoRhiLVF79jYWHDNAM8991zZOecbY7DOUhR5EMf24mrxu3fvniuKIgAQEVTVxvFMx1o5VuyBR78lO1X4TDnq+8j2O38pzlmstag633//8ZcPffcXVWddp6pGAGIkFkPdeMHC4M4nltaxeeYv/PfXP3h078/ewXHi57/ViXUBHtsnv9p+0w3f2XnnHX7Y0eu9fFrFqeKcQxV5YN9jHw8rEeVSRFCKEJQ8T7riuNaVpA3+cmzZYgbv7vu+8ogWdfvaxL+LQ/vkN488qfvXBMgLHtrzvcdD44VYK7w4eQlrC/IiR53jvctlqoVPFBlCq3jGI80CGmmVRhLibIG1FussqobtN99j+vqq5vZdi8Gh/fc+BKwN4Cyh8XoA8DylI8w4evR55ufn6awoHR1Venu78X0P3/cREYKSIwwt1cJR7ZzmXxMTxPEi3ZvKzC9kbOkL8YIIZwnXLQGAmj5ESkDG1+/u5fRb75DnJUaGb6JaLSEoIgo4mhuiQVVADPd8tZ9z03M0YsPw4Ha6e7oQr4ItZldKtTJAWv8nhhgTDOEFQ9xy8wiqAYpB1QcTohIiJgIF52JsUcfmdYq8xpYeIa8kxPVTJAtzGJkjb5y6egA0J1v4A36pH4k+hQmGKPKYPHuXLJkhTWqkaUyWpWRpQpql5GlClqWkaUKWp2RpSpalVCLo7OzkYzfevgGAJTMtl+aO1/4s4BnB8wTfF1QFUUGk6Z4n+AYCH6qd0L0J/FUyrTcJr9ucQtyAOF75/kZPRACognWKtUpRKFmu5JmSZUqaNr9nKWRZM74SQRRtCGDtM8JGSxCWwdqNAKhbE2ApTME5cMvUyAslzyHLIU2bsNZBV88GAHSdg267BE4VRWkfqkSazSoGjGk2XqUCm7uhXN4AQHPArG5LJTCCM4LzWu6aSVVBvaaQRppqNFY5J5sPFhURkSaQrlKwZdaWf3kjpqmSpEojUeIGLMZQW4AkhXJpKY8vIkt5/daPBgiA6ocVWLkUIk2ZlxrRteSXpjLLm7CrszmwW7YZWBCRVFVdm8RrJR+5EsAuueKAYkMNam3z6S/PX1GCbUAX4ImIGBFpj7gK0CuCK/IM8XpQzVFXB10EXURdA6VAVZfmQJ6vJL+SJM3ag9DTXcX3HCI4oLeVywPwVVWlubXlwGIt5sQff//Mbbu+fH+pVO7EbwT4ng+SgkZAH16pQeQ38Ep1/FJMuSjIwoIsc5RSS1FAkTcVCHyPy7WMF/5+MpurcwKIgaxdW1HVdg9EwOYgoO/eL/C1gS1yW1j2u6Io6iqHYWfglzrEmMgzpgQSIp4JgsCqKnmWeM4V1lmbWc0TV9gky/N6mqaLeVHUslRrl2aZePYYz8Yx7wLvAw1VtW2AdhkCoNxyjw/egD9kUYR3y1Y6NEDefJt6o8Fqf532ULGtJ09bV6eqesWrWQukDcNqya/BdNnV6bKk/wNfA0H9/hWdtQAAAABJRU5ErkJggg==`
|
||||
var SERVER_PUBLIC = `iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAa7SURBVFiFrZddiF1XFcd/a59z7rn3zp2bmUlmbL7HJIXW1JJ0aprEPBisrRAEBRGftA9t/cKX6jAl2mJRQmNoiBFREFEfFPRBEH1pU7DVVpM0pBTFWENiJtYm0/meuR/n7HP2Xj7ce+fLSSA4GzaHffY9Z/32f/33XueKqrJW7fiJY9VCofCZzZu3fG2gf2BHFEbNqanJG6P/Hn2xXq+fHhk+enXlM7JWAKdOv9DX1VX5+4H9B3t3f+C+AoD3HlCmpqf9a6//MR8dvXYhTdMvjAwf/duaAhw/cSzYsGHD2f37D+zduWNXEBeKAGS5RcQQmADvPW9fvqRnXn5pPk3SwyPDRy8CmP87OtDVVXli+/bB+7Zt3R6kacLE1HvcfO8G/7nxDlPTEzSadQB27bhbHn3k49Uoil45fuLYboBwTQDK5Y8MDg4WVZXJ6QlujL3L+bNvNPPcaWCM2bfvofj++/dIMS6ybesgQ0ND5QsXLgwDj62JAmJkqLu7ildHrVHj+rXrWZqkJ4afGunKsuzg+fPnLr36yh+aeZ4ThSE7d90dAJ8+fuJYvCYAzrntcaGA957UJkyMTzRtas8CjAwffTPLsn1X/3XF12rzAFS6uhkYeJ8DjqwJgCqRiOC9J0stjUYzMIH5a2d+ZPho3Xv/o2uj1zJEMMYwOLi9GkXRJ9cEYAkIee7wzodRFNWWzjnnzszNzlr1HgHiuIgxZsuaAoDi8avOOOcm0zRBAREhDENUtX+NAToYq54tU2lqjWpr1kiAqvYt24bPPiF7gf1ATxCaDVEYDoiR9UCfqvZ476ve+YpzWgIwgTSMUNv44A9XxPLh1D9ODj/92DfeFeHs8z/j4nPffnYmtWmo6kEVVSXP8+oCwHe+Ii+8f9eOL+196ENhubIuKJd7TVyuEkUxYVQkCAsEYUwQxJggBlWcS6uZrVd/+VuPGINIS1BBgkMPH346DhN35dKl/JuPX/vxqZPfH/ne6ZOhtoMrHud8eQHAOb78+a9+t2iCIq//5RJjV2ZYtw4Gt/ewZXM/cRwtWaGAQGhKhFEPWXaVRr2Ox+OdR4FyzwFzzz1bzAMH8+jkM597cnp6+luAdd7H7dWjqn4pQNEEve1RAYiAGCi2rwWQJQCdfKuyccDw0pkXAWVsbIxiwRGEMZVKL1EUgFIEco8m6n0MYLMMVa/LPKCmH5ECHz7Uz6KPPJADDtS3x74N0ZL9yKN7uHlzluvvTDD0wXvZeFc/63qqGFMizyYJW1EaeFWvnkAMoBhjlgOktT9jaGCiTQTRJiToQzVGMaiGiCmCFBFTAgXvG7i8hnM11vUI93YJWTpNff4tmnMzGJkha77VUcr99Oc/Qb1CKMzNzlGIY7+8GGmGnf8VYWEAKe3GRJvIswaZHccmN0iTOdK0gbUpNk1IbUqWJlibkqYJNkuxaYq1KeUSVCoVdu56cMUOUebmZhkfHycw5lbl2LS7IG2pQRCBwAhBIIShUIiEQkGIY6FYFEpFoVyCrjJUu6Gvh478rWQ6lzeThCzP2fvAHqy10ZqU49WaV2g0odFYvOe8f+6N8+dPVatV+8/Lb0fGmOfv6CRUBecV55Q8V2ymWKukqZIkSjNRGk2oN6BeB2OgVFp8/snHv/iDSqWyeXT02pFms7np60+NPLNCgdt/nq1MgaogKoi0ehAIoYEohO4KFGNwbnmAhz/6yBgw1rmxwoSrF5LVlPAe/BI1slzJMrAZpGkL1nmo9t7+XcvPAZTbqdBJgVdFUTrfsyIts4ppyR6GUC63TBjHdwDALUpppy2kwAjeCD5od98KqgoatIQ00lKjmdwewEirtUDU3f7XLMq/1IhpqiTpchPOzUOSQlzowEsonWq1QoEC0P2/CqyeCpGWzAtG9G35paXMUhNWK0urBn3AvIikqotmM+3gW5cDuIWunVpwBwZ1rrX66dllKdgGVIFARBa4DFAG1ovg88wiQS+qGeproHXQOuqbKDmqunAOZNlq8itJ0so9CL093YSBRwQPrG/HCpYCh0AG1OebnPvNL349dOhjny0U4gphMyIMQ4QU1RLQTxA1KYVNgkKNsNAgznNsMcdaT5w6shzyDHIHURgwM2d57dWLdqbGOaAB2JW5FaAL6ItC+j91mE/ctcEMFeOgWiqVqnFcqkRR2GVMUDJiYhWJxQQmCiOnqlibBOpz572zzmeJy1ySZbZura3ZLJ+3mc6OTfLm7//E7xoJ48Ak0FRddLu0Jel8fcTtsbDMP4utu0ywcytdRpDL16nNN7jV1ukcKq698rR99brkH/F/AQ0wdhYSGdHKAAAAAElFTkSuQmCC
|
||||
`
|
||||
22
common/toolbar_icons.go
Normal 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`
|
||||
@@ -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()
|
||||
|
||||
45
doc/installation/macos/README.md
Normal 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.
|
||||
|
After Width: | Height: | Size: 224 B |
|
After Width: | Height: | Size: 149 B |
|
After Width: | Height: | Size: 157 B |
@@ -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.
|
||||
@@ -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"
|
||||
@@ -0,0 +1,6 @@
|
||||
[X-GNOME-Metatheme]
|
||||
Name=Clearlooks Brave
|
||||
Encoding=UTF-8
|
||||
GtkTheme=Clearlooks Brave
|
||||
MetacityTheme=Clearlooks-Colors Metacity
|
||||
IconTheme=gnome-brave
|
||||
|
After Width: | Height: | Size: 190 B |
BIN
doc/installation/macos/Resources/themes/OSX/gtk-2.0/Panel/panel-button-hover.png
Executable file
|
After Width: | Height: | Size: 191 B |
|
After Width: | Height: | Size: 191 B |
BIN
doc/installation/macos/Resources/themes/OSX/gtk-2.0/Panel/panel.png
Executable file
|
After Width: | Height: | Size: 195 B |
799
doc/installation/macos/Resources/themes/OSX/gtk-2.0/gtkrc
Executable 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"
|
||||
11
doc/installation/macos/Resources/themes/OSX/index.theme
Executable 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
|
||||
2
doc/installation/macos/Resources/themes/gtkrc
Normal file
@@ -0,0 +1,2 @@
|
||||
include "ClearlooksBrave/gtk-2.0/gtkrc"
|
||||
include "gtkrc-keybindings"
|
||||
157
doc/installation/macos/Resources/themes/gtkrc-keybindings
Normal 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"
|
||||
@@ -1,5 +1,31 @@
|
||||
#!/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?
|
||||
@@ -32,16 +58,19 @@ if [ $? -ne 0 ]; then
|
||||
fi
|
||||
|
||||
echo "Building URTrator..."
|
||||
go build -v github.com/pztrn/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 /Applications/URTrator.app/Contents/{MacOS,Library,Resources}
|
||||
cp $GOPATH/bin/urtrator /Applications/URTrator.app/Contents/MacOS/
|
||||
cp $GOPATH/src/github.com/pztrn/urtrator/artwork/urtrator.icns /Applications/URTrator.app/Contents/Resources/
|
||||
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
|
||||
@@ -53,7 +82,7 @@ INFOPLIST='<?xml version="1.0" encoding="UTF-8"?>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>URTrator</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>urtrator</string>
|
||||
<string>urtrator.sh</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>name.pztrn.urtrator</string>
|
||||
<key>CFBundleName</key>
|
||||
@@ -73,20 +102,54 @@ INFOPLIST='<?xml version="1.0" encoding="UTF-8"?>
|
||||
</dict>
|
||||
</plist>'
|
||||
|
||||
echo ${INFOPLIST} > /Applications/URTrator.app/Contents/Info.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.
|
||||
echo "Copying libraries..."
|
||||
LIBS_TO_COPY=$(otool -L urtrator | awk {' print $1 '} | grep "/usr/local")
|
||||
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"
|
||||
|
||||
for lib in ${LIBS_TO_COPY[@]}; do
|
||||
cp ${lib} /Applications/URTrator.app/Contents/Library
|
||||
libname=$(echo ${lib} | awk -F"/" {' print $NF '})
|
||||
install_name_tool -change ${lib} @executable_path/../Library/${libname} /Applications/URTrator.app/Contents/MacOS/urtrator
|
||||
#####################################################################
|
||||
# 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! Launch from Applications!"
|
||||
echo "URTrator is ready! Copy URTrator.app bundle to Applications and launch it!"
|
||||
|
||||
3
doc/installation/windows/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Windows installation
|
||||
|
||||
*TBW*
|
||||
115
doc/installation/windows/make-dist.sh
Normal 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."
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -33,13 +35,17 @@ type Launcher struct {
|
||||
|
||||
func (l *Launcher) CheckForLaunchedUrbanTerror() error {
|
||||
if l.launched {
|
||||
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() {
|
||||
m.Destroy()
|
||||
})
|
||||
m.Run()
|
||||
return errors.New("User didn't select valid profile, mismatch with server's version.")
|
||||
// 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() {
|
||||
m.Destroy()
|
||||
})
|
||||
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())
|
||||
|
||||
@@ -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:], "\\")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
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()
|
||||
// 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 {
|
||||
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()
|
||||
// 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")
|
||||
}
|
||||
|
||||
|
||||
215
ui/mainwindow.go
@@ -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.
|
||||
@@ -118,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() {
|
||||
@@ -157,17 +171,23 @@ func (m *MainWindow) addToFavorites() {
|
||||
// Executes when delimiter for two panes is moved, to calculate VALID
|
||||
// position.
|
||||
func (m *MainWindow) checkMainPanePosition() {
|
||||
m.pane_negative_position = m.window_width - m.hpane.GetPosition()
|
||||
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() {
|
||||
m.window.GetPosition(&m.window_pos_x, &m.window_pos_y)
|
||||
m.window.GetSize(&m.window_width, &m.window_height)
|
||||
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)
|
||||
m.hpane.SetPosition(m.window_width - m.pane_negative_position)
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
// Executes on URTrator shutdown.
|
||||
@@ -191,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...")
|
||||
@@ -213,12 +245,18 @@ func (m *MainWindow) deleteFromFavorites() {
|
||||
}
|
||||
|
||||
if not_favorited {
|
||||
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()
|
||||
// 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{})
|
||||
@@ -229,19 +267,23 @@ func (m *MainWindow) deleteFromFavorites() {
|
||||
func (m *MainWindow) dropDatabasesData() {
|
||||
fmt.Println("Dropping database data...")
|
||||
var will_continue bool = false
|
||||
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) {
|
||||
if resp.Args(0) == 4294967287 {
|
||||
will_continue = false
|
||||
} else {
|
||||
will_continue = true
|
||||
}
|
||||
})
|
||||
d.Response(func() {
|
||||
d.Destroy()
|
||||
})
|
||||
d.Run()
|
||||
// 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) {
|
||||
if resp.Args(0) == 4294967287 {
|
||||
will_continue = false
|
||||
} else {
|
||||
will_continue = true
|
||||
}
|
||||
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")
|
||||
@@ -279,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() {
|
||||
@@ -291,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)
|
||||
@@ -306,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
|
||||
}
|
||||
@@ -328,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)
|
||||
}
|
||||
@@ -365,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 {
|
||||
@@ -393,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)
|
||||
}
|
||||
@@ -423,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) {
|
||||
@@ -451,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.
|
||||
@@ -531,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.
|
||||
@@ -548,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]])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,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)
|
||||
|
||||
|
||||
@@ -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.
|
||||
m.InitializeMainMenu()
|
||||
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)
|
||||
col.SetSortColumnId(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
@@ -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
@@ -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")
|
||||
}
|
||||
@@ -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
|
||||
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) {
|
||||
if resp.Args(0) == 4294967287 {
|
||||
will_continue = false
|
||||
} else {
|
||||
will_continue = true
|
||||
}
|
||||
})
|
||||
m.Response(func() {
|
||||
m.Destroy()
|
||||
})
|
||||
m.Run()
|
||||
// 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."
|
||||
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()
|
||||
})
|
||||
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 {
|
||||
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()
|
||||
})
|
||||
m.Run()
|
||||
// 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."
|
||||
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 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
|
||||
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) {
|
||||
if resp.Args(0) == 4294967287 {
|
||||
will_continue = false
|
||||
} else {
|
||||
will_continue = true
|
||||
}
|
||||
})
|
||||
m.Response(func() {
|
||||
m.Destroy()
|
||||
})
|
||||
m.Run()
|
||||
// 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."
|
||||
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()
|
||||
})
|
||||
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 {
|
||||
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()
|
||||
})
|
||||
m.Run()
|
||||
// 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."
|
||||
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 selected.</span></markup>"})
|
||||
}
|
||||
return errors.New("User didn't select valid profile, mismatch with server's version.")
|
||||
}
|
||||
|
||||
@@ -183,6 +239,9 @@ func (m *MainWindow) launchActually(server_profile *datamodels.Server, user_prof
|
||||
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>"})
|
||||
|
||||
96
ui/mainwindow_servers_sorting.go
Normal 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
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
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()
|
||||
// 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)
|
||||
|
||||
|
||||
@@ -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!")
|
||||
mbox_string := "Invalid binary selected!\nAccording to your OS, it should be Quake3-UrT.x86_64."
|
||||
// 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" {
|
||||
// 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!")
|
||||
// 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()
|
||||
op.binary_path.SetText("")
|
||||
} else {
|
||||
//
|
||||
}
|
||||
}
|
||||
} 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" {
|
||||
fmt.Println("Invalid binary selected!")
|
||||
mbox_string := "Invalid binary selected!\nAccording to your OS, it should be Quake3-UrT.app."
|
||||
m := gtk.NewMessageDialog(op.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, mbox_string)
|
||||
m.Response(func() {
|
||||
m.Destroy()
|
||||
})
|
||||
m.Run()
|
||||
op.binary_path.SetText("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||