2016-12-22 11 views
0

"普通の" CSSプロバイダは私の場合には多くの作業と余分な処理を必要とするため、自分でGtkStyleProviderの実装を提供しようとしています。GtkStyleProvider - 独自の実装を提供する

内部状態に基づいてウィジェットのスタイルを提供したいと思っています。CSSでこれを行うには、CSSスタイルの宣言にPango.FontDescriptionなどのようなものを翻訳してください。状態の変化に基づいて、そしてにそれを供給します。をGtk-landに処理します。独自のプロバイダと比較すると、クライアントウィジェットがスタイルを要求して、その状態に直接基づいて新しいスタイリングを渡すように通知するだけです(何とか)。

GtkStyleProviderはこれを達成する方法です - 私はある状態に基づいてスタイリングを返すプロバイダを作って、関連するGtkStyleContextにスタイルプロバイダとして追加することができます。 (C)インタフェースは、この目的を達成するために

// deprecated - return NULL in new code 
GtkIconFactory *  gtk_style_provider_get_icon_factory (
            GtkStyleProvider *provider, 
            GtkWidgetPath *path);) 
// deprecated - return NULL in new code 
GtkStyleProperties * gtk_style_provider_get_style (
            GtkStyleProvider *provider, 
            GtkWidgetPath *path)) 
// return true if property found and has a value, else false 
gboolean    gtk_style_provider_get_style_property (
            GtkStyleProvider *provider, 
            GtkWidgetPath *path, 
            GtkStateFlags state, 
            GParamSpec *pspec, 
            GValue *value); 

で、私は私が働くことが期待され、このような何かを書いたが、それは常にプロパティを報告しなければならないとして、何もしない設定ではありません。

# compile with: valac styleprov.vala --pkg gtk+-3.0 --pkg gdk-3.0 
using Gtk; 
using Gdk; 

public class DerivedStyleProvider : Object, Gtk.StyleProvider 
{ 
    public unowned Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path) 
    { 
     return (Gtk.IconFactory) null; // Evil cast to work around buggy declaration in VAPI file 
    } 

    public Gtk.StyleProperties get_style (Gtk.WidgetPath path) 
    { 
     return (Gtk.StyleProperties) null; // Evil cast to work around buggy declaration in VAPI file 
    } 

    public bool get_style_property (Gtk.WidgetPath path, 
       Gtk.StateFlags state, 
       GLib.ParamSpec pspec, 
       out GLib.Value value) 
    { 
     stdout.printf("get_style_property"); 
     // Compiler happiness for testing 
     value = Value (typeof (string)); 
     return false; //TODO 
    } 
} 

public class styleprov.MainWindow : Gtk.Window 
{ 
    construct { 
     DerivedStyleProvider styleProvider = new DerivedStyleProvider(); 

     // but this would work 
     //Gtk.CssProvider styleProvider = new Gtk.CssProvider(); 
     //styleProvider.load_from_data("*{ background-color: #ff0000; }"); 

     StyleContext.add_provider_for_screen(this.get_screen(), 
              styleProvider, 
              Gtk.STYLE_PROVIDER_PRIORITY_USER); 
    } 
} 

class styleprov.Main : GLib.Object 
{ 
     public void run() { 
      styleprov.MainWindow mainWindow = new styleprov.MainWindow(); 
      mainWindow.show_all(); 
     } 

     public static int main (string[] args) { 
      Gtk.init (ref args); 

      Main app = new Main(); 
      app.run(); 
      Gtk.main(); 
      return 0; 
     } 
} 

これはOKコンパイルし、最大動作しますが、ほとんどの警告を吐き出す:

(styleprov:32365): GLib-GObject-WARNING **: gsignal.c:2523: signal '-gtk-private-changed' is invalid for instance '0x1154ac0' of type 'DerivedStyleProvider' 
(styleprov:32365): Gtk-WARNING **: (gtkstylecascade.c:256):gtk_style_cascade_lookup: code should not be reached 
(styleprov:32365): Gtk-WARNING **: (gtkstylecascade.c:256):gtk_style_cascade_lookup: code should not be reached 
...several of these.... 

警告にもかかわらず、get_style_property()メソッドが呼び出されているように見えることはありません、ので、何のカスタムスタイリングを提供することができません。

DerivedStyleProviderを「通常の」CSSプロバイダに置き換えると正常に動作します。

GtkStyleProvider(任意の言語)のカスタムを実装する正しい方法は何ですか?

+0

私はGtkCssProviderを簡単に見て、* 2つの*インターフェース、 'GtkStyleProvider'と' GtkStyleProviderPrivate'を実装しています。 2番目のインタフェースの実装も提供する必要があります。私はGtk +専門家ではありません... –

+0

宣言(Cコード)はここにあります:https://github.com/GNOME/gtk/blob/master/gtk/gtkstyleproviderprivate.h –

+0

ところで:とにかくあなたのUIスタイルをカスタマイズしますか?私はここで[XY問題](http://xyproblem.info/)のにおいをします。一歩踏み込んでデザインを考え直したいと思うかもしれません。クラッター、カイロ、または何かをsimilaryで自分でUIを描くことは別の方法かもしれません。 –

答えて

2

GtkStyleProviderInterfaceGtkStyleProviderPrivateInterfaceないだけを使用するように見えるGtkCssProviderの実装、そして(彼GTK + IRCチャンネルで優しい人々に応じて明らかに効率上の理由から、)をバイパス複雑なカスタムの多くを見て、私がすることを決めました通常のCSSメソッドを使用して、手作業でCSSを文字列として作成するだけです。

メカニズムである:

  • GtkCssProvider作成さ
  • プロバイダはgtk_style_context_add_provider()と関連するスタイルのコンテキスト(またはグローバルgtk_style_context_add_provider_for_screen()
  • データマネージャは、データが変更されたことの信号を送るに取り付けられ
  • これは関連する新しいCSS文字列を生成するデータ - > CSSトランスレータによって捕捉されますGtkCssProvider
  • この文字列は、既存プロバイダにgtk_css_provider_load_from_data()で入力されます。その更新の結果
  • 任意のUIの変更が自動的に

どうなる私はこの問題は、私は完全にGTK +の下にどのように機能するかを理解していない可能性があるとします。CSSをとして扱い、正規の「oracle」というUIの場合は、CSSを実際に更新するとが実際には正しい方法であると思われます。、技術的に可能な低レベルのアクセスが期待されますが、 GTK +の方法では "正しい"ものではありません。

この低レベルのアクセスは、ウィジェットの「背景色」のようなもののスタイリングを直接コントロールできる他のフレームワークから期待していたものですが、抽象的なCSSレイヤーはありませんがそれはGTK +(それ以上)でどのように動作するかではありません。

少なくとも、それは私がそれを理解する方法です!

+0

ええ、これも私が到着したものです。あなたと同じように、私はプロパティに直接アクセスしたいと思っていましたが、CSSがソースであるように書かれていることを理解しました。 GObjectへの内部変換は公開APIではありません。これは、おそらくメンテナンスの悪夢となり、パーサーの書き換え/最適化などの手段になると約束しているからです。スタイルマシンはCSSを使用できる必要があるため、これを唯一のルートとして持つことは理にかなっており、1つのAPIサーフェイスを維持するだけで済みます。 –

関連する問題