Покажите меню NSSegmentedControl, когда сегмент нажал, несмотря на то, что установил действие

Я стараюсь избегать включая любой JavaScript с HTML. Весь код инкапсулируется в классы, и каждый класс находится в своем собственном файле. Для разработки у меня есть отдельный < script> теги для включения каждого js файла но они объединяются в единственный больший пакет для производства для сокращения издержек Запросов HTTP.

Как правило, у меня будет единственный 'основной' js файл для каждого приложения. Так, если бы я писал приложение "обзора", у меня был бы js файл названным "survey.js". Это содержало бы точку входа в код jQuery. Я создаю ссылки jQuery во время инстанцирования и затем передаю их в мои объекты как параметры. Это означает, что классы JavaScript 'чисты' и не содержат ссылок на идентификаторы CSS или имена классов.

// file: survey.js
$(document).ready(function() {
  var jS = $('#surveycontainer');
  var jB = $('#dimscreencontainer');
  var d = new DimScreen({container: jB});
  var s = new Survey({container: jS, DimScreen: d});
  s.show();
});

я также нахожу соглашение о присвоении имен быть важным для удобочитаемости. Например: Я предварительно ожидаю 'j' ко всем экземплярам jQuery.

В вышеупомянутом примере, существует класс под названием DimScreen. (Предположите, что это потускнело экран и открывается окно предупреждений.) Этому нужен элемент отделения, который это может увеличить для покрытия экрана, и затем добавить окно предупреждений, таким образом, я передаю в объекте jQuery. jQuery имеет сменное понятие, но это казалось ограничением (например, экземпляры не являются персистентными и не могут быть получены доступ) без реального позитивного аспекта. Таким образом, класс DimScreen был бы стандартным классом JavaScript, который просто, оказывается, использует jQuery.

// file: dimscreen.js
function DimScreen(opts) { 
   this.jB = opts.container;
   // ...
}; // need the semi-colon for minimizing!


DimScreen.prototype.draw = function(msg) {
  var me = this;
  me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
  //...
};

я создал некоторый довольно сложный appliations, использующий этот подход.

7
задан Justin Williams 29 July 2009 в 23:46
поделиться

3 ответа

Я не уверен в каком-либо встроенном способе сделать это (хотя на самом деле это явная дыра в API NSSegmentedControl).

Я рекомендую продолжать делать то, что вы ' Повторно всплывающее контекстное меню. Однако вместо того, чтобы просто использовать источник сегментированного элемента управления, вы можете расположить его непосредственно под сегментом (как вы хотите), выполнив следующие действия:

NSPoint menuOrigin = [segmentedControl frame].origin;
menuOrigin.x = NSMaxX([segmentedControl frame]) - [segmentedControl widthForSegment:4];
// Use menuOrigin where you _were_ just using [segmentedControl frame].origin

Он не идеален или идеален, но он должен выполнять свою работу и давать внешний вид / поведение, которого ожидают ваши пользователи.

(в стороне, NSSegmentedControl действительно нуждается в методе -rectForSegment: )

4
ответ дан 6 December 2019 в 06:03
поделиться

widthForSegment: возвращает ноль, если размер сегмента автоматически. Если вас не беспокоят недокументированные API, существует rectForSegment:

  • (NSRect) rectForSegment: (NSInteger) segment inFrame: (NSRect) frame;

Но чтобы ответить на исходный вопрос, Более простой способ заставить меню немедленно появиться - создать подкласс NSSegmentedCell и вернуть 0 для (опять же, недокументированного)

  • (double) _menuDelayTimeForSegment: (NSInteger) segment;
2
ответ дан 6 December 2019 в 06:03
поделиться

Подкласс NSSegmentedCell, переопределить метод ниже и заменить класс ячейки в IB. (Не требует приватных API).

- (SEL)action
{
    //this allows connected menu to popup instantly (because no action is returned for menu button)
    if ([self tagForSegment:[self selectedSegment]]==0) {
        return nil;
    } else {
        return [super action];
    }
}
19
ответ дан 6 December 2019 в 06:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: