ノーム3.2の貝の天面ボタンとの現在の限定の1つは異なったマウスのボタンのかちりと言う音のための別のメニューを表示するためのサポートがないことである。 はい、はい、私はノームの貝デザイナーがこの使用場合が意図的であるという信念および完全な権限と言うことを聞くことができる。 あらゆる批評への答え、建設的なまたは別の方法で、設計について一般により(決して出版された)有用性の調査が設計を支える誰でもよく知っていることであり。 ノームの貝が最初に解放された場合の噴火した中断のversaの電源遮断にメニュー選択討論のちょうど一見!
とにかく、この特定の限定はしばらく私が最近問題を見、限定に簡単で実行可能な解決を試み、都合することにしたことを私を悩まし。
天面のノームのフィートボタンを活動化させるのに私が私の左のマウスのボタンを使用する時私が次のメニューに表示されてほしかったことを仮定しなさい:

そして私は同じ天面ボタンを活動化させるのに私が私のマウスの右ボタン使用するとき次のメニュー選択に表示されてほしい:

下にあることに何もつぶやく 限界がそのような機能性のために支えるコードをない。 実際は 持っている 押されたか、または解放されたマウスのボタンを表す整数を戻すための明確なサポートをつぶやきなさい。 散乱 ( つぶやくかどれがに基づかせている)ドキュメンテーションに従って、標準的なスクロールマウスの場合には、次の数は信頼できる:
- 1 =左のマウスのボタン
- 2 =スクロール車輪
- 3 =マウスの右ボタン
より多くのボタンを持つマウスのために特定の値どの特定ボタンが戻るか見るために、実験しなければならないことができる。
あなたのコードでは、どの特定のマウスのボタンが押されたかいかに定めるか。 ボタン押でき事にイベントハンドラ(AKA製品回収または信号の扱う人)および/または適した俳優のボタン解放でき事信号を単に接続しなさい。 イベントハンドラでは、押されたりおよび/または解放された特定のマウスのボタンを表す整数を戻す使用get_button ()。 出版物および解放両方信号のために単一機能を使用できる。
...
_init: function(menuAlignment) {
PanelMenu.ButtonBox.prototype._init.call(this,
{ reactive: true,
can_focus: true,
track_hover: true
});
...
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
...
},
_onButtonPress: function(actor, event) {
let button = event.get_button();
if (button == 1) {
// do something
} else if (button == 3) {
// do something
}
},
...
ボタン押でき事はマウスのボタンが押されるが出たり、反応俳優で必ずしも、とき解放される。 ボタン解放でき事は(マウスがあらかじめどこかに押し下げられても)マウスのボタンが反応俳優で解放されるとき出る。 通常明確に俳優の反応特性を可能にしなければならない。 ところで、反応俳優(散乱の概念)はポインターのでき事を出すことができる俳優である。
代替的アプローチはClutter.ClickActionを使用することである。
...
let clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', Lang.bind(this, function(button) {
this._onButtonPress(button);
}));
this.actor.add_action(clickAction);
...
_onButtonPress: function(button) {
if (button == 1) {
// do something
} else if (button == 3) {
// do something
}
},
...
Clutter.ClickActionが/usr/share/gnome-shell/js/ui/shellEntry.jsのノームの貝3.2コード、かちりと鳴る道具に使用される
手もと問題に戻って。 それはノームの貝3.2の二重行為メニューの実行への主要な障害がボタンの目的を実行するコードにあることなる。 /usr/share/gnome-shell/js/ui/panelMenu.jsを見なさい。 関連したコードはここにある:
function Button(menuAlignment) {
this._init(menuAlignment);
}
Button.prototype = {
__proto__: ButtonBox.prototype,
_init: function(menuAlignment) {
ButtonBox.prototype._init.call(this, { reactive: true,
can_focus: true,
track_hover: true });
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress));
this.menu = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
this.menu.actor.add_style_class_name('panel-menu');
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
Main.uiGroup.add_actor(this.menu.actor);
this.menu.actor.hide();
},
function Button(menuAlignment) {
this._init(menuAlignment);
}
Button.prototype = {
__proto__: ButtonBox.prototype,
_init: function(menuAlignment) {
ButtonBox.prototype._init.call(this, { reactive: true,
can_focus: true,
track_hover: true });
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress));
this.menu = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
this.menu.actor.add_style_class_name('panel-menu');
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
Main.uiGroup.add_actor(this.menu.actor);
this.menu.actor.hide();
},
_onButtonPress: function(actor, event) {
if (!this.menu.isOpen) {
// Setting the max-height won't do any good if the minimum height of the
// menu is higher then the screen; it's useful if part of the menu is
// scrollable so the minimum height is smaller than the natural height
let monitor = Main.layoutManager.primaryMonitor;
this.menu.actor.style = ('max-height: ' +
Math.round(monitor.height - Main.panel.actor.height) +
'px;');
}
this.menu.toggle();
},
_onSourceKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.menu.toggle();
return true;
} else if (symbol == Clutter.KEY_Escape && this.menu.isOpen) {
this.menu.close();
return true;
} else if (symbol == Clutter.KEY_Down) {
if (!this.menu.isOpen)
this.menu.toggle();
this.menu.actor.navigate_focus(this.actor, Gtk.DirectionType.DOWN, false);
return true;
} else
return false;
},
_onMenuKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
let focusManager = St.FocusManager.get_for_stage(global.stage);
let group = focusManager.get_group(this.actor);
if (group) {
let direction = (symbol == Clutter.KEY_Left) ? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
group.navigate_focus(this.actor, direction, false);
return true;
}
}
return false;
},
_onOpenStateChanged: function(menu, open) {
if (open)
this.actor.add_style_pseudo_class('active');
else
this.actor.remove_style_pseudo_class('active');
},
destroy: function() {
this.actor._delegate = null;
this.menu.destroy();
this.actor.destroy();
this.emit('destroy');
}
};
Signals.addSignalMethods(Button.prototype);
上記のコードを検査すれば、試みが異なったマウスのボタンの間で区別する試みられないことを見る。 上記のコードに関する限りでは、1つのマウスのボタンは別のマウスのボタンと同じである。 多分ノームの貝のデザイナーはボタンのAppleの単一マウスまたは育った、同様に多くの解説者は提案した、ノームの貝を使用して実際にマウスが一般に使用されるか、または利用できないタブレットおよびpalmheldsのために設計されていた。
マウスのボタンを使用して二重メニュー機能性の実行への解決はどのマウスのボタンが行為それに応じて押されたか定めるために上記のボタンコードのbuttom押でき事信号の扱う人を変更することであり。
私がプロトタイプに二重メニュー機能性の働く実施を使用した簡単なノームの貝延長のためのソースコードはここにある:
const St = imports.gi.St;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Lang = imports.lang;
const Clutter = imports.gi.Clutter;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
function DualActionButton(menuAlignment) {
this._init(menuAlignment);
}
DualActionButton.prototype = {
__proto__: PanelMenu.ButtonBox.prototype,
_init: function(menuAlignment) {
PanelMenu.ButtonBox.prototype._init.call(this, { reactive: true,
can_focus: true,
track_hover: true });
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress));
this.menuL = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
this.menuL.actor.add_style_class_name('panel-menu');
this.menuL.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.menuL.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
Main.uiGroup.add_actor(this.menuL.actor);
this.menuL.actor.hide();
this.menuR = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
this.menuR.actor.add_style_class_name('panel-menu');
this.menuR.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.menuR.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
Main.uiGroup.add_actor(this.menuR.actor);
this.menuR.actor.hide();
},
_onButtonPress: function(actor, event) {
let button = event.get_button();
if (button == 1) {
if (this.menuL.isOpen) {
this.menuL.close();
} else {
if (this.menuR.isOpen)
this.menuR.close();
this.menuL.open();
}
} else if (button == 3) {
if (this.menuR.isOpen) {
this.menuR.close();
} else {
if (this.menuL.isOpen)
this.menuL.close();
this.menuR.open();
}
}
},
_onButtonPress: function(actor, event) {
let button = event.get_button();
if (button == 1) {
if (this.menuL.isOpen) {
this.menuL.close();
} else {
if (this.menuR.isOpen)
this.menuR.close();
this.menuL.open();
}
} else if (button == 3) {
if (this.menuR.isOpen) {
this.menuR.close();
} else {
if (this.menuL.isOpen)
this.menuL.close();
this.menuR.open();
}
}
},
_onSourceKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
if (this.menuL.isOpen) {
this.menuL.close();
} else if (this.menuR.isOpen) {
this.menuR.close();
}
return true;
} else if (symbol == Clutter.KEY_Escape) {
if (this.menuL.isOpen)
this.menuL.close();
if (this.menuR.isOpen)
this.menuR.close();
return true;
} else
return false;
},
_onMenuKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
let focusManager = St.FocusManager.get_for_stage(global.stage);
let group = focusManager.get_group(this.actor);
if (group) {
let direction = (symbol == Clutter.KEY_Left) ? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
group.navigate_focus(this.actor, direction, false);
return true;
}
}
return false;
},
_onOpenStateChanged: function(menu, open) {
if (open)
this.actor.add_style_pseudo_class('active');
else
this.actor.remove_style_pseudo_class('active');
},
destroy: function() {
this.actor._delegate = null;
this.menuL.destroy();
this.menuR.destroy();
this.actor.destroy();
this.emit('destroy');
},
};
Signals.addSignalMethods(DualActionButton.prototype);
function DemoDualActionButton() {
this._init();
}
DemoDualActionButton.prototype = {
__proto__: DualActionButton.prototype,
_init: function() {
DualActionButton.prototype._init.call(this, 0.0);
this._iconActor = new St.Icon({ icon_name: 'start-here',
icon_type: St.IconType.SYMBOLIC,
style_class: 'system-status-icon' });
this.actor.add_actor(this._iconActor);
this.actor.add_style_class_name('panel-status-button');
let item = new PopupMenu.PopupMenuItem(_("Left Menu Item 1"));
this.menuL.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Left Menu Item 2"));
this.menuL.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Right Menu Item 1"));
this.menuR.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Right Menu Item 2"));
this.menuR.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Right Menu Item 3"));
this.menuR.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Right Menu Item 4"));
this.menuR.addMenuItem(item);
},
enable: function() {
Main.panel._centerBox.add(this.actor, { y_fill: true });
Main.panel._menus.addMenu(this.menuL);
Main.panel._menus.addMenu(this.menuR);
},
disable: function() {
Main.panel._centerBox.remove_actor(this.actor);
Main.panel._menus.removeMenu(this.menuL);
Main.panel._menus.removeMenu(this.menuR);
}
};
function init() {
return new DemoDualActionButton();
}
DualActionButtonのオブジェクトコードはボタンコードの修正バージョン単にである。 中心のマウスのボタンメニューのためのサポートを加えることはとるに足らない; 私はするためにそれを必要とすればあなたのためのそれを残す。
私が名字または価値組の後にコンマを含んでいないことに注目しなさい。 MozillaのJavaScriptドキュメンテーションに従って、 ダグラスCrockford および他はのこれ正しい構文法である。 残念ながら、多くの貝延長開発者は目的の誤字のための正しい構文法を知らないようで、Mozilla SpiderMonkeyのJavaScriptエンジンおよびGObjectの内省フレームワーク に 基づいているgjs 以来の コンマを含むためにこの特定の文法エラーについて不平を言わない。
ノームの貝延長を内部に閉じ込めるのを好まないそれらの読者のために方法を可能にし、不具にすれば、コメントに従ってあなたの相当数があり、私が受け取る電子メールは、ここに上記の延長の機能によって基づく初期設定、可能になることおよび不具になることのためのソースコードである。
let button;
function init() {
button = new DemoDualActionButton();
}
function enable() {
Main.panel._centerBox.add(button.actor, { y_fill: true });
Main.panel._menus.addMenu(button.menuL);
Main.panel._menus.addMenu(button.menuR);
}
function disable() {
Main.panel._centerBox.remove_actor(button.actor);
Main.panel._menus.removeMenu(button.menuL);
Main.panel._menus.removeMenu(button.menuR);
}
貝延長を扱うための上記のコードが理解し私が一般に使用する目的の文字のコーディング様式よりやすく、易いことを何人かの人々主張する。 私の答えは機能アプローチはより複雑な貝延長の延長規模そしてある少なくとも1つの変数、頻繁に時、多くのそのような変数を使用するように要求することである。 Mozillaの現在標準外JavaScriptは変数が定義されるブロックにキーワードの限界を変数の語彙規模、またあらゆる内部のブロック含んでいた内部を許可したブロック自体を可能にした。 但し、varのキーワードがの代りに許可したらキーワードを使用されるかまたはキーワードが使用されなければ、変数の規模は全体的に履行を怠る。 JavaScriptのグローバル変数はもたらしてもいい間違いおよび潜在的な副作用のために可能な限り避けるべきである。 このタイプの規模の間違いは見つけにくく、従って私は問題を完全に避けることを選ぶ。 ダグラスCrockfordの精液の本のJavaScriptの付録A (ひどい部品)を 読みなさい: 全体的な規模の JavaScriptの変数が邪悪なぜであるか理解しなければよい部分。
ところで、私は範例はマイクロソフト・ウインドウズで共通であることを二重行為メニューボタンの概念がノームの貝のためのコンピュータ入手の可能性(a11y)の指針を破ったらが、与えられて、私がない疑えば確かめない。
私はあなたが私のノームの貝延長ウェブサイトからダウンロードできる上記のコードに基づいて簡単なノームの貝延長 、demodualmenubuttonを、 作成した。
楽しみなさい!


























