ButtonFunction.java
     1: //========================================================================================
     2: //  ButtonFunction.java
     3: //    en:Button function assignments
     4: //    ja:ボタン機能割り当て
     5: //  Copyright (C) 2003-2024 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  https://stdkmd.net/xeij/
    11: //========================================================================================
    12: 
    13: package xeij;
    14: 
    15: import java.awt.event.*;  //ActionListener
    16: import java.util.*;  //ArrayList
    17: import javax.swing.*;  //JMenu
    18: 
    19: //class ButtonFunction
    20: //  ボタン機能割り当て
    21: public class ButtonFunction {
    22: 
    23: 
    24: 
    25:   public static enum Button {
    26:     F11 {
    27:       @Override String en () {
    28:         return "F11 key";
    29:       }
    30:       @Override String ja () {
    31:         return "F11 キー";
    32:       }
    33:       @Override String paramK () {
    34:         return "f11key";
    35:       }
    36:     },
    37:     F12 {
    38:       @Override String en () {
    39:         return "F12 key";
    40:       }
    41:       @Override String ja () {
    42:         return "F12 キー";
    43:       }
    44:       @Override String paramK () {
    45:         return "f12key";
    46:       }
    47:     },
    48:     WHEEL {
    49:       @Override String en () {
    50:         return "Wheel button";
    51:       }
    52:       @Override String ja () {
    53:         return "ホイールボタン";
    54:       }
    55:       @Override String paramK () {
    56:         return "wheel";
    57:       }
    58:     },
    59:     WHEELUP {
    60:       @Override String en () {
    61:         return "Wheel scroll up";
    62:       }
    63:       @Override String ja () {
    64:         return "ホイールスクロールアップ";
    65:       }
    66:       @Override String paramK () {
    67:         return "wheelup";
    68:       }
    69:     },
    70:     WHEELDOWN {
    71:       @Override String en () {
    72:         return "Wheel scroll down";
    73:       }
    74:       @Override String ja () {
    75:         return "ホイールスクロールダウン";
    76:       }
    77:       @Override String paramK () {
    78:         return "wheeldown";
    79:       }
    80:     },
    81:     BUTTON4 {
    82:       @Override String en () {
    83:         return "Button 4";
    84:       }
    85:       @Override String ja () {
    86:         return "ボタン 4";
    87:       }
    88:       @Override String paramK () {
    89:         return "button4";
    90:       }
    91:     },
    92:     BUTTON5 {
    93:       @Override String en () {
    94:         return "Button 5";
    95:       }
    96:       @Override String ja () {
    97:         return "ボタン 5";
    98:       }
    99:       @Override String paramK () {
   100:         return "button5";
   101:       }
   102:     };
   103:     abstract String en ();
   104:     abstract String ja ();
   105:     abstract String paramK ();
   106:   }  //enum Button
   107: 
   108:   static final Button[] BUTTON_ARRAY = Button.values ();
   109:   static final int BUTTONS = BUTTON_ARRAY.length;
   110: 
   111: 
   112: 
   113:   public static enum Modifier {
   114:     ONLY {
   115:       @Override int mask () {
   116:         return 0;
   117:       }
   118:       @Override String paramK () {
   119:         return "";
   120:       }
   121:       @Override String en () {
   122:         return "Only";
   123:       }
   124:       @Override String ja () {
   125:         return "単独";
   126:       }
   127:     },
   128:     SHIFT {
   129:       @Override int mask () {
   130:         return InputEvent.SHIFT_DOWN_MASK;
   131:       }
   132:       @Override String paramK () {
   133:         return "shift";
   134:       }
   135:       @Override String en () {
   136:         return "Shift";
   137:       }
   138:       @Override String ja () {
   139:         return "Shift";
   140:       }
   141:     },
   142:     CTRL {
   143:       @Override int mask () {
   144:         return InputEvent.CTRL_DOWN_MASK;
   145:       }
   146:       @Override String paramK () {
   147:         return "ctrl";
   148:       }
   149:       @Override String en () {
   150:         return "Ctrl";
   151:       }
   152:       @Override String ja () {
   153:         return "Ctrl";
   154:       }
   155:     },
   156:     ALT {
   157:       @Override int mask () {
   158:         return InputEvent.ALT_DOWN_MASK;
   159:       }
   160:       @Override String paramK () {
   161:         return "alt";
   162:       }
   163:       @Override String en () {
   164:         return "Alt";
   165:       }
   166:       @Override String ja () {
   167:         return "Alt";
   168:       }
   169:     };
   170:     abstract int mask ();
   171:     abstract String paramK ();
   172:     abstract String en ();
   173:     abstract String ja ();
   174:   }  //enum Modifier
   175: 
   176:   static final Modifier[] MODIFIER_ARRAY = Modifier.values ();
   177:   static final int MODIFIERS = MODIFIER_ARRAY.length;
   178: 
   179: 
   180: 
   181:   public static enum Function {
   182:     FULLSCREEN {
   183:       @Override String en () {
   184:         return "Toggle fullscreen";
   185:       }
   186:       @Override String ja () {
   187:         return "全画面表示の切り替え";
   188:       }
   189:       @Override String paramV () {
   190:         return "fullscreen";
   191:       }
   192:       @Override boolean execute (boolean pressed) {
   193:         if (pressed) {
   194:           XEiJ.pnlToggleFullscreen ();
   195:         }
   196:         return true;
   197:       }
   198:     },
   199:     SEAMLESS {
   200:       @Override String en () {
   201:         return "Toggle seamless mouse";
   202:       }
   203:       @Override String ja () {
   204:         return "シームレスマウスの切り替え";
   205:       }
   206:       @Override String paramV () {
   207:         return "seamless";
   208:       }
   209:       @Override boolean execute (boolean pressed) {
   210:         if (pressed) {
   211:           Mouse.musSetSeamlessOn (!Mouse.musSeamlessOn);
   212:         }
   213:         return true;
   214:       }
   215:     },
   216:     SCREENSHOT {
   217:       @Override String en () {
   218:         return "Take a screenshot";
   219:       }
   220:       @Override String ja () {
   221:         return "スクリーンショットを撮る";
   222:       }
   223:       @Override String paramV () {
   224:         return "screenshot";
   225:       }
   226:       @Override boolean execute (boolean pressed) {
   227:         if (pressed) {
   228:           Keyboard.kbdDoCapture ();
   229:         }
   230:         return true;
   231:       }
   232:     },
   233:     TEXTCOPY {
   234:       @Override String en () {
   235:         return "Text screen copy";
   236:       }
   237:       @Override String ja () {
   238:         return "テキスト画面コピー";
   239:       }
   240:       @Override String paramV () {
   241:         return "textcopy";
   242:       }
   243:       @Override boolean execute (boolean pressed) {
   244:         if (pressed) {
   245:           TextCopy.txcCopy ();
   246:         }
   247:         return true;
   248:       }
   249:     },
   250:     GIFANIMATION {
   251:       @Override String en () {
   252:         return "Start recording GIF animation";
   253:       }
   254:       @Override String ja () {
   255:         return "GIF アニメーション録画開始";
   256:       }
   257:       @Override String paramV () {
   258:         return "gifanimation";
   259:       }
   260:       @Override boolean execute (boolean pressed) {
   261:         if (pressed) {
   262:           GIFAnimation.gifStartRecording ();
   263:         }
   264:         return true;
   265:       }
   266:     },
   267:     STOPANDSTART {
   268:       @Override String en () {
   269:         return "Stop and start";
   270:       }
   271:       @Override String ja () {
   272:         return "停止と再開";
   273:       }
   274:       @Override String paramV () {
   275:         return "stopandstart";
   276:       }
   277:       @Override boolean execute (boolean pressed) {
   278:         if (pressed) {
   279:           XEiJ.mpuStopAndStart ();
   280:         }
   281:         return true;
   282:       }
   283:     },
   284:     TRACE1 {
   285:       @Override String en () {
   286:         return "1 trace";
   287:       }
   288:       @Override String ja () {
   289:         return "トレース 1 回";
   290:       }
   291:       @Override String paramV () {
   292:         return "trace1";
   293:       }
   294:       @Override boolean execute (boolean pressed) {
   295:         if (pressed) {
   296:           XEiJ.mpuAdvance (1);
   297:         }
   298:         return true;
   299:       }
   300:     },
   301:     TRACE10 {
   302:       @Override String en () {
   303:         return "10 traces";
   304:       }
   305:       @Override String ja () {
   306:         return "トレース 10 回";
   307:       }
   308:       @Override String paramV () {
   309:         return "trace10";
   310:       }
   311:       @Override boolean execute (boolean pressed) {
   312:         if (pressed) {
   313:           XEiJ.mpuAdvance (10);
   314:         }
   315:         return true;
   316:       }
   317:     },
   318:     TRACE100 {
   319:       @Override String en () {
   320:         return "100 traces";
   321:       }
   322:       @Override String ja () {
   323:         return "トレース 100 回";
   324:       }
   325:       @Override String paramV () {
   326:         return "trace100";
   327:       }
   328:       @Override boolean execute (boolean pressed) {
   329:         if (pressed) {
   330:           XEiJ.mpuAdvance (100);
   331:         }
   332:         return true;
   333:       }
   334:     },
   335:     STEP1 {
   336:       @Override String en () {
   337:         return "1 step";
   338:       }
   339:       @Override String ja () {
   340:         return "ステップ 1 回";
   341:       }
   342:       @Override String paramV () {
   343:         return "step1";
   344:       }
   345:       @Override boolean execute (boolean pressed) {
   346:         if (pressed) {
   347:           XEiJ.mpuStep (1);
   348:         }
   349:         return true;
   350:       }
   351:     },
   352:     STEP10 {
   353:       @Override String en () {
   354:         return "10 steps";
   355:       }
   356:       @Override String ja () {
   357:         return "ステップ 10 回";
   358:       }
   359:       @Override String paramV () {
   360:         return "step10";
   361:       }
   362:       @Override boolean execute (boolean pressed) {
   363:         if (pressed) {
   364:           XEiJ.mpuStep (10);
   365:         }
   366:         return true;
   367:       }
   368:     },
   369:     STEP100 {
   370:       @Override String en () {
   371:         return "100 steps";
   372:       }
   373:       @Override String ja () {
   374:         return "ステップ 100 回";
   375:       }
   376:       @Override String paramV () {
   377:         return "step100";
   378:       }
   379:       @Override boolean execute (boolean pressed) {
   380:         if (pressed) {
   381:           XEiJ.mpuStep (100);
   382:         }
   383:         return true;
   384:       }
   385:     },
   386:     RETURN {
   387:       @Override String en () {
   388:         return "Step until return";
   389:       }
   390:       @Override String ja () {
   391:         return "ステップアンティルリターン";
   392:       }
   393:       @Override String paramV () {
   394:         return "return";
   395:       }
   396:       @Override boolean execute (boolean pressed) {
   397:         if (pressed) {
   398:           XEiJ.mpuStepUntilReturn ();
   399:         }
   400:         return true;
   401:       }
   402:     },
   403:     LEFTCLICK {
   404:       @Override String en () {
   405:         return "Left click";
   406:       }
   407:       @Override String ja () {
   408:         return "左クリック";
   409:       }
   410:       @Override String paramV () {
   411:         return "leftclick";
   412:       }
   413:       @Override boolean execute (boolean pressed) {
   414:         if (pressed) {
   415:           Mouse.musWheelButton = 1;  //左クリック
   416:           Mouse.musWheelReleaseTime = XEiJ.mpuClockTime + XEiJ.TMR_FREQ / 1000 * 100;  //下へ回転。左クリック100ms
   417:         }
   418:         return true;
   419:       }
   420:     },
   421:     RIGHTCLICK {
   422:       @Override String en () {
   423:         return "Right click";
   424:       }
   425:       @Override String ja () {
   426:         return "右クリック";
   427:       }
   428:       @Override String paramV () {
   429:         return "rightclick";
   430:       }
   431:       @Override boolean execute (boolean pressed) {
   432:         if (pressed) {
   433:           Mouse.musWheelButton = 2;  //右クリック
   434:           Mouse.musWheelReleaseTime = XEiJ.mpuClockTime + XEiJ.TMR_FREQ / 1000 * 100;  //上へ回転。右クリック100ms
   435:         }
   436:         return true;
   437:       }
   438:     },
   439:     DONOTHING {
   440:       @Override String en () {
   441:         return "No function";
   442:       }
   443:       @Override String ja () {
   444:         return "機能なし";
   445:       }
   446:       @Override String paramV () {
   447:         return "donothing";
   448:       }
   449:       @Override boolean execute (boolean pressed) {
   450:         return false;
   451:       }
   452:     };
   453:     abstract String en ();
   454:     abstract String ja ();
   455:     abstract String paramV ();
   456:     abstract boolean execute (boolean pressed);
   457:   }  //enum Function
   458: 
   459:   static final Function[] FUNCTION_ARRAY = Function.values ();
   460:   static final int FUNCTIONS = FUNCTION_ARRAY.length;
   461: 
   462: 
   463: 
   464:   //割り当て
   465:   //  assignment[MODIFIERS * bi + mi] = fi
   466:   final static int[] assignment = new int[MODIFIERS * BUTTONS];
   467: 
   468:   //ウインドウ
   469:   public static JFrame bfnFrame;
   470: 
   471:   //bfnInit ()
   472:   //  初期化
   473:   public static void bfnInit () {
   474:     //パラメータを復元する
   475:     for (int bi = 0; bi < BUTTONS; bi++) {
   476:       Button b = BUTTON_ARRAY[bi];
   477:       for (int mi = 0; mi < MODIFIERS; mi++) {
   478:         Modifier m = MODIFIER_ARRAY[mi];
   479:         String k = m.paramK () + b.paramK ();
   480:         String v = Settings.sgsGetString (k);
   481:         int fi = Function.DONOTHING.ordinal ();
   482:         for (int gi = 0; gi < FUNCTIONS; gi++) {
   483:           Function g = FUNCTION_ARRAY[gi];
   484:           if (g.paramV ().equals (v)) {
   485:             fi = gi;
   486:             break;
   487:           }
   488:         }
   489:         assignment[MODIFIERS * bi + mi] = fi;
   490:       }
   491:     }
   492:     switch (Settings.sgsGetString ("mousewheel")) {  //旧パラメータ。保存しない
   493:     case "trace":
   494:       //-wheelup=trace1
   495:       //-shiftwheelup=trace10
   496:       //-ctrlwheelup=trace100
   497:       //-wheeldown=step1
   498:       //-shiftwheeldown=step10
   499:       //-ctrlwheeldown=step100
   500:       //-altwheeldown=return
   501:       assignment[MODIFIERS * Button.WHEELUP.ordinal () + Modifier.ONLY.ordinal ()] = Function.TRACE1.ordinal ();
   502:       assignment[MODIFIERS * Button.WHEELUP.ordinal () + Modifier.SHIFT.ordinal ()] = Function.TRACE10.ordinal ();
   503:       assignment[MODIFIERS * Button.WHEELUP.ordinal () + Modifier.CTRL.ordinal ()] = Function.TRACE100.ordinal ();
   504:       assignment[MODIFIERS * Button.WHEELDOWN.ordinal () + Modifier.ONLY.ordinal ()] = Function.STEP1.ordinal ();
   505:       assignment[MODIFIERS * Button.WHEELDOWN.ordinal () + Modifier.SHIFT.ordinal ()] = Function.STEP10.ordinal ();
   506:       assignment[MODIFIERS * Button.WHEELDOWN.ordinal () + Modifier.CTRL.ordinal ()] = Function.STEP100.ordinal ();
   507:       assignment[MODIFIERS * Button.WHEELDOWN.ordinal () + Modifier.ALT.ordinal ()] = Function.RETURN.ordinal ();
   508:       break;
   509:     case "click":
   510:       //-wheelup=leftclick
   511:       //-wheeldown=rightclick
   512:       assignment[MODIFIERS * Button.WHEELUP.ordinal () + Modifier.ONLY.ordinal ()] = Function.LEFTCLICK.ordinal ();
   513:       assignment[MODIFIERS * Button.WHEELDOWN.ordinal () + Modifier.ONLY.ordinal ()] = Function.RIGHTCLICK.ordinal ();
   514:       break;
   515:     }
   516:   }  //bfnInit
   517: 
   518:   //bfnTini ()
   519:   //  後始末
   520:   public static void bfnTini () {
   521:     //パラメータを保存する
   522:     for (int bi = 0; bi < BUTTONS; bi++) {
   523:       Button b = BUTTON_ARRAY[bi];
   524:       for (int mi = 0; mi < MODIFIERS; mi++) {
   525:         Modifier m = MODIFIER_ARRAY[mi];
   526:         String k = m.paramK () + b.paramK ();
   527:         int fi = assignment[MODIFIERS * bi + mi];
   528:         Function f = FUNCTION_ARRAY[fi];
   529:         String v = f.paramV ();
   530:         Settings.sgsPutString (k, v);
   531:       }
   532:     }
   533:     Settings.sgsPutString ("mousewheel", "");  //旧パラメータ。保存しない
   534:   }  //bfnTini
   535: 
   536:   //bfnMakeMenuItem ()
   537:   public static JMenuItem bfnMakeMenuItem () {
   538:     return Multilingual.mlnText (
   539:       ComponentFactory.createMenuItem (
   540:         "Button function assignments",
   541:         new ActionListener () {
   542:           @Override public void actionPerformed (ActionEvent ae) {
   543:             bfnOpen ();
   544:           }
   545:         }),
   546:       "ja", "ボタン機能割り当て");
   547:   }  //bfnMakeMenuItem
   548: 
   549:   //bfnStart ()
   550:   public static void bfnStart () {
   551:     if (RestorableFrame.rfmGetOpened (Settings.SGS_BFN_FRAME_KEY)) {
   552:       bfnOpen ();
   553:     }
   554:   }  //bfnStart
   555: 
   556:   //bfnOpen ()
   557:   //  ウィンドウを開く
   558:   public static void bfnOpen () {
   559:     if (bfnFrame == null) {
   560:       bfnMakeFrame ();
   561:     }
   562:     XEiJ.pnlExitFullScreen (false);
   563:     bfnFrame.setVisible (true);
   564:   }  //bfnOpen()
   565: 
   566:   //bfnMakeFrame ()
   567:   //  ウィンドウを作る
   568:   //  ここでは開かない
   569:   public static void bfnMakeFrame () {
   570:     ActionListener listener = new ActionListener () {
   571:       @Override public void actionPerformed (ActionEvent ae) {
   572:         int bmi = Integer.parseInt (ae.getActionCommand ());
   573:         int fi = bmi / (MODIFIERS * BUTTONS);
   574:         bmi -= MODIFIERS * BUTTONS * fi;
   575:         assignment[bmi] = fi;
   576:       }
   577:     };
   578:     //                                                                                                                     MODIFIERS*BUTTONS
   579:     //                     0       1     2        3      4                                                                               |
   580:     //              +-------------+--------------------------+---------+-------+-----------------+-------------------+----------+----------+
   581:     //            0 |             |         F11 key          | F12 key | Wheel | Wheel scroll up | Wheel scroll down | Button 4 | Button 5 |
   582:     //              |             +--+--------+-------+------+-+--+-+--+-+-+-+-+---+----+---+----+----+----+----+----+-+--+--+--+-+--+--+--+
   583:     //            1 |             |  | Shift+ | Ctrl+ | Alt+ | |  | |  | | | | |   |    |   |    |    |    |    |    | |  |  |  | |  |  |  |
   584:     //              +-------------+--+--------+-------+------+-+--+-+--+-+-+-+-+---+----+---+----+----+----+----+----+-+--+--+--+-+--+--+--+
   585:     //            2 | Fullscreen  |X |   X    |   X   |  X   |X|X |X|X |X|X|X|X| X | X  | X | X  | X  | X  | X  | X  |X|X |X |X |X|X |X |X |
   586:     //              +-------------+--+--------+-------+------+-+--+-+--+-+-+-+-+---+----+---+----+----+----+----+----+-+--+--+--+-+--+--+--+
   587:     //            :
   588:     //              +-------------+--+--------+-------+------+-+--+-+--+-+-+-+-+---+----+---+----+----+----+----+----+-+--+--+--+-+--+--+--+
   589:     //  1+FUNCTIONS | No function |X |   X    |   X   |  X   |X|X |X|X |X|X|X|X| X | X  | X | X  | X  | X  | X  | X  |X|X |X |X |X|X |X |X |
   590:     //              +-------------+--+--------+-------+------+-+--+-+--+-+-+-+-+---+----+---+----+----+----+----+----+-+--+--+--+-+--+--+--+
   591:     //  水平線の位置はfi={0,5,13,15}の上に固定
   592:     //  各ボタンの左側に垂直線を加える
   593:     int colCount = 1 + (1 + MODIFIERS) * BUTTONS;
   594:     ArrayList<Object> cellList = new ArrayList<Object> ();
   595:     cellList.add ("");
   596:     for (int bi = 0; bi < BUTTONS; bi++) {
   597:       Button b = BUTTON_ARRAY[bi];
   598:       cellList.add (ComponentFactory.createVerticalSeparator ());
   599:       cellList.add (Multilingual.mlnText (ComponentFactory.createLabel (b.en ()), "ja", b.ja ()));
   600:     }
   601:     for (int bi = 0; bi < BUTTONS; bi++) {
   602:       for (int mi = 0; mi < MODIFIERS; mi++) {
   603:         Modifier m = MODIFIER_ARRAY[mi];
   604:         cellList.add (Multilingual.mlnText (ComponentFactory.createLabel (m.en ()), "ja", m.ja ()));
   605:       }
   606:     }
   607:     ButtonGroup[] group = new ButtonGroup[MODIFIERS * BUTTONS];
   608:     for (int fi = 0; fi < FUNCTIONS; fi++) {
   609:       Function f = FUNCTION_ARRAY[fi];
   610:       if (fi == 0 || fi == 5 || fi == 13 || fi == 15) {
   611:         cellList.add (ComponentFactory.createHorizontalSeparator ());
   612:       }
   613:       cellList.add (Multilingual.mlnText (ComponentFactory.createLabel (f.en ()), "ja", f.ja ()));
   614:       for (int bi = 0; bi < BUTTONS; bi++) {
   615:         cellList.add (ComponentFactory.createVerticalSeparator ());
   616:         for (int mi = 0; mi < MODIFIERS; mi++) {
   617:           int bmi = MODIFIERS * bi + mi;
   618:           if (fi == 0) {
   619:             group[bmi] = new ButtonGroup ();
   620:           }
   621:           cellList.add (
   622:             ComponentFactory.setEnabled (
   623:               ComponentFactory.setText (
   624:                 ComponentFactory.createRadioButton (
   625:                   group[bmi],
   626:                   assignment[bmi] == fi,
   627:                   String.valueOf (MODIFIERS * BUTTONS * fi + bmi),  //commandをfbmiにする
   628:                   listener),
   629:                 ""),  //textを""にする
   630:               fi == Function.TEXTCOPY.ordinal () ? XEiJ.clpClipboard != null :  //テキスト画面コピーはクリップボードが必要
   631:               true)
   632:             );
   633:         }
   634:       }
   635:     }
   636:     String colStyles = "italic";
   637:     String cellStyles = "rowSpan=2";
   638:     for (int bi = 0; bi < BUTTONS; bi++) {
   639:       colStyles += ";lengthen";
   640:       for (int mi = 0; mi < MODIFIERS; mi++) {
   641:         colStyles += ";";
   642:       }
   643:       cellStyles += ";rowSpan=2;colSpan=" + MODIFIERS;
   644:     }
   645:     bfnFrame = Multilingual.mlnTitle (
   646:       ComponentFactory.createRestorableSubFrame (
   647:         Settings.SGS_BFN_FRAME_KEY,
   648:         "Button function assignments",
   649:         null,
   650:         ComponentFactory.setPreferredSize (
   651:           new JScrollPane (
   652:             ComponentFactory.setEmptyBorder (
   653:               ComponentFactory.createGridPanel (
   654:                 colCount,  //colCount
   655:                 2 + FUNCTIONS + 4,  //rowCount
   656:                 "paddingLeft=3,paddingRight=3,center",   //gridStyles
   657:                 colStyles,  //colStyles
   658:                 "italic;italic" +
   659:                 ";colSpan=" + colCount + ",widen" +  //0の上
   660:                 ";;;;;;colSpan=" + colCount + ",widen" +  //5の上
   661:                 ";;;;;;;;;colSpan=" + colCount + ",widen" +  //13の上
   662:                 ";;;colSpan=" + colCount + ",widen",  //15の上 rowStyles
   663:                 cellStyles,  //cellStyles
   664:                 cellList.toArray (new Object[0])),
   665:               6, 6, 6, 6)),
   666:           600, 380)),
   667:       "ja", "ボタン機能割り当て");
   668:   }  //bfnMakeFrame()
   669: 
   670:   //consumed = bfnExecute (b, modifiersEx, pressed, forcedF)
   671:   //  ボタンが押されたまたは離された
   672:   public static boolean bfnExecute (Button b, int modifiersEx, boolean pressed, Function forcedF) {
   673:     int mask = modifiersEx & (InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
   674:     for (int mi = 0; mi < MODIFIERS; mi++) {
   675:       Modifier m = MODIFIER_ARRAY[mi];
   676:       if (m.mask () == mask) {
   677:         int bi = b.ordinal ();
   678:         int bmi = MODIFIERS * bi + mi;
   679:         int fi = assignment[bmi];
   680:         Function f = FUNCTION_ARRAY[fi];
   681:         if (forcedF != null) {
   682:           f = forcedF;
   683:         }
   684:         return f.execute (pressed);
   685:       }
   686:     }
   687:     return false;
   688:   }  //bfnExecute
   689: 
   690: 
   691: 
   692: }  //class ButtonFunction