Community
    • Login

    Shortcut or menu path to "Rotate to right/left"

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    18 Posts 5 Posters 3.4k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • EkopalypseE
      Ekopalypse
      last edited by

      What I think the problem was is that a newly created script hasn’t been assigned
      an ID known to npp. This is normally done during plugin initialization where npp
      asks for functions to register, hence the restart of npp solved it.

      1 Reply Last reply Reply Quote 2
      • deleeleeD
        deleelee @Ekopalypse
        last edited by

        @Ekopalypse said in Shortcut or menu path to "Rotate to right/left":

        A python script might look like this

        import ctypes
        
        ROTATION_A_LEFT = 2000
        ROTATION_A_RIGHT = 2001
        WM_COMMAND = 0x111
        
        def isSingleView():
            npp_hwnd = ctypes.windll.user32.FindWindowW(u'Notepad++', None)
            splitter_hwnd = ctypes.windll.user32.FindWindowExW(npp_hwnd, None, u'splitterContainer', None)
            return (not bool(ctypes.windll.user32.IsWindowVisible(splitter_hwnd)), splitter_hwnd)
        
        def LOWORD(value): return value & 0xFFFF
        
        single_view, hwnd = isSingleView()
        if not single_view:
            ctypes.windll.user32.SendMessageW(hwnd, WM_COMMAND, LOWORD(ROTATION_A_LEFT), 0)
        

        A few years old but it still works!!! I’ve been wanting a toolbar button for rotating the panes and this is great. Do you know if it would be possible to have the script toggle so that it rotates one way on the first click and back the other way on the next click? As it is, the first click rotates in the desired direction but the next click rotates once more in the same direction which doesn’t return the panes to the order they were in, so it requires three clicks to do that. Obviously, I could just have two buttons, one for right and one for left, but it would save toolbar space if they were combined into one button.

        EkopalypseE 1 Reply Last reply Reply Quote 0
        • EkopalypseE
          Ekopalypse @deleelee
          last edited by

          @deleelee

          Oh dear … When I see this old code, what was I thinking? :-D

          let’s create a new property of the notepad class and store the state there.

          import ctypes
          
          ROTATION_A_LEFT = 2000
          ROTATION_A_RIGHT = 2001
          WM_COMMAND = 0x111
          
          def isSingleView():
              npp_hwnd = ctypes.windll.user32.FindWindowW(u'Notepad++', None)
              splitter_hwnd = ctypes.windll.user32.FindWindowExW(npp_hwnd, None, u'splitterContainer', None)
              return (not bool(ctypes.windll.user32.IsWindowVisible(splitter_hwnd)), splitter_hwnd)
          
          def LOWORD(value): return value & 0xFFFF
          
          if not hasattr(notepad, "rotateSplitView"):
              notepad.rotateSplitView = False
          
          single_view, hwnd = isSingleView()
          if not single_view:
              if notepad.rotateSplitView:
                  ctypes.windll.user32.SendMessageW(hwnd, WM_COMMAND, LOWORD(ROTATION_A_LEFT), 0)
              else:
                  ctypes.windll.user32.SendMessageW(hwnd, WM_COMMAND, LOWORD(ROTATION_A_RIGHT), 0)
              notepad.rotateSplitView = not notepad.rotateSplitView
          

          But nowadays I guess I would do something like

          from ctypes import wintypes, WinDLL
          from Npp import notepad
          
          class ViewRotator():
              def __init__(self):
                  self.LOWORD_LEFT = 2000
                  self.LOWORD_RIGHT = 2001
                  self.WM_COMMAND = 0x111
                  self.toggle_rotating_direction = False
                  self.npp_hwnd = WinDLL("user32").FindWindowW(u'Notepad++', None)
                  self.splitter_hwnd = WinDLL("user32").FindWindowExW(self.npp_hwnd, None, u'splitterContainer', None)
                  self.send = WinDLL("user32").SendMessageW
                  self.send.argtypes = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
                  self.send.resttype = wintypes.LPARAM  # LRESULT
          
              def isSingleView(self):
                  return not bool(WinDLL("user32").IsWindowVisible(self.splitter_hwnd))
          
              def rotate(self):
                  if not self.isSingleView():
                      if self.toggle_rotating_direction:
                          self.send(self.splitter_hwnd, self.WM_COMMAND, self.LOWORD_RIGHT, 0)
                      else:
                          self.send(self.splitter_hwnd, self.WM_COMMAND, self.LOWORD_LEFT, 0)
                      self.toggle_rotating_direction = not self.toggle_rotating_direction
          
          
          if not hasattr(notepad, "rotateSplitView"):
              notepad.rotateSplitView = ViewRotator().rotate
          
          notepad.rotateSplitView()
          
          Alan KilbornA 1 Reply Last reply Reply Quote 1
          • Alan KilbornA
            Alan Kilborn @Ekopalypse
            last edited by Alan Kilborn

            @Ekopalypse

            self.send.resttype = wintypes.LPARAM # LRESULT

            I think you mean restype

            def isSingleView(self):
            …
            if not self.isSingleView():

            Any reason not to use notepad.isSingleView() instead of writing a custom function?


            Oh dear … When I see this old code, what was I thinking? :-D

            Yep, we all feel this way about our own old code. :-)
            It’s because we’ve learned so much since the time of original writing.

            EkopalypseE 1 Reply Last reply Reply Quote 3
            • EkopalypseE
              Ekopalypse @Alan Kilborn
              last edited by

              @Alan-Kilborn said in Shortcut or menu path to "Rotate to right/left":

              I think you mean restype

              Yes, I do, thanks for pointing that out.

              Any reason not to use notepad.isSingleView() instead of writing a custom function?

              No, I just hadn’t thought about whether there were any builtin methods.

              Yep, we all feel this way about our own old code. :-)
              It’s because we’ve learned so much since the time of original writing.

              … and still learning … :-D that’s the beauty of this work, at least for me.

              EkopalypseE 1 Reply Last reply Reply Quote 1
              • EkopalypseE
                Ekopalypse @Ekopalypse
                last edited by Ekopalypse

                @deleelee

                UPDATED VERSION

                from ctypes import wintypes, WinDLL
                from Npp import notepad
                
                class ViewRotator():
                    def __init__(self):
                        self.LOWORD_LEFT = 2000
                        self.LOWORD_RIGHT = 2001
                        self.WM_COMMAND = 0x111
                        self.toggle_rotating_direction = False
                        self.npp_hwnd = WinDLL("user32").FindWindowW(u'Notepad++', None)
                        self.splitter_hwnd = WinDLL("user32").FindWindowExW(self.npp_hwnd, None, u'splitterContainer', None)
                        self.send = WinDLL("user32").SendMessageW
                        self.send.argtypes = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
                        self.send.restype = wintypes.LPARAM  # LRESULT
                
                    def rotate(self):
                        if not notepad.isSingleView():
                            if self.toggle_rotating_direction:
                                self.send(self.splitter_hwnd, self.WM_COMMAND, self.LOWORD_RIGHT, 0)
                            else:
                                self.send(self.splitter_hwnd, self.WM_COMMAND, self.LOWORD_LEFT, 0)
                            self.toggle_rotating_direction = not self.toggle_rotating_direction
                
                
                if not hasattr(notepad, "rotateSplitView"):
                    notepad.rotateSplitView = ViewRotator().rotate
                
                notepad.rotateSplitView()
                
                Alan KilbornA deleeleeD 2 Replies Last reply Reply Quote 4
                • Alan KilbornA
                  Alan Kilborn @Ekopalypse
                  last edited by

                  @Ekopalypse

                  This is an interesting approach to remembering toggle_rotating_direction from run to run of the script. Side note: IMO the name of that variable could have been better.

                  If I were writing that script, I might have remembered only the variable in the notepad variable (i.e., notepad.toggle_rotating_direction = …) instead of the function.

                  Your way has the advantage that you’ve added a general purpose function (notepad.rotateSplitView()) that could also easily be called by other scripts.

                  EkopalypseE 1 Reply Last reply Reply Quote 1
                  • EkopalypseE
                    Ekopalypse @Alan Kilborn
                    last edited by

                    @Alan-Kilborn said in Shortcut or menu path to "Rotate to right/left":

                    IMO the name of that variable could have been better

                    Sure, but I’m constantly struggling to name things.
                    What would be your choice? change_rotating_direction?

                    …

                    I had the same thoughts and decided to use a function because it can easily be modified to use a parameter to get either a split landscape or portrait view.

                    1 Reply Last reply Reply Quote 0
                    • Alan KilbornA
                      Alan Kilborn
                      last edited by

                      IMO the name of that variable could have been better

                      The reason toggle_rotating_direction isn’t good IMO is because, every time the code runs a toggle happens, and not just when toggle_rotating_direction is true.

                      what would be your choice?

                      Hmm, for this one, since it is a boolean, I might go with next_rotate_is_to_the_right.

                      With something like that, true/false makes sense.

                      Of course, this is all up to individual taste.


                      I’m constantly struggling to name things.

                      Yes, it is hard sometimes. Often what I do is to name something zz or zzz and just barrel ahead coding with that. Later, like when I’ve completed the local block of code, a good name surfaces and a rename fixes things.

                      I find that if I spend the time up front to come up with a great name, the code to be written changes the meaning somewhat and the great name is no longer great. So I end up taking the time to come up with 2 good names instead of just 1. Naming after the fact seems a viable technique, at least for me.

                      Of course I don’t do this 100% of the time, just when a suitable name doesn’t immediately come to mind.

                      1 Reply Last reply Reply Quote 1
                      • deleeleeD
                        deleelee @Ekopalypse
                        last edited by

                        @Ekopalypse said in Shortcut or menu path to "Rotate to right/left":

                        @deleelee

                        UPDATED VERSION

                        from ctypes import wintypes, WinDLL
                        from Npp import notepad
                        
                        class ViewRotator():
                            def __init__(self):
                                self.LOWORD_LEFT = 2000
                                self.LOWORD_RIGHT = 2001
                                self.WM_COMMAND = 0x111
                                self.toggle_rotating_direction = False
                                self.npp_hwnd = WinDLL("user32").FindWindowW(u'Notepad++', None)
                                self.splitter_hwnd = WinDLL("user32").FindWindowExW(self.npp_hwnd, None, u'splitterContainer', None)
                                self.send = WinDLL("user32").SendMessageW
                                self.send.argtypes = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
                                self.send.restype = wintypes.LPARAM  # LRESULT
                        
                            def rotate(self):
                                if not notepad.isSingleView():
                                    if self.toggle_rotating_direction:
                                        self.send(self.splitter_hwnd, self.WM_COMMAND, self.LOWORD_RIGHT, 0)
                                    else:
                                        self.send(self.splitter_hwnd, self.WM_COMMAND, self.LOWORD_LEFT, 0)
                                    self.toggle_rotating_direction = not self.toggle_rotating_direction
                        
                        
                        if not hasattr(notepad, "rotateSplitView"):
                            notepad.rotateSplitView = ViewRotator().rotate
                        
                        notepad.rotateSplitView()
                        

                        Wowsers!!! That is perfect. Thank you so much.

                        1 Reply Last reply Reply Quote 1
                        • First post
                          Last post
                        The Community of users of the Notepad++ text editor.
                        Powered by NodeBB | Contributors