私はとてもぞんざいであることを憎む。 しかしなぜすべてのこれらの延長のあなたの時間を無駄にしている(私は日刊新聞をところで使用するその)か。 私は網を渡るあなたの名前そしてこのウェブサイトをいつも見る-私はあなたが掲示するが、1つの質問は残るページから学ぶ: なぜノームのためのコーディングを導いていないか。
実際には、私はノーム延長に少しだけ時間かエネルギーを使う。 時間がか傾斜を単にあってはいけない。 「ノームのためのコーディングを」導くに関しては私がノームの貝の中心のチームの設計そして実行哲学に同意しないと同時に、起こることを行っていない。
私はあなたの版権について好奇心が強かった。 版権はあなたの仕事を再分配することができない意味するか。 なぜ版権FOSSか。
免許証および版権は頻繁にFOSSの世界で混同する2つの概念である。 私の仕事はそれでGPLごとに提供した許可を私の著作権表示再分配することができる。 私の仕事を変更すれば私の著作権表示を設置されている残さなければならなければあなた自身の著作権表示を加えることができる。
の米国とほとんどの国、あらゆる出版された仕事に自動的に版権を有する。 それは仕事が出版されるとすぐデフォルトで起こる。 実際に仕事に著作権をとられてほしくなければ、公有地にあなたの仕事を明確に置かなければならない。
http://www.gnu.org/licenses/gpl-faq.html#RequiredToClaimCopyrightを 詳細については 見なさい。