Getting CellDingbat to remember its state between Mathematica sessions

只谈情不闲聊 提交于 2019-11-30 03:27:51

问题


I have modified my notebook's stylesheet to include a StyleData["Todo"] that inherits from StyleData["Item"]. It changes the cell dingbat to a checkbox. In the stylesheet editor:

Cell[StyleData["ToDo", StyleDefinitions -> StyleData["Item"]], 
  CellDingbat->DynamicModuleBox[{$CellContext`color$$}, 
    CheckboxBox[
    Dynamic[$CellContext`color$$], {RGBColor[1, 0.5, 0],RGBColor[0,Rational[2, 3], 0]},    
    Background -> Dynamic[$CellContext`color$$]], 
    DynamicModuleValues :> {}
  ],
]

The problem is that the state of the checkbox, when used in a notebook, is not saved between Mathematica sessions. I thought the DynamicModule[] would do the trick. How do I get the checkbox to remember its state?

EDIT

Simon's solution does save the state of the checkbox, but the checkbox is clipped when used as a CellDingbat (MacOS X). Putting Simon's code in a CellFrameLabels options does the trick, and also keeps the default "Item" CellDingbat. Here is what I've gone with:

Cell[StyleData["ToDo", StyleDefinitions -> StyleData["Item"]],
 CellFrameLabels->{{
    ButtonBox[
     CheckboxBox[False], ButtonFunction :> (SelectionMove[
        ButtonNotebook[], All, ButtonCell]; 
      With[{$CellContext`new = ReplaceAll[
           Options[
            NotebookSelection[
             ButtonNotebook[]], CellFrameLabels], CheckboxBox[
             Pattern[$CellContext`x, 
              Alternatives[True, False]]] :> CheckboxBox[
             Not[$CellContext`x]]]}, 
        SetOptions[
         NotebookSelection[
          ButtonNotebook[]], $CellContext`new]]; SelectionMove[
        ButtonNotebook[], After, CellContents]), Appearance -> None, 
     Method -> "Preemptive", Evaluator -> Automatic], None}, {
   None, None}},
 MenuSortingValue->1621]

回答1:


The problem with your code (I think) is that a new DynamicModule does not get created each time you create a new "ToDo" cell. So there is nowhere that the state of each Checkbox can get saved.

The simplest solution I could think of for storing the state of the Checkbox for each "ToDo" cell is to overwrite the CellDingbat the first time that the Checkbox is activated. (Other options I played with were using TaggingRules, toggling between "ToDo" and "ToDone" styles, etc...)

However, even a plain Checkbox in a CellDingbat does not store its state - try running the following then cycle the output through a Show Expression cycle.

CellPrint[Cell["test", "Text", CellDingbat -> ToBoxes[Checkbox[]]]]

To get around this, I used Checkbox with the definite argument True or False wrapped up in a button that changes the state. This is stupid and inefficient, but it works!

So, my code for the cell style

Cell[StyleData["ToDo", StyleDefinitions -> StyleData["Item"]],
 CellDingbat -> ButtonBox[CheckboxBox[False], 
   ButtonFunction :> (SelectionMove[ButtonNotebook[], All, ButtonCell]; 
     With[{$CellContext`new = ReplaceAll[
          Options[NotebookSelection[ButtonNotebook[]], CellDingbat], 
          CheckboxBox[Pattern[$CellContext`x, Alternatives[True, False]]] :> CheckboxBox[Not[$CellContext`x]]]}, 
        SetOptions[NotebookSelection[ButtonNotebook[]], $CellContext`new]]; 
      SelectionMove[ButtonNotebook[], After, CellContents]), 
    Appearance -> None, Method -> "Preemptive", Evaluator -> Automatic]]

I'm not happy with this solution, but it's the best I've come up with. An improvement would be to move the button function code out of the cell so that it is not repeated for every checked ToDo cell. Also to make it run without a ReplaceAll so that the kernel is not needed and the function can be run using just the frontend.



来源:https://stackoverflow.com/questions/7932172/getting-celldingbat-to-remember-its-state-between-mathematica-sessions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